icontract supports preconditions with decorators (that are compatible with
type information stored in annotations :

```

@icontract.require(lambda x: x > 3)
def some_func(x: int, y: int = 5)->None:
    pass

```

PyContracts supports a few different syntaxes for specifying preconditions:
decorator, annotations, docstrings. Unfortunately, AFAIU, the annotations
syntax is not compatible with MyPy/typeshed capitalizations:

http://andreacensi.github.io/contracts/

```

Specifying contracts: Contracts can be specified in three ways:

Using the ``@contract`` decorator:

@contract(a='int,>0', b='list[N],N>0', returns='list[N]')
def my_function(a, b):
    ...
Using annotations (for Python 3):

@contract
def my_function(a : 'int,>0', b : 'list[N],N>0') -> 'list[N]':
     # Requires b to be a nonempty list, and the return
     # value to have the same length.
     ...
Using docstrings, with the :type: and :rtype: tags:

@contract
def my_function(a, b):
    """ Function description.
        :type a: int,>0
        :type b: list[N],N>0
        :rtype: list[N]
    """
    ...
Deployment: In production, all checks can be disabled using the function
contracts.disable_all(), so the performance hit is 0.

```

PEP-316 proposed a docstring syntax which also predates py3k annotations.

On Sun, Jun 14, 2020, 5:47 PM Wes Turner <[email protected]> wrote:

> Such preconditions (checks of input parameters beyond their type at
> compile-tine) are a feature of DbC: Design by Contract.
>
> https://en.wikipedia.org/wiki/Design_by_contract
>
> Python is listed under "Languages with third-party support" :
>
> > Python, using packages like icontract, PyContracts, Decontractors,
> dpcontracts, zope.interface, PyDBC or Contracts for Python. A permanent
> change to Python to support Design by Contracts was proposed in PEP-316,
> but deferred
>
> https://www.python.org/dev/peps/pep-0316/ (2003)
>
>
> "Contracts in python -- a report & next steps" (2018)
>
> https://mail.python.org/archives/list/[email protected]/thread/3TDEJI4M4LLS56IUHII6W5DLPNPW7BGU/
>
> ... https://github.com/Parquery/icontract :
>
> > Second, icontract allows inheritance of the contracts and supports
> weakining of the preconditions as well as strengthening of the
> postconditions and invariants. Notably, weakining and strengthening of the
> contracts is a feature indispensable for modeling many non-trivial class
> hierarchies. Please see Section Inheritance. To the best of our knowledge,
> there is currently no other Python library that supports inheritance of the
> contracts in a correct way.
>
> On Sun, Jun 14, 2020, 12:29 PM Christopher Barker <[email protected]>
> wrote:
>
>> On Sun, Jun 14, 2020 at 8:41 AM Paul Moore <[email protected]> wrote:
>>
>>> As Chris A says, I'd be inclined to see how far we can get with
>>> (extended) type hints before going for new syntax, though.
>>>
>>> > def foo() -> {1, 2, 3}:
>>> >    return 2
>>>
>>> That is, of course, valid syntax right now. I wonder what a type
>>> checker could do with it? Similarly,
>>>
>>
>> Well, the thing is that there is no way to know at compile time what
>> Value is getting passed in -- this is really more a way to catch a
>> ValueError than TypeError, so can't be done with static type checking.
>>
>> Unless you do, as ChrisA suggests, crate a Type (and Enum) that you can
>> then check for.
>>
>> But while I like the idea of Enums, particularly for, say multi-valued
>> flags, They require an extra name and extra typingthat I find annoying
>> (annoying enough that I haven't used one yet in my code. That is, I prefer,
>> so use Chris A's example:
>>
>> some_function(1, 2)
>>     ...
>>
>> to:
>>
>> from some_module import Spam
>>
>> some_function(Spam(1), 2)
>>    ...
>>
>> That being said, if you want your API to be "safe" and type-chackable,
>> then Enum is the way to go.
>>
>> As for the OP, who was asking for a run-time check, if:
>>
>> def fun(a, b):
>>     if a not in {1,2,3}:
>>         raise ValueError("a has to be one of these values: 1, 2, 3")
>>
>> is too verbose, you can always write a utility function (or a callable
>> class or closure that stores the options) to make it a simple one-liner:
>>
>> def fun(a, b):
>>     value_check(a, options= {1, 2, 3})
>>
>> -CHB
>>
>> --
>> Christopher Barker, PhD
>>
>> Python Language Consulting
>>   - Teaching
>>   - Scientific Software Development
>>   - Desktop GUI and Web Development
>>   - wxPython, numpy, scipy, Cython
>> _______________________________________________
>> Python-ideas mailing list -- [email protected]
>> To unsubscribe send an email to [email protected]
>> https://mail.python.org/mailman3/lists/python-ideas.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/[email protected]/message/MPST6DZ2WF2XBIO4U26II2WJGTHRL3OL/
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/XES6FH4BNRTY5YR5HRSXZPWXUR4VKXIV/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to