On Thu, Sep 09, 2021 at 09:16:23AM -0700, Guido van Rossum wrote:

>   assert cond, raise=ExcType(args)

How about this?

    if not cond: raise ExcType(args)

This is 100% backwards compatible, doesn't not abuse `assert`, will not 
be removed when running under -O, and takes exactly the same number of 
characters to type.

If we are seriously considering DBC for Python, here's is my initial 
proposal for function and method contracts. I don't have a proposal for 
class invariants as yet.


    def function(args):
        """Docstring"""

        require:
           # Preconditions checked before calling the function body.
           block

        ensure(result):
           # Postconditions checked after calling the function body.
           block

        # body of function


`require` and `ensure` would be soft-keywords, and legal only inside a 
`def` block, after the docstring and before the body of the function.

If present, the `require` block is executed before the body of the 
function. The precondition has access to the function arguments, but 
otherwise runs in its own namespace. Since it runs before the body, none 
of the body's local variables will be defined (apart from the function 
arguments).

If present, the `ensure` block is executed after the body of the 
function. It also runs in its own namespace, but has access to the 
function's body namespace. It also receives the function body's return 
result as a named argument. The parameter name "result" is not 
mandatory.

Both contract blocks are expected to either raise AssertionError, or 
just return. Raising other exceptions is permitted but discouraged.

Catching these exceptions is permitted but discouraged except for the 
purpose of logging.

When running under -O, both condition blocks are ignored. (At some time 
in the future we may add a fine-grained interface to disable them.)

I have chosen the names `require` and `ensure` to match the names used 
by Eiffel.

https://www.eiffel.org/doc/solutions/Design_by_Contract_and_Assertions

If the `require` and `ensure` blocks are all assertions, we can treat 
the blocks as executable *specifications documention*:

    def function(spam, eggs, cheese, aardvark):
        require:
            assert isinstance(spam, Food)
            assert -1 <= eggs < MAXEGGS
            assert cheese.colour = 'blue'
            assert aardvark is not None

        # function body


That should allow third-party checkers and tools to either do static 
pre- and post-condition checking, or to generate documentation from the 
conditions.


-- 
Steve
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/I3L2EPZJ3TA3W4OSBQJUA3WMVWHOCSCY/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to