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 <wes.turner@gmail.com> 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/python-ideas@python.org/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 <pythonchb@gmail.com> wrote:
On Sun, Jun 14, 2020 at 8:41 AM Paul Moore <p.f.moore@gmail.com> 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 -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@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/MPST6DZ2WF2XBIO4U26II2WJGTHRL3OL/
Code of Conduct: http://python.org/psf/codeofconduct/