Base classes for defining abstract data types.

This module provides three public members, which are used together.

Given a structure, possibly a choice of different structures, that you’d like to associate with a type:

  • First, create a class, that subclasses the Sum class.
  • Then, for each possible structure, add an attribute annotation to the class with the desired name of the constructor, and a type of Ctor, with the types within the constructor as arguments.

To look inside an ADT instance, use the functions from the structured_data.match module.

Putting it together:

>>> from structured_data import match
>>> class Example(Sum):
...     FirstConstructor: Ctor[int, str]
...     SecondConstructor: Ctor[bytes]
...     ThirdConstructor: Ctor
...     def __iter__(self):
...         matchable = match.Matchable(self)
...         if matchable(Example.FirstConstructor(match.pat.count, match.pat.string)):
...             count, string = matchable[match.pat.count, match.pat.string]
...             for _ in range(count):
...                 yield string
...         elif matchable(Example.SecondConstructor(match.pat.bytes)):
...             bytes_ = matchable[match.pat.bytes]
...             for byte in bytes_:
...                 yield chr(byte)
...         elif matchable(Example.ThirdConstructor()):
...             yield "Third"
...             yield "Constructor"
>>> list(Example.FirstConstructor(5, "abc"))
['abc', 'abc', 'abc', 'abc', 'abc']
>>> list(Example.SecondConstructor(b"abc"))
['a', 'b', 'c']
>>> list(Example.ThirdConstructor())
['Third', 'Constructor']
class structured_data.adt.Ctor[source]

Marker class for adt constructors.

To use, index with a sequence of types, and annotate a variable in an adt-decorated class with it.

class structured_data.adt.Product[source]

Base class of classes with typed fields.

Examines PEP 526 __annotations__ to determine fields.

If repr is true, a __repr__() method is added to the class. If order is true, rich comparison dunder methods are added.

The Product class examines the class to find annotations. Annotations with a value of “None” are discarded. Fields may have default values, and can be set to inspect.empty to indicate “no default”.

The subclass is subclassable. The implementation was designed with a focus on flexibility over ideals of purity, and therefore provides various optional facilities that conflict with, for example, Liskov substitutability. For the purposes of matching, each class is considered distinct.

class structured_data.adt.Sum[source]

Base class of classes with disjoint constructors.

Examines PEP 526 __annotations__ to determine subclasses.

If repr is true, a __repr__() method is added to the class. If order is true, rich comparison dunder methods are added.

The Sum class examines the class to find Ctor annotations. A Ctor annotation is the adt.Ctor class itself, or the result of indexing the class, either with a single type hint, or a tuple of type hints. All other annotations are ignored.

The subclass is not subclassable, but has subclasses at each of the names that had Ctor annotations. Each subclass takes a fixed number of arguments, corresponding to the type hints given to its annotation, if any.

class structured_data.adt.SumBase[source]

Dummy class to help keep Sum and Product separate.