Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
Hi Steven (D'Aprano), Right now, that choice is very restrictive, and I personally don't like > the look and feel of existing contract libraries. I would give my right > eye for Cobra-like syntax for contracts in Python: > > http://cobra-language.com/trac/cobra/wiki/Contracts > You might be interested in the discussion on transpiling contracts back and forth. See the other thread "Transpile contracts" and the issue in github: https://github.com/Parquery/icontract/issues/48 ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Transpiling contracts
Hi James, I had another take at it. I wrote it down in the github issue ( https://github.com/Parquery/icontract/issues/48#issuecomment-426147468): SLOW=os.environ.get("SOME_ENVIRONMENT_VARIABLE", "") != "" class SomeClass: def __init__(self)->None: self.some_prop = 1984 def some_func(arg1: List[int], arg2: List[int])->SomeClass: with requiring: len(arg1) > 3, "some description" len(arg2) > 5, ValueError("some format {} {}".format(arg1, arg2)) if SLOW: all(elt in arg2 for elt in arg1) len(arg2) == len(set(arg2)) result = None # type: SomeClass with ensuring, oldie as O: len(arg1) == len(O.arg1) result.some_prop < len(arg2) This transpiles to/from: SLOW=os.environ.get("SOME_ENVIRONMENT_VARIABLE", "") != "" class SomeClass: def __init__(self)->None: self.some_prop = 1984 @requires(lambda P: len(P.arg1) > 3, "some description")@requires(lambda P: len(P.arg2), error=lambda P: ValueError("some format {} {}".format(P.arg1, P.arg2)))@requires(lambda P: all(elt in P.arg2 for elt in P.arg1), enabled=SLOW)@requires(lambda P: len(arg2) == len(set(arg2)))@ensures(lambda O, P: len(P.arg1) == len(O.arg1))@ensures(lambda P, result: result.some_prop < len(P.arg2))def some_func(arg1: List[int], arg2: List[int])->SomeClass: ... 2. What’s the use case for preferring block syntax over lambda syntax? Is > the block syntax only better when multiple statements are needed to test a > single contract condition? > Actually no. The condition must be a single statement (specified as a boolean expression) regardless of the form (readable or executable). My idea was that contracts would be a more readable + easier to type and group by the respective enabled flags. It should be a 1-to-1 back and forth transformation. I didn't aim for any other advantages other than readability/easier modification. The use case I have in mind is not to separate each file into two (executable and readable). I'm more thinking of a tool that I can attach to key shortcuts in the IDE that let me quickly transform the contracts into readable form when I need to read them / make my modifications and then convert them back into executable form. 3. When we do need multiple statements to formally verify/specify, is it > usually a better idea to factor out major functionality of the contract > testing to an external function? (So other contracts can use the same > external function and the intent of the contract is clear trough the > function name) > I would say so (i.e. no multi-statement conditions) . Making multi-statement conditions would be rather confusing and also harder to put into documentation. And it would be hard to implement :) 4. If this is true, is it a good idea to include a contracts/ folder at the > same folder level or a .contracts.py file to list “helper” or verification > functions for a contract? > So far, we never had to make a function external to a contract -- it was often the signal that something had to be refactored out of the function if the condition became complex, but the resulting functions usually either stayed in the same file or were more general and had to move to a separate module anyhow. Our Python code base has about 95K LOC, I don't know how contracts behave on larger code bases or how they would need to be structured. Cheers, Marko On Mon, 1 Oct 2018 at 17:18, James Lu wrote: > Hi Marko, > > I’m going to refer to the transpiler syntax as “block syntax.” > > 1. How does Eiffel do formal contracts? > 2. What’s the use case for preferring block syntax over lambda syntax? Is > the block syntax only better when multiple statements are needed to test a > single contract condition? > 2. If the last proposition is true, how often do we need multiple > statements to test or specify a single contract condition? > 3. When we do need multiple statements to formally verify/specify, is it > usually a better idea to factor out major functionality of the contract > testing to an external function? (So other contracts can use the same > external function and the intent of the contract is clear trough the > function name) > 4. If this is true, is it a good idea to include a contracts/ folder at > the same folder level or a .contracts.py file to list “helper” or > verification functions for a contract? > > I think we should answer questions two and three by looking at real code. > — > > If MockP is supported, it could be used for all the contract decorators: > @snapshot(var=P.self.name) > @post(var=R.attr == P.old.var) > > The decorator can also check the type of the returned object, and if it’s > MockP it will use MockP protocol and otherwise it will check the object is > callable and treat it as a lambda. > > Your approach has better type hinting, but I’m not sure if type hinting > would be that useful if you’re adding a contract whilst writing the > function. > > James Lu > > On Oct 1, 2018, at 1:01 AM,
Re: [Python-ideas] Renaming icontract to pcontract
Ok, let's keep icontract as it was already referenced a couple of times at least on this list. I'll rename the pypi package to icontract2 and the module as well as soon as I change the interface. On Mon, 1 Oct 2018 at 20:43, James Lu wrote: > I think the confusion would be minimal and not worth the hassle of > renaming to pcontract. People would just say “Python icontract” when it’s > ambiguous. > > Sent from my iPhone > > On Oct 1, 2018, at 3:28 AM, Marko Ristin-Kaufmann > wrote: > > Hi Cameron, > A nerdy way to make it sound like a sentence: "I contract that ...". > > Pcontract would stand for python contract. Pycontract is already taken. > > Cheers, > Marko > > Le lun. 1 oct. 2018 à 09:15, Cameron Simpson a écrit : > >> On 01Oct2018 07:25, Marko Ristin-Kaufmann wrote: >> >I'd like to rename icontract into pcontract to avoid name conflict with >> >java's icontract library. >> > >> >Do you have any better suggestion? >> >> No, sounds ok to me. What was the "i" for in the old name? >> >> Cheers, >> Cameron Simpson >> ___ >> Python-ideas mailing list >> Python-ideas@python.org >> https://mail.python.org/mailman/listinfo/python-ideas >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Why is design-by-contracts not widely adopted?
On Mon, Oct 1, 2018, 9:13 PM Steven D'Aprano wrote: > For an application, it doesn't matter if my function sets the computer on > fire when passed the string "fish", if there is no way for the application > to pass that string to the function. If it can't happen, it can't happen > and there's no need to defend against it beyond a regression test. > How many times have you written or seen a comment in code similar to "This can't possibly happen!!" ... Usually in response to a failed debugging attempt. It's really hard to understands all possible execution paths that might result from all possible inputs and program states. "Fail early and fail hard" is a good principle... And indeed one generally in a spirit compatible with DbC. Beware of bugs in the above code; I have only proved it correct, not tried it. - Donald Knuth ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
On Tue, Oct 02, 2018 at 02:43:57AM +0900, Stephen J. Turnbull wrote: > Steven D'Aprano writes: > > > I'm not sure how Stephen went from my comment that you can't unit test > > loop invariants to the idea that loop invariants aren't in the > > implementation. > > Obviously I didn't. I went from your statement that (1) contracts are > separated from the implementation and the inference from (7) that > contracts can specify loop invariants to the question of whether both > can be true at the same time. Okay, fair enough. The loop invariant is separate in the sense that it is in a distinctly named block. But it connected in the sense that the loop invariant is attached to the loop, which is inside the function implementation, rather than in a separate block outside of the implementation. In Python terms, we might say something like: for x in sequence: BLOCK else: BLOCK invariant: BLOCK Static tools could parse the source and extract the invariant blocks, editors could allow you to collapse them out of sight. But unlike the (hypothetical) require and ensure blocks, its right there inside the function implementation. We presumably wouldn't want the invariant to be far away from the loop: ... code ... more code for x in sequence: BLOCK ... more code ... more code ... # and far, far away invariant: BLOCK Even if we had some mechanism to connect the two (some sort of label, as you suggest) it would suck from a readability perspective to have to jump backwards and forwards from the loop to the loop invariant. Things which are closely connected ought to be close together. -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Why is design-by-contracts not widely adopted?
On Mon, Oct 01, 2018 at 12:36:18PM -0400, David Mertz wrote: > There's some saying/joke about software testing along the lines of: > > For an argument that should be in range 1-100: > try 50; try 1; try 100 > try 101; try 0; > try -1, > try 3.14 > try 1+1j; > try the string "fish", > try a null pointer; > etc. > > Many of those oddball cases can easily be in a list of values to test in > unit tests, but may be impossible or unlikely to make it to the function > call in the normal/possible flow of the program. Right. And for a *library*, you must handle out of range errors, because the library cannot trust the input passed to it by third parties. If a third party passes "fish" as an argument, that's not a bug in the library and the library cannot fix it, it should handle the error gracefully with a sensible error message. But for an *application*, the internal routines are completely under control of the one developer team. If an internal routine passes "fish", that's a bug that the dev team can and ought to fix. Once that bug is fixed, there's no need to check for "fish" in production code. Its a waste of time. (In principle at least -- it depends on how confident you or your QA team are that all the bugs are ironed out. Do you ship your apps with debugging turned off? Then you might ship with contract checking turned off, or at least dialled back to a lower level.) For an application, it doesn't matter if my function sets the computer on fire when passed the string "fish", if there is no way for the application to pass that string to the function. If it can't happen, it can't happen and there's no need to defend against it beyond a regression test. (Modulo comments about how confident you are about the software quality.) For a library, anyone can pass "fish" to anything, so you better handle it gracefully rather than setting the computer on fire. For application developers, the point of contracts is to make error conditions *impossible* rather than to just defend against them, so you can turn off the defensive error checking in production because they aren't needed. > > I'm curious. When you write a function or method, do you include input > > checks? Here's an example from the Python stdlib (docstring removed for > > brevity): > > > > # bisect.py > > def insort_right(a, x, lo=0, hi=None): > > if lo < 0: > > raise ValueError('lo must be non-negative') > > if hi is None: > > hi = len(a) > > while lo < hi: > > mid = (lo+hi)//2 > > if x < a[mid]: hi = mid > > else: lo = mid+1 > > a.insert(lo, x) > > > > Do you consider that check for lo < 0 to be disruptive? How would you > > put that in a unit test? > > > > I definitely put in checks like that. However, I might well write a test > like: > > assert lo >= 0, "lo must be non-negative" > > That would allow disabling the check for production. For a library function, I would consider that an abuse of assert, since: (1) It raises the wrong exception (AssertionError); (2) It can be disabled; (3) And it sends the wrong message, telling the reader that lo is an internal implementation detail rather than part of the function's external API. > However, I presume > the stdlib does this for a reason; it presumably wants to allow callers to > catch a specific exception. I haven't seen anything in the contract > discussion that allows raising a particular exception when a contract is > violated, only a general one for all contracts. I think that the Eiffel philosophy is that all contract violations are assertion errors, but I'm not really confident in my understanding of Eiffel's exception mechanism. It doesn't have a generalised try...except statement like Python. If Python had contracts, I'd want to see: - by default, contract violations raise specific subclasses of AssertionError, e.g. RequireError, EnsureError; - but there ought to be a mechanism to allow specific errors to raise more specific exceptions. I haven't given any thought to that mechanism. It might simply be "the status quo" -- there's no reason why we *must* move defensive input checking into the (hypothetical) require block just because it is available. You can still write your test the old fashioned way in the body of the function and raise the exception of your choice. > The case of 'if hi is None' is different. It's remediation of a missing > value where it's perfectly fine to impute an unspecified value. So that > would be a poor contract. Since the check for None is not error checking at all, I didn't talk about it or make it a precondition test. -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Renaming icontract to pcontract
I think the confusion would be minimal and not worth the hassle of renaming to pcontract. People would just say “Python icontract” when it’s ambiguous. Sent from my iPhone > On Oct 1, 2018, at 3:28 AM, Marko Ristin-Kaufmann > wrote: > > Hi Cameron, > A nerdy way to make it sound like a sentence: "I contract that ...". > > Pcontract would stand for python contract. Pycontract is already taken. > > Cheers, > Marko > >> Le lun. 1 oct. 2018 à 09:15, Cameron Simpson a écrit : >> On 01Oct2018 07:25, Marko Ristin-Kaufmann wrote: >> >I'd like to rename icontract into pcontract to avoid name conflict with >> >java's icontract library. >> > >> >Do you have any better suggestion? >> >> No, sounds ok to me. What was the "i" for in the old name? >> >> Cheers, >> Cameron Simpson >> ___ >> Python-ideas mailing list >> Python-ideas@python.org >> https://mail.python.org/mailman/listinfo/python-ideas >> Code of Conduct: http://python.org/psf/codeofconduct/ > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
Marko Ristin-Kaufmann writes: > Do you mean annotating an abstract class with contracts or > annotating the actual functions in abc module? I mean the functions in the abc module. > Inheriting of contracts also proved useful when you define an > interface as a group of functions together with the contracts. You > define the functions as an ABC with purely static methods (no > state) and specify the contracts in that abstract class. I can envision how that would work in a situation with application- specific classes, even in a deep hierarchy, with some discipline. However, Python does not necessarily conform to that kind of discipline. I suspect that Pythonic programming styles are not terribly amenable to inheritance of contracts. I think the ABC module is most likely to provide a strong evidence that I'm wrong: if contract inheritance, and in general the contracting style of programming, works well for that module, it will work for anything written in Python. By the way, I'm not asking you to do this; you've already provided both the icontract module and a rather complete annotation of a sizeable stdlib module. Your work is appreciated! Of course I'd be happy to see a similar treatment of abc, but it's also a reasonable candidate for thought experiments, or a sample of a few cases. Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
Steven D'Aprano writes: > I'm not sure how Stephen went from my comment that you can't unit test > loop invariants to the idea that loop invariants aren't in the > implementation. Obviously I didn't. I went from your statement that (1) contracts are separated from the implementation and the inference from (7) that contracts can specify loop invariants to the question of whether both can be true at the same time. > Obviously the loop invariant has to be attached to the loop. You > can't attach a loop invariant to a method or class, because they > might contain more than one loop. That's not so obvious. At least in theory you could provide a label for the loop (Common Lisp for example has named blocks), and refer to that in an "invariant" section outside the function. I couldn't imagine a pleasing syntax without help from someone who's used contracts, though. That's why I asked. It's not a big deal that they aren't both simultaneously true in practice, it's just that there are a huge number of abstract claims being made for contracts, and for my money they don't look anywhere near as much of an improvement over asserts in practice as they sound in the abstract, in decorator form or in Eiffel syntax. As I said before, since a number of people are asking for them, I'm at least +0 on including a contracts module with attractive syntax for contracts in the stdlib on the general principle that we should provide batteries for as many common patterns or styles as possible. But I'm not ready to go that high for language changes for this purpose, at least not yet. Since I don't expect to be using contracts any time soon, I'll leave the definition of "attractive" up to those who expect to have to read them frequently. Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Why is design-by-contracts not widely adopted?
On Sun, Sep 30, 2018 at 11:34 AM Steven D'Aprano wrote: > On Sun, Sep 30, 2018 at 10:29:50AM -0400, David Mertz wrote: > But given that in general unit tests tend to only exercise a handful of > values (have a look at the tests in the Python stdlib) I think it is > fair to say that in practice unit tests typically do not have anywhere > near the coverage of live data used during alpha and beta testing. > I still think it's a mixture. I write tests to also address "this really shouldn't happen" cases as well (often in a loop, or using a Nose class for scaffolding). There's some saying/joke about software testing along the lines of: For an argument that should be in range 1-100: try 50; try 1; try 100 try 101; try 0; try -1, try 3.14 try 1+1j; try the string "fish", try a null pointer; etc. Many of those oddball cases can easily be in a list of values to test in unit tests, but may be impossible or unlikely to make it to the function call in the normal/possible flow of the program. > I'm curious. When you write a function or method, do you include input > checks? Here's an example from the Python stdlib (docstring removed for > brevity): > > # bisect.py > def insort_right(a, x, lo=0, hi=None): > if lo < 0: > raise ValueError('lo must be non-negative') > if hi is None: > hi = len(a) > while lo < hi: > mid = (lo+hi)//2 > if x < a[mid]: hi = mid > else: lo = mid+1 > a.insert(lo, x) > > Do you consider that check for lo < 0 to be disruptive? How would you > put that in a unit test? > I definitely put in checks like that. However, I might well write a test like: assert lo >= 0, "lo must be non-negative" That would allow disabling the check for production. However, I presume the stdlib does this for a reason; it presumably wants to allow callers to catch a specific exception. I haven't seen anything in the contract discussion that allows raising a particular exception when a contract is violated, only a general one for all contracts. The case of 'if hi is None' is different. It's remediation of a missing value where it's perfectly fine to impute an unspecified value. So that would be a poor contract. -- Keeping medicines from the bloodstreams of the sick; food from the bellies of the hungry; books from the hands of the uneducated; technology from the underdeveloped; and putting advocates of freedom in prisons. Intellectual property is to the 21st century what the slave trade was to the 16th. ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
On Sun, Sep 30, 2018 at 06:33:08PM +1000, Chris Angelico wrote: > On Sun, Sep 30, 2018 at 6:03 PM Steven D'Aprano wrote: > > > > On Sun, Sep 30, 2018 at 02:50:28PM +1000, Chris Angelico wrote: > > > > > And yet all the examples I've seen have just been poor substitutes for > > > unit tests. Can we get some examples that actually do a better job of > > > selling contracts? > > > > In no particular order... > > > > (1) Distance > > Don't doctests deal with this too? With the exact same downsides? I'm not sure that I understand the question. Yes, doctests are usually (but not always) close to the function too. That's a plus in favour of doctests. The downside is that if you want to show a metric tonne of examples, your docstring becomes huge. (Or move it out into a separate text file, which doctest can still run.) Sometimes its a real struggle to write a good docstring that isn't huge. But on the other hand, a good editor should allow you to collapse docstrings to a single line. > > (2) Self-documenting code > > Ditto Sorry, are you asking if doctests are self-documenting code? Since they aren't part of the implementation of the function, no they aren't. > > (3) The "Have you performed the *right* tests?" problem > > Great if your contracts can actually be perfectly defined. Why do you think the contracts have to be perfectly defined? I keep reading people accusing pro-Contracts people of being zealots who believe that Contracts are a magic bullet that solve every problem 100% perfectly. I don't know where people get this idea. Contracts are a tool, like unit tests. Just as a single unit test is better than no unit tests, and two unit tests is better than one, same goes for contracts. If you have an imperfect (incomplete, not buggy!) contract, that's better than *no* contract at all. If you would like to check five things, but can only specify three of them in a contract, that's better than not specifying any of them. > Every time > a weird case is mentioned, those advocating contracts (mainly Marko) > give examples showing "hey, contracts can do that too", and they're > just testing specifics. Can you give an example? Of course, contracts *can* be specific (at least in Eiffel), the syntax allows it. In pseudo-code: def spam(x, y): require: if x is None: y > 0 # implementation goes here... The precondition checks that if x is None, y must be greater than zero. On its own, that's not a very good contract since it tells us nothing about the case when x is not None, but (as per my comments above) its better than nothing. How would you do this as a unit test? For starters, you need to move the precondition into the function implementation block, giving it an explicit raise: def spam(x, y): if x is None and y <= 0: raise SomeError # implementation continues... Now you've given up any hope of disabling that specific check, short of editing the source code. Then you have to make a unit test to check that it works the way you think it does: def test_if_x_is_none_y_cannot_be_negative_or_zero(self): # Naming things is hard... self.AssertRaise(SomeError, spam, None, -1) self.AssertRaise(SomeError, spam, None, 0) Great! Now we know that if spam is passed None and -1, or None and 0, it will correctly fail. But the unit test doesn't give us any confidence that None and -9137 will fail, since we haven't tested that case. Work-around: I often write unit tests like this: def test_if_x_is_none_y_cannot_be_negative_or_zero(self): for i in range(20): # I never know how many or how few values to check... n = random.randint(1, 1000) # or which values... self.AssertRaise(SomeError, spam, None, -n) self.AssertRaise(SomeError, spam, None, 0) As David points out in another post, it is true that Contracts also can only check the values that you actually pass to the application during the testing phase, but that is likely to be a larger set of values than those we put in the unit tests, which lets us gain confidence in the code more quickly and with less effort. Rather than write lots of explicit tests, we can just exercise the routine with realistic data and see if the contract checks fail. [...] > > (6) Separation of concerns: function algorithm versus error checking > > Agreed, so long as you can define the contract in a way that isn't > just duplicating the function's own body. Sure. That's a case where contracts aren't really suitable and a few unit tests would be appropriate, but that's only likely to apply to post-conditions, not pre-conditions. > Contracts are great for some situations, but I'm seeing a lot of cases > where they're just plain not, yet advocates still say "use contracts, > use contracts". Why? For the same reason advocates say "Use tests, use tests" despite there being
Re: [Python-ideas] Transpiling contracts
Hi Marko, I’m going to refer to the transpiler syntax as “block syntax.” 1. How does Eiffel do formal contracts? 2. What’s the use case for preferring block syntax over lambda syntax? Is the block syntax only better when multiple statements are needed to test a single contract condition? 2. If the last proposition is true, how often do we need multiple statements to test or specify a single contract condition? 3. When we do need multiple statements to formally verify/specify, is it usually a better idea to factor out major functionality of the contract testing to an external function? (So other contracts can use the same external function and the intent of the contract is clear trough the function name) 4. If this is true, is it a good idea to include a contracts/ folder at the same folder level or a .contracts.py file to list “helper” or verification functions for a contract? I think we should answer questions two and three by looking at real code. — If MockP is supported, it could be used for all the contract decorators: @snapshot(var=P.self.name) @post(var=R.attr == P.old.var) The decorator can also check the type of the returned object, and if it’s MockP it will use MockP protocol and otherwise it will check the object is callable and treat it as a lambda. Your approach has better type hinting, but I’m not sure if type hinting would be that useful if you’re adding a contract whilst writing the function. James Lu > On Oct 1, 2018, at 1:01 AM, Marko Ristin-Kaufmann > wrote: > > Hi James, > >> Regarding the “transpile into Python” syntax with with statements: Can I see >> an example of this syntax when used in pathlib? I’m a bit worried this >> syntax is too long and “in the way”, unlike decorators which are before the >> function body. Or do you mean that both MockP and your syntax should be >> supported? >> >> Would >> >> with requiring: assert arg1 < arg2, “message” >> >> Be the code you type or the code that’s actually run? > > > That's the code you would type. Let me make a full example (I'm omitting > "with contracts" since we actually don't need it). > > You would read/write this: > def some_func(arg1: List[int])->int: > with requiring: > assert len(arg1) > 3, "some description" > > with oldie as O, resultie as result, ensuring: > if SLOW: > O.var1 = sum(arg1) > assert result > sum(arg1) > O.var1 > > assert len(result) > 5 > > This would run: > @requires(lambda P: len(P.arg1) > 3, "some description") > @snapshot(lambda P, var1: sum(P.arg1), enabled=SLOW) > @ensures(lambda O, P, result: result > sum(arg1) > O.var1, enabled=SLOW) > @ensures(lambda result: len(result) > 5) > > I omitted in the example how to specify a custom exception to avoid confusion. > > If we decide that transpiler is the way to go, I'd say it's easier to just > stick with lambdas and allow no mock-based approach in transpilation. > > Cheers, > Marko > > > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
On Sun, Sep 30, 2018 at 06:19:11PM -0400, Eric V. Smith wrote: > On 9/30/2018 8:11 AM, Stephen J. Turnbull wrote: > >Steven D'Aprano writes: > > > (7) You can't unit test loop invariants > > > >I don't see how a loop invariant can be elegantly specified without > >mixing it in to the implementation. Can you show an example of code > >written in a language with support for loop invariants *not* mixed > >into the implementation? > > I'd be very interested in this, too. Any pointers? I'm not sure how Stephen went from my comment that you can't unit test loop invariants to the idea that loop invariants aren't in the implementation. Obviously the loop invariant has to be attached to the loop. You can't attach a loop invariant to a method or class, because they might contain more than one loop. https://en.wikipedia.org/wiki/Loop_invariant#Eiffel from x := 0 invariant x <= 10 until x > 10 loop x := x + 1 end -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
Hi Steve (Turnbull), It sounds to me like the proof of the pudding for Python will be > annotating the ABC module with contracts. If that turns out to be a > mostly fruitless exercise, it's hard to see how "real" contracts > (vs. using asserts to "program in contracting style") are an important > feature for Python in general. > Do you mean annotating an abstract class with contracts or annotating the actual functions in abc module? If you meant abstract classes in general, we do that for quite some time in our code base and had no problems so far. icontract already supports inheritance of contracts (as well as weakening/strengthening of the contracts). Inheriting of contracts also proved useful when you define an interface as a group of functions together with the contracts. You define the functions as an ABC with purely static methods (no state) and specify the contracts in that abstract class. The concrete classes implement the static functions, but don't need to repeat the contracts since they are inherited from the abstract class. I can copy/paste from our code base if you are interested. Cheers, Marko On Mon, 1 Oct 2018 at 15:09, Stephen J. Turnbull < turnbull.stephen...@u.tsukuba.ac.jp> wrote: > Elazar writes: > > On Sun, Sep 30, 2018, 15:12 Stephen J. Turnbull < > > turnbull.stephen...@u.tsukuba.ac.jp> wrote: > > > > What does "inherited" mean? Just that methods that are not overridden > > > retain their contracts? > > > > Contracts are attached to interfaces, not to specifications. So > > when you have abstract base class, it defines contracts, and > > implementing classes must adhere to these contracts - the can only > > strengthen it, not weaken it. > > Stated in words, it sounds very reasonable. > > Thinking about the implications for writing Python code, it sounds > very constraining in the context of duck-typing. Or, to give a > contrapositive example, you can write few, if any, contracts for > dunders beyond their signatures. For example, len(x) + len(y) == > len(x + y) is not an invariant over the classes that define __len__ > (eg, set and dict, taking the "x + y" loosely for them). Of course if > you restrict to Sequence, you can impose that invariant. The question > is the balance. > > It sounds to me like the proof of the pudding for Python will be > annotating the ABC module with contracts. If that turns out to be a > mostly fruitless exercise, it's hard to see how "real" contracts > (vs. using asserts to "program in contracting style") are an important > feature for Python in general. > > That said, given the passion of the proponents, if we can come up with > an attractive style for implementing contracts without a language > change, I'd be +0 at least for adding a module to the stdlib. But > this is a Python 3.9 project, given the state of the art. > > > This is precisely like with types, since types are contracts (and > > vice versa, in a way). > > Not Python types (== classes), though. As a constraint on behavior, > subclassing is purely nominal, although Python deliberately makes it > tedious to turn a subclass of str into a clone of int. > > Steve > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Simplicity of C (was why is design-by-contracts not widely)
Elazar writes: > On Sun, Sep 30, 2018, 15:12 Stephen J. Turnbull < > turnbull.stephen...@u.tsukuba.ac.jp> wrote: > > What does "inherited" mean? Just that methods that are not overridden > > retain their contracts? > > Contracts are attached to interfaces, not to specifications. So > when you have abstract base class, it defines contracts, and > implementing classes must adhere to these contracts - the can only > strengthen it, not weaken it. Stated in words, it sounds very reasonable. Thinking about the implications for writing Python code, it sounds very constraining in the context of duck-typing. Or, to give a contrapositive example, you can write few, if any, contracts for dunders beyond their signatures. For example, len(x) + len(y) == len(x + y) is not an invariant over the classes that define __len__ (eg, set and dict, taking the "x + y" loosely for them). Of course if you restrict to Sequence, you can impose that invariant. The question is the balance. It sounds to me like the proof of the pudding for Python will be annotating the ABC module with contracts. If that turns out to be a mostly fruitless exercise, it's hard to see how "real" contracts (vs. using asserts to "program in contracting style") are an important feature for Python in general. That said, given the passion of the proponents, if we can come up with an attractive style for implementing contracts without a language change, I'd be +0 at least for adding a module to the stdlib. But this is a Python 3.9 project, given the state of the art. > This is precisely like with types, since types are contracts (and > vice versa, in a way). Not Python types (== classes), though. As a constraint on behavior, subclassing is purely nominal, although Python deliberately makes it tedious to turn a subclass of str into a clone of int. Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Suggestion: Extend integers to include iNaN
On 2018-09-30 10:45, Anders Hovmöller wrote: > >>> I am roughing out such a class and some test cases which will hopefully >>> include some cases where the hoped for advantages can be realised. >>> >>> My thinking on bitwise operations is to do the same as arithmetic >>> operations, i.e. (anything op iNaN) = iNaN and likewise for shift >>> operations. >> Steve, >> >> While you are extending a number system, can every int be truthy, while >> only iNan be falsey? I found that behaviour more useful because >> checking if there is a value is more common than checking if it is a >> zero value. > I’m not saying you’re wrong in principle but such a change to Python seems > extremely disruptive. And if we’re talking about robustness of code then > truthiness would be better like in Java (!) imo, where only true is true and > false is false and everything else is an error. If we’re actually talking > about changing the truth table of Python for basic types then this is the > logical next step. > > But making any change to the basic types truth table is a big -1 from me. > This seems like a Python 2-3 transition to me. Sorry, I can see I was unclear: I was only asking that the new number system (and the class that implements it) have truthy defined differently. My imagination never considered extending ints with iNaN. I would imagine the iNaN checks on every int operation to be noticeably slower, so out of the question. ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Suggestion: Extend integers to include iNaN
Hi Steve You've suggested that we add to Python an integer NaN object, similar to the already existing float NaN object. >>> x = float('nan') >>> x, type(x) (nan, ) I've learnt that decimal also has a NaN object, but not fractions. https://stackoverflow.com/questions/19374254/ >>> from decimal import Decimal >>> y = Decimal('nan') >>> y, type(y) (Decimal('NaN'), ) Numpy has its own fixed size int classes >>> from numpy import int16 >>> x = int16(2358); x, type(x) (2358, ) >>> x = x * x; x, type(x) __main__:1: RuntimeWarning: overflow encountered in short_scalars (-10396, ) I'm confident that one could create classes similar to numpy.int16, except that >>> z = int16('nan') Traceback (most recent call last): ValueError: invalid literal for int() with base 10: 'nan' would not raise an exception (and would have the semantics you wish for). I wonder, would this be sufficient for the use cases you have in mind? -- Jonathan ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Suggestion: Extend integers to include iNaN
On Mon, 1 Oct 2018 at 00:00, Chris Angelico wrote: > > On Mon, Oct 1, 2018 at 8:53 AM Oscar Benjamin > wrote: > > > > On Sun, 30 Sep 2018 at 02:01, Steven D'Aprano wrote: > > > > > > On Sat, Sep 29, 2018 at 09:43:42PM +0100, Oscar Benjamin wrote: > > > > On Sat, 29 Sep 2018 at 19:38, Steve Barnes > > > > wrote: > > > > > > > > > I converted to int because I needed a whole number, this was > > > > > > intended to > > > > > represent some more complex process where a value is converted to a > > > > > whole number down in the depths of the processing. > > > > > > > > Your requirement to have a whole number cannot meaningfully be > > > > satisfied if your input is nan so an exception is the most useful > > > > result. > > > > > > Not to Steve it isn't. > > > > > > Be careful about making value judgements like that: Steve is asking for > > > an integer NAN because for *him* an integer NAN is more useful than an > > > exception. You shouldn't tell him that he is wrong, unless you know his > > > use-case and his code, which you don't. > > > > Then he can catch the exception and do something else. If I called > > int(x) because my subsequent code "needed a whole number" then I would > > definitely not want to end up with a nan. The proposal requested is > > that int(x) could return something other than a well defined integer. > > That would break a lot of code! > > At no point was the behaviour of int(x) ever proposed to be changed. > Don't overreact here. The context got trimmed a bit too much. You can see here the messages preceding what is quoted above: https://mail.python.org/pipermail/python-ideas/2018-September/053840.html Quoting here: > One simplistic example would be print(int(float('nan'))) (gives a ValueError) > while print(int(iNaN)) should give 'nan' or maybe 'inan' That would mean that the result of int(x) is no longer guaranteed to be a well-defined integer. > The recommended use-case was for a library to > return iNaN instead of None when it is unable to return an actual > value. You can already use None or float('nan') for this. You can also create your own singleton nan object if you want. When I said I haven't seen a use-case what I mean is that no one has presented a situation where the existing language facilities are considered insufficient (apart from the suggestion about int(iNaN) that I refer to above). -- Oscar ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Renaming icontract to pcontract
Hi Cameron, A nerdy way to make it sound like a sentence: "I contract that ...". Pcontract would stand for python contract. Pycontract is already taken. Cheers, Marko Le lun. 1 oct. 2018 à 09:15, Cameron Simpson a écrit : > On 01Oct2018 07:25, Marko Ristin-Kaufmann wrote: > >I'd like to rename icontract into pcontract to avoid name conflict with > >java's icontract library. > > > >Do you have any better suggestion? > > No, sounds ok to me. What was the "i" for in the old name? > > Cheers, > Cameron Simpson > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Renaming icontract to pcontract
On 01Oct2018 07:25, Marko Ristin-Kaufmann wrote: I'd like to rename icontract into pcontract to avoid name conflict with java's icontract library. Do you have any better suggestion? No, sounds ok to me. What was the "i" for in the old name? Cheers, Cameron Simpson ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/