Typing system for places (and transitions guards). Types are contraint checkers to verify whether a value is in the type or not. For instance:

``````>>> 5 in tInteger
True
>>> 4.3 in tInteger
False``````

The typechecking of several values is possible using the type as a function. It fails if one value is not in the type.

``````>>> tInteger(5, 4, 6)
True
>>> tInteger(5, 4, 6.0)
False``````

Types can be composed in order to build more complexe types. For example:

``````>>> 8 in (tInteger & ~Range(1, 5))
True
>>> 3 in (tInteger & ~Range(1, 5))
False``````

The various compositions are the same as sets operations, plus the complement: `&`, `|`, `-`, `^` and `~` (complement).

Various types are predefined (like `tInteger`) the others can be constructed using the various classes in the module. Prefefined types are:

• `tAll`: any value is in the type
• `tNothing`: empty type
• `tString`: string values
• `tList`: lists values
• `tInteger`: integer values
• `tNatural`: non-negative integers
• `tPositive`: strictly positive integers
• `tFloat`: float values
• `tNumber`: integers or float values
• `tDict`: Python's `dict` values
• `tNone`: the single value `None`
• `tBoolean`: `True` or `False`
• `tTuple`: tuple values
• `tPair`: tuples of length two

Types with finitely many elements can be iterated over:

``````>>> list(sorted(iter(CrossProduct(Range(0, 10, 2), tBoolean) & ~OneOf((4, True), (6, False)))))
[(0, False), (0, True), (2, False), (2, True), (4, False), (6, True), (8, False), (8, True)]
>>> list(iter(OneOf(1, 2, 3)))
[1, 2, 3]
>>> iter(tInteger)
Traceback (most recent call last):
...
TypeError: ... not iterable
>>> iter(~OneOf(1, 2, 3))
Traceback (most recent call last):
...
TypeError: ... not iterable``````

### Class `Type`

``class Type (object) :``

Base class for all types. Implements operations `&`, `|`, `-`, `^` and `~` to build new types. Also implement the typechecking of several values. All the subclasses should implement the method `__contains__` to typecheck a single object.

This class is abstract and should not be instantiated.

#### Method `Type.__and__`

``def __and__ (self, other) :``

Intersection type.

``````>>> Instance(int) & Greater(0)
(Instance(int) & Greater(0))``````
##### Call API
• `Type other`: the other type in the intersection
• `return Type`: the intersection of both types

#### Method `Type.__or__`

``def __or__ (self, other) :``

Union type.

``````>>> Instance(int) | Instance(bool)
(Instance(int) | Instance(bool))``````
##### Call API
• `Type other`: the other type in the union
• `return Type`: the union of both types

#### Method `Type.__sub__`

``def __sub__ (self, other) :``

Substraction type.

``````>>> Instance(int) - OneOf([0, 1, 2])
(Instance(int) - OneOf([0, 1, 2]))``````
##### Call API
• `Type other`: the other type in the substraction
• `return Type`: the type `self` minus the type `other`

#### Method `Type.__xor__`

``def __xor__ (self, other) :``

Disjoint union type.

``````>>> Greater(0) ^ Instance(float)
(Greater(0) ^ Instance(float))``````
##### Call API
• `Type other`: the other type in the disjoint union
• `return Type`: the disjoint union of both types

#### Method `Type.__invert__`

``def __invert__ (self) :``

Complementary type.

``````>>> ~ Instance(int)
(~Instance(int))``````
##### Call API
• `return Type`: the complementary type

#### Method `Type.__call__`

``def __call__ (self, *values) :``

Typecheck values.

``````>>> Instance(int)(3, 4, 5)
True
>>> Instance(int)(3, 4, 5.0)
False``````
##### Call API
• `object values`: values that have to be checked
• `return bool`: `True` if all the values are in the types, `False` otherwise

### Class `Instance`

``class Instance (Type) :``

A type whose values are all instances of one class.

