Skip to main content

Type Checking and Constraints via Function Annotations

Project description

constrict
=========
Constrict is a framework for adding type checking and constraints to functions.
Constraints are declared as function annotations (following the `typespec`
format) and type checking is added using function decorators.

Constrict also provides a set of assertions for ad hoc type checking an a mix
in TestCase class for extending your unit tests.

Constrict depends on the ``typespec`` <https://github.com/galini/typespec>
module and you should see the documentation of that module for details of how
to format function arguments.

The Decorators
--------------

Import the decorators like so::

>>> from constrict import checkargs, checkreturn, checkyield, check

Adding type checking for function arguments::

>>> @checkargs
... def my_func_of_int(i : int) -> int:
... return i + 1
>>> my_func_of_int("hello")
Traceback (most recent call last):
...
constrict.ArgumentAssertionError: Invalid value 'hello' for argument i - i must be int.
>>> my_func_of_int(1)
2

Adding type checking for function return values::

>>> @checkreturn
... def my_func_of_int(i : int) -> int:
... return str(i+1)
>>> my_func_of_int("hello")
Traceback (most recent call last):
...
TypeError: Can't convert 'int' object to str implicitly
>>> my_func_of_int(1)
Traceback (most recent call last):
...
constrict.ReturnAssertionError: Invalid return value '2' - value must be int.

Adding type checking for yielded values::

>>> @checkyield
... def my_generator() -> int:
... for val in (1, 2, 3, "4", 5, 6):
... yield val
>>> for val in my_generator():
... pass
Traceback (most recent call last):
...
constrict.YieldAssertionError: Invalid yielded value '4' - value must be int.

The ``check`` decorator is the same as using both ``checkargs`` and
``checkreturn`` for a function or ``checkargs`` and ``checkyield`` for a
generator.

The Assertions
--------------

Importing all assertions::

>>> from constrict import (assert_isa, assert_valid, assert_valid_args,
... assert_valid_return, assert_valid_yield, assert_call_ok,
... assert_iter_ok)

The assertions are functions that work like the ``assert`` statement. They do
dynamic type checking and raise errors for invalid types. See the documentation
of each function for further details.

Using With unittest
-------------------

You can write test cases that check argument, return and yielded values.
Simply mix in the constrict.TestCase class into your test cases::

import unittest
import constrict

class MyTestCase(unittest.TestCase, constrict.TestCase):
def testSomething(self):
...

if __name__ == '__main__':
unittest.main()

This makes available extra test assertions that you can use.
See the documentation of the ``constrict.TestCase`` class for more details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

constrict-1.0.0.tar.gz (4.0 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page