contracts

PyContracts is a Python package that allows to declare constraints on function parameters and return values. Contracts can be specified using Python3 annotations, or inside a docstring. PyContracts supports a basic type system, variables binding, arithmetic constraints, and has several specialized contracts and an extension API.

  • 所有者: AndreaCensi/contracts
  • 平台:
  • 许可证: Other
  • 分类:
  • 主题:
  • 喜欢:
    0
      比较:

Github星跟踪图

.. image:: https://circleci.com/gh/AndreaCensi/contracts.svg?style=svg
:target: https://circleci.com/gh/AndreaCensi/contracts

PyContracts is a Python package that allows to declare constraints on function parameters and
return values. It supports a basic type system, variables binding, arithmetic constraints, and
has several specialized contracts (notably for Numpy arrays).

As a quick intro, please see this presentation about PyContracts_.

.. _this presentation about PyContracts: http://censi.mit.edu/pub/research/201410-pycontracts/201410-pycontracts.pdf

.. image:: http://censi.mit.edu/pub/research/201410-pycontracts/201410-pycontracts.border.png
:height: 100px
:target: http://censi.mit.edu/pub/research/201410-pycontracts/201410-pycontracts.pdf
:alt: A presentation about PyContracts

.. container:: brief_summary

A brief summary follows. See the full documentation at: <http://andreacensi.github.com/contracts/>

Why: The purpose of PyContracts is not to turn Python into a statically-typed language
(albeit you can be as strict as you wish), but, rather, to avoid the time-consuming and
obfuscating checking of various preconditions. In fact, more than the type constraints, I found
useful the ability to impose value and size constraints. For example, "I need a list of at least
3 positive numbers" can be expressed as list[>=3](number, >0)). If you find that
PyContracts is overkill for you, you might want to try a simpler alternative, such as
typecheck_. If you find that PyContracts is not enough for you, you probably want to be
using Haskell_ instead of Python.

Specifying contracts: Contracts can be specified in three ways:

  1. Using the @contract decorator: ::

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

  2. 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.
    ...

  3. 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]
    """
    ...

..
In any case, PyContracts will include the spec in the __doc__ attribute.

Deployment: In production, all checks can be disabled using the function contracts.disable_all(), so the performance hit is 0.

Extensions: You can extend PyContracts with new contracts types: ::

new_contract('valid_name', lambda s: isinstance(s, str) and len(s)>0)
@contract(names='dict(int: (valid_name, int))')
def process_accounting(records):
    ...

Any Python type is a contract: ::

@contract(a=int, # simple contract
          b='int,>0' # more complicated
          )
def f(a, b):
    ...

Enforcing interfaces: ContractsMeta is a metaclass,
like ABCMeta, which propagates contracts to the subclasses: ::

from contracts import contract, ContractsMeta, with_metaclass

class Base(with_metaclass(ContractsMeta, object)):

    @abstractmethod
    @contract(probability='float,>=0,<=1')
    def sample(self, probability):
        pass

class Derived(Base):
    # The contract above is automatically enforced, 
    # without this class having to know about PyContracts at all!
    def sample(self, probability):
        ....

Numpy: There is special support for Numpy: ::

@contract(image='array[HxWx3](uint8),H>10,W>10')
def recolor(image):
    ...

Status: The syntax is stable and it won't be changed. PyContracts is very well tested on Python 2.x.

Status on Python 3.x: We reached feature parity! Everything works on Python 3 now.

Contributors:

  • Chris Beaumont_ (Harvard-Smithsonian Center for Astrophysics): $var syntax; kwargs/args for extensions.
  • Brett Graham_ (Rowland Institute at Harvard University): attr(name:type) syntax for checking types of attributes.
  • William Furr_: bug reports and performance improvements
  • Karol Kuczmarski_ (Google Zurich): implementation of "string" and "unicode" contracts
  • Maarten Derickx_ (Leiden U.): documentation fixes
  • Calen Pennington_ (EdX): disabling checks inside check() function.
  • Adam Palay_ (EdX): implementation of environment variable enabling/disabling override.
  • Ryan Heimbuch_: bug reports
  • Bernhard Biskup: bug reports
  • asharp_: bug fixes
  • Dennis Kempin_ (Google mothership): Sphinx-style constraints specs
  • Andy Hayden_: Python 3 support, more efficient Numpy checks
  • Jonathan Sharpe_: contracts for file-like objects, not operator

(Please let me know if I forgot anybody.)

.. _Jonathan Sharpe: http://jonathansharpe.me.uk/

.. _Chris Beaumont: http://chrisbeaumont.org/
.. _asharp: https://github.com/asharp
.. _Maarten Derickx: http://mderickx.nl/
.. _Ryan Heimbuch: https://github.com/ryanheimbuch-wf
.. _Calen Pennington: https://github.com/cpennington
.. _Adam Palay: https://github.com/adampalay
.. _William Furr: http://www.ccs.neu.edu/home/furrwf/
.. _Karol Kuczmarski: http://xion.org.pl/
.. _Brett Graham: https://github.com/braingram
.. _Dennis Kempin: https://github.com/denniskempin
.. _Andy Hayden: http://careers.stackoverflow.com/hayd

.. _typecheck: http://oakwinter.com/code/typecheck/
.. _Haskell: http://www.haskell.org/

主要指标

概览
名称与所有者AndreaCensi/contracts
主编程语言Python
编程语言Makefile (语言数: 2)
平台
许可证Other
所有者活动
创建于2010-12-09 19:17:10
推送于2025-06-21 11:02:49
最后一次提交2020-06-29 19:33:13
发布数197
最新版本名称z7-prod-ok-june2026 (发布于 )
第一版名称0.9 (发布于 2010-12-25 13:31:34)
用户参与
星数407
关注者数14
派生数62
提交数471
已启用问题?
问题数65
打开的问题数43
拉请求数19
打开的拉请求数12
关闭的拉请求数10
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?