``````>>> [1, 2] in Instance(list)
True
>>> (1, 2) in Instance(list)
False``````

#### Method `Instance.__init__`

``def __init__ (self, _class) :``

Initialize the type

``````>>> Instance(int)
Instance(int)``````
##### Call API
• `class _class`: the class of instance
• `return Instance`: initialized object

### Class `TypeCheck`

``class TypeCheck (Type) :``

A type whose values are accepted by a given function.

``````>>> def odd (val) :
...     return type(val) is int and (val % 2) == 1
>>> 3 in TypeCheck(odd)
True
>>> 4 in TypeCheck(odd)
False
>>> 3.0 in TypeCheck(odd)
False``````

#### Method `TypeCheck.__init__`

``def __init__ (self, checker, iterate=None) :``

Initialize the type, optionally, a function to iterate over the elements may be provided.

``````>>> import operator
>>> TypeCheck(operator.truth)
TypeCheck(...truth)
>>> list(TypeCheck(operator.truth))
Traceback (most recent call last):
...
ValueError: type not iterable
>>> def true_values () : # enumerates only choosen values
...     yield True
...     yield 42
...     yield '42'
...     yield 
...     yield (42,)
...     yield {True: 42}
>>> TypeCheck(operator.truth, true_values)
TypeCheck(...truth, snakes.typing.true_values)
>>> list(TypeCheck(operator.truth, true_values))
[True, 42, '42', , (42,), {True: 42}]``````
##### Call API
• `callable checker`: a function that checks one value and returns `True` if it is in te type and `False` otherwise
• `generator iterate`: `None` or an iterator over the values of the type

### Class `OneOf`

``class OneOf (Type) :``

A type whose values are explicitely enumerated.

``````>>> 3 in OneOf(1, 2, 3, 4, 5)
True
>>> 0 in OneOf(1, 2, 3, 4, 5)
False``````

### Class `Collection`

``class Collection (Type) :``

A type whose values are a given container, holding items of a given type and ranging in a given interval.

``````>>> [0, 1.1, 2, 3.3, 4] in Collection(Instance(list), tNumber, 3, 10)
True
>>> [0, 1.1] in Collection(Instance(list), tNumber, 3, 10) #too short
False
>>> [0, '1.1', 2, 3.3, 4] in Collection(Instance(list), tNumber, 3, 10) #wrong item
False``````

#### Method `Collection.__init__`

``def __init__ (self, collection, items, min=None, max=None) :``

Initialise the type

``````>>> Collection(Instance(list), tNumber, 3, 10)
Collection(Instance(list), (Instance(int) | Instance(float)), min=3, max=10)``````
##### Call API
• `Type collection`: the collection type
• `Type items`: the type of the items
• `object min`: the smallest allowed value
• `object max`: the greatest allowed value

### Function `List`

``def List (items, min=None, max=None) :``

Shorthand for instantiating `Collection`

``````>>> List(tNumber, min=3, max=10)
Collection(Instance(list), (Instance(int) | Instance(float)), min=3, max=10)``````
##### Call API
• `Type items`: the type of the elements in the collection
• `int min`: the minimum number of elements in the collection or `None`
• `int max`: the maximum number of elements in the collection or `None`
• `return Collection`: a type that checks the given constraints

### Function `Tuple`

``def Tuple (items, min=None, max=None) :``

Shorthand for instantiating `Collection`

``````>>> Tuple(tNumber, min=3, max=10)
Collection(Instance(tuple), (Instance(int) | Instance(float)), min=3, max=10)``````
##### Call API
• `Type items`: the type of the elements in the collection
• `int min`: the minimum number of elements in the collection or `None`
• `int max`: the maximum number of elements in the collection or `None`
• `return Collection`: a type that checks the given constraints

### Function `Set`

``def Set (items, min=None, max=None) :``

Shorthand for instantiating `Collection`

