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.
=========
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
Release history Release notifications | RSS feed
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 details)
File details
Details for the file constrict-1.0.0.tar.gz
.
File metadata
- Download URL: constrict-1.0.0.tar.gz
- Upload date:
- Size: 4.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a9f1b4cb34594c1450a16f71cd640ba61a1dc5e93580d1986eb5c1b000e8bf83 |
|
MD5 | 0a9c938445476a612e98e0a2fe4c0d24 |
|
BLAKE2b-256 | 7feee3337478e6005d93feeac78a2cf54be3420a36652d3f348a9b7d0fe60276 |