Welcome to Pytyp’s documentation!

Utilities that help you write declarative code: instead of saying how something should be done, you describe what the results look like (examples).

Pytyp can help you:

Describe Python 3 data in more detail
pytyp.spec.abcs makes it easier to say what you want, and to write libraries that support a declarative style.
Map serialised data to Python objects (and back again)
pytyp.s11n contains modules (pytyp.s11n.json and pytyp.s11n.yaml) that transform JSON and YAML data. This is a good example of declarative code - you say what classes you want, and the routine works out how to construct them.
Verify function arguments
pytyp.spec.check provides a decorator to verify that function arguments are of the type expected.
Use dynamic dispatch by type
pytyp.spec.dispatch module lets you split complex functions into separate parts, depending on the arguments given.
Use attributes instead of [], and vice versa
pytyp.spec.record contains a useful class that is both a dict and an object.

Note

The ideas behind this library are described in the paper Algebraic ABCs.

The library has been almost completely rewritten for the 2.0 release. Public APIs have changed. You may need to fix your code when updating.

Installation and Support

To install from PyPI:

easy_install pytyp

Warning

This project is Python 3 only.

For source see Google Code; for support email Andrew Cooke.

Indices and tables

Examples

Testing type specifications (pytyp.spec.abcs):

>>> isinstance([1,2,None,3], Seq(Opt(int)))
True
>>> isinstance([1,2,None,3.0], Seq(Opt(int)))
False

Verifying function arguments (pytyp.spec.check):

>>> def myfunction(a:int, b:str) -> int:
...     return len(a * b)
>>> myfunction(2, 'foo')
6
>>> myfunction('oops', 'banana')
Traceback (most recent call last):
  ...
TypeError: Type str inconsistent with 'oops'.

Loading JSON data into Python classes:

>>> class Example():
...     def __init__(self, foo):
...         self.foo = foo
...     def __repr__(self):
...         return '<Example({0})>'.format(self.foo)
>>> class Container():
...     def __init__(self, *examples:[Example]):
...         self.examples = examples
...     def __repr__(self):
...         return '<Container({0})>'.format(','.join(map(repr, self.examples)))
>>> loads = make_loads(Container)
>>> loads('[{"foo":"abc"}, {"foo":"xyz"}]')
<Container(<Example(abc)>,<Example(xyz)>)>

This is very inobtrusive - the type expected is given to make_loads() and “chained” through type annotations in the constructors - but relies extensively on pytp. For example, the annotation of *examples is a type specification (equivalent to Seq(Example)), and the implementation uses’s pytyp’s support for iteration and dynamic dispatch by type. This gives the command surprising flexibility. For example, the required class can be given as set of alternatives (eg. Alt(Container,Foo,Bar)) and the “right” solution will be returned, depending on the input data.

Table Of Contents

Next topic

Type Specifications (pytyp.spec.abcs)

This Page