``````>>> Set(tNumber, min=3, max=10)
Collection(Instance(set), (Instance(int) | Instance(float)), min=3, max=10)``````
##### Call API
• `Type items`: the type of the elements in the collection
• `int min`: the minimum number of elements in the collection or `None`
• `int max`: the maximum number of elements in the collection or `None`
• `return Collection`: a type that checks the given constraints

### Class `Mapping`

``class Mapping (Type) :``

A type whose values are mapping (eg, `dict`)

``````>>> {'Yes': True, 'No': False} in Mapping(tString, tAll)
True
>>> {True: 1, False: 0} in Mapping(tString, tAll)
False``````

#### Method `Mapping.__init__`

``def __init__ (self, keys, items, _dict=Instance(dict)) :``

Initialise a mapping type

``````>>> Mapping(tInteger, tFloat)
Mapping(Instance(int), Instance(float), Instance(dict))
>>> from snakes.data import hdict
>>> Mapping(tInteger, tFloat, Instance(hdict))
Mapping(Instance(int), Instance(float), Instance(hdict))``````
##### Call API
• `Type keys`: the type for the keys
• `Type items`: the type for the items
• `dict _dict`: the class that mapping must be instances of

### Class `Range`

``class Range (Type) :``

A type whose values are in a given range

Notice that ranges are not built into the memory so that huge values can be used.

``````>>> 3 in Range(1, 2**128, 2)
True
>>> 4 in Range(1, 2**128, 2)
False``````

#### Method `Range.__init__`

``def __init__ (self, first, last, step=1) :``

The values are those that the builtin ```range(first, last, step)``` would return.

``````>>> Range(1, 10)
Range(1, 10)
>>> Range(1, 10, 2)
Range(1, 10, 2)``````
##### Call API
• `int first`: first element in the range
• `int last`: upper bound of the range, not belonging to it
• `int step`: step between elements in the range

### Class `Greater`

``class Greater (Type) :``

A type whose values are greater than a minimum.

The minimum and the checked values can be of any type as soon as they can be compared with `>`.

``````>>> 6 in Greater(3)
True
>>> 3 in Greater(3)
False``````

#### Method `Greater.__init__`

``def __init__ (self, min) :``

Initialises the type

``````>>> Greater(5)
Greater(5)``````
##### Call API
• `object min`: the greatest value not included in the type

### Class `GreaterOrEqual`

``class GreaterOrEqual (Type) :``

A type whose values are greater or equal than a minimum.

See the description of `Greater`

#### Method `GreaterOrEqual.__init__`

``def __init__ (self, min) :``

Initialises the type

``````>>> GreaterOrEqual(5)
GreaterOrEqual(5)``````
##### Call API
• `object min`: the minimal allowed value

### Class `Less`

``class Less (Type) :``

A type whose values are less than a maximum.

See the description of `Greater`

#### Method `Less.__init__`

``def __init__ (self, max) :``

Initialises the type

``````>>> Less(5)
Less(5)``````
##### Call API
• `object max`

### Class `LessOrEqual`

``class LessOrEqual (Type) :``

A type whose values are less than or equal to a maximum.

See the description of `Greater`

#### Method `LessOrEqual.__init__`

``def __init__ (self, max) :``

Initialises the type

``````>>> LessOrEqual(5)
LessOrEqual(5)``````
##### Call API
• `object max`

### Class `CrossProduct`

``class CrossProduct (Type) :``

A type whose values are tuples, each component of them being in given types. The resulting type is the cartesian cross product of the compound types.

``````>>> (1, 3, 5) in CrossProduct(Range(1, 10), Range(1, 10, 2), Range(1, 10))
True
>>> (2, 4, 6) in CrossProduct(Range(1, 10), Range(1, 10, 2), Range(1, 10))
False``````

#### Method `CrossProduct.__init__`

``def __init__ (self, *types) :``

Initialise the type

``````>>> CrossProduct(Instance(int), Instance(float))
CrossProduct(Instance(int), Instance(float))``````
##### Call API
• `Type types`: the types of each component of the allowed tuples