Fields

The Basics - Usage

Each field is a class. Using it has two variations: the simplified form is just the class names. For example:

names = Array[String]
name_and_age = Tuple[String, PositiveFloat]
age_by_name = Map[Sring, PositiveFloat]
name = String
quantity = Number

However, if more restriction are required, they need to be passed to the constructor. For Example:

name = Number(String(pattern='[A-Za-z]+$', maxLength=20)

Support For The Types In The “Typing” Module, and PEP-585

Starting at version 2.0, Typedpy supports field definition using the “typing”, making it look somewhat like a Dataclass:

class Example(Structure):
    names: List[str]
    id: int = 0
    my_dict: Dict[str, Union[str, list]]

Or PEP-585 style:

class Example(Structure):
    names: list[str]
    id: int = 0
    my_dict: dict[str, Union[str, list]]
    my_set: set[int]

The fields above will automatically be converted to their Typedpy counterparts. Superficially, it looks like a dataclass, but there are several differences:

  1. The IDE does not analyze the Typedpy definition as it does to dataclasses, thus it does not display warnings if the constructor is called with the wrong types. However, you can still annotate the Structure as @dataclass, which will make the IDE inspect it and display warnings as with a “regular” dataclass.

  2. Most importantly: Typedpy also enforces the definition dynamically, and blocks any code that creates or updates an instance so that it does not adhere to the definition.

  3. With Typedpy we can define a Structure as immutable, which is much more powerful than dataclass “frozen” setting.

  4. Typedpy offers flexible serialization/deserialization, as well as JSON Schema mapping.

  5. Typedpy inheritance is cleaner than dataclasses.

  6. Typedpy validates default values.

Combining Python and Typedpy types in field definition

Starting at version 2.6, Typedpy supports combining Typedpy and Python fields in definition better. It allows to mix standard Python classes(such as PEP-585 and the “typing” library) and Typedpy arbitrarily. This means that all the following fields definitions are valid and work as though they were “pure Typedpy”:

import typing
from typedpy import Array, Integer, String, Structure

class Foo(Structure):
    a0: list[str]
    a1: list[String]
    a2: typing.List[String(minLength=5)]
    a3: list[set[String]]
    a4: typing.List[String]
    a5: list[typing.Set[String]]
    a6: typing.List[typing.Set[String]]
    a7: Array[str]
    a8: Array[dict[str, Integer]]
    a9: Array[dict[String, int]]
    a10: Array[dict[String(minLength=5), int]]
    a11: typing.Optional[set[String]]

The motivation is to further simplify using Typedpy. Anything that relies on PEP-585 only works on Python version >= 3.9.

Implicit Wrapping of Arbitrary Classes As Field

(version > 2.0)

Supposed you defined your own class, and you want to use it as a field. There are ways to map it
explicitly to a Field class (see Link title).
However, after version 2.0 Typepy can also do it implicitly.
For example:
 class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def distance(self):
        return sqrt(self.x ** 2 + self.y ** 2)

class Foo(Structure):
    point_by_int: Map[Integer, Point]
    my_point: Field[Point]

foo = Foo(my_point = Point(0,0), point_by_int={1: Point(3, 4)})
assert foo.point_by_int[1].distance() == 5

# the following will raise a TypeError, since 3 is not a valid Point
foo.point_by_int[1] = 3
The example above illustrates that if you use the non-Typedpy class as an embedded type, such as List[Point],
you can use the class directly, but if it is the type of the field, you have to use the Field[Point] notation.

Defining a Field as Optional

Start by reading this: Required Fields and Optional Fields .

Not that typing.Optional is only support at the level of field definition. It is not supported in a nested definition. For example, to represent a field of list of integers-or-None, the following is invalid:

Default Values Of Optional Fields

For an optional field, if no value is provided, then the assessor returns None by default. You can
provide a default settings, using the “default” parameter (see below). If a default value is set
and no value is provided, then the assessor returns the default value.
Example:
class Person(Structure):
    name = String(pattern='[A-Za-z]+$', maxLength=16, default='Arthur')
    ssid = String(minLength=3, pattern='[A-Za-z]+$')
    num: Integer = 5

def test_defaults():
    person = Person(ssid="abc")
    assert person.foo is None
    assert person.name == 'Arthur'
    assert person.num == 5

A bad example:

class InvalidStructure(Structure):
      s = Array[Optional[String]]

Instead, you need to do the following:

class ValidStructure(Structure):
      s = Array[AnyOf[String, None]]

Inheritance and Mixins

Inheritance works the way you would expect:

# define a new mixin
class Even(Field):
    def __set__(self, instance, value):
        if value % 2 > 0:
            raise ValueError('Must be even')
        super().__set__(instance, value)

class EvenPositiveInt(Integer, Positive, Even): Pass

# Done! Now we have a new Field type that we can use

Using a Structure as a Field

Any Structure type can also be used as a field.

# Suppose we defined a new structure "Foo":
class Foo(Structure):
    st = String

# We can now use it as a Field:
class Example(Structure):
    a = Foo
    b = Array[Foo]
    c = AnyOf[Foo, Integer]

#This will raise a TypeError for a
Example(a = 1, b=[], c=2)

#This is valid
Example(a=Foo(st=""), b=[Foo(st="xyz")], c=2))

Inlining a Structure as a Field

See StructureReference

Immutability

To define an immutable Field, you use the mixin ImmutableField. Example:

class A(Structure):
    x = Number
    y = ImmutableString


a = A(x=0.5, y="abc")

# This will raise an ValueError exception, with the message  "y: Field is immutable"
a.y += "xyz"

The predefined immutable types even block updates of nested fields:

class A(Structure):
    m: ImmutableArray[Map]

instance = A(m=[{'a': 1}, {'b': 2}])

# This will throw a ValueError, with the message: m_0: Field is immutable
instance.m[0]['a'] = 5

Note that in the last example, trying to update a nested Map (i.e. a dictionary) inside an immutable Array was blocked.

It is also possible to define an immutable Structure. See Under the Structures section.

Immutable Field/Structure classes cannot be inherited, to avoid a developer accidentally making the subclass a mutable one .

Uniqueness (Deprecated)

Typedpy allows you to ensure that all instances of a certain Structure have unique values of a certain field (for example, a unique ID or a primary key). This is done either by decorating the Field class defintion with @unique, or by setting the optional “is_unique” parameter when initializing a field. Consistent with Typedpy behavior, the uniqueness constraint will be maintained for dynamic updates as well.

To illustrate:

@unique
class SSID(String): pass

class Person(Structure):
    ssid: SSID
    name: String

Person(ssid="1234", name="john")

Person(ssid="1234", name="john")  # OK, since it equal to the other instance with ssid "1234"

Person(ssid="1234", name="Jeff")  # raises a ValueError. Can't have a different person with the same ssid.

Person(ssid="1234", name="john").name = "Joe" # raise a similar ValueError

Note that uniqueness of a field is enforced per Structure class. Two structures of different types can have the same value of a unique field type.

Alternatively, we can define a field as unique using an optional parameter:

class Person(Structure):
    ssid: String(is_unique = True)
    name: String

It has the same effect as the decorator.

Beyond a threshold of 100,000 different values, uniqueness is not enforced anymore, to avoid the overhead.

Custom Serialization or Deserialization of a Field

class SerializableField(name=None, immutable=None, is_unique=None, default=None)[source]

An abstract class for a field that has custom deserialization. can override the method.

deserialize(self, value)

These methods are not being used for pickling.

If your field inherits from this class, Typedpy will look for custom serialization or deserialization functions in it. If found, it will use them to serialize or deserialize.

For more details, see Serialization/Deserialization of a Field

Extension and Utilities

create_typed_field(classname, cls, validate_func=None)[source]

Factory that generates a new class for a Field as a wrapper of any class.

Arguments:

classname(str):

A new name this class can be referenced by

cls(type):

The class we are wrapping

validate_func(function): optional

A validation function. It should raise an exception if the instance is invalid.

Example:

Given a class Foo, and a validation function for an instance of Foo, called validate_foo(foo):

class Foo(object):
    def __init__(self, x):
        self.x = x


ValidatedFooField = create_typed_field("FooField",
                                     Foo,
                                     validate_func=validate_foo)

Generates a new Field class that validates the content using validate_foo, and can be used just like any Field type.

class A(Structure):
    foo = ValidatedFooField
    bar = Integer

# assuming we have an instance of Foo called my_foo, we can create a valid instance of A:
A(bar=4, foo=my_foo)

Defining a Field Independently

Supposed you have a field definition you would like to reuse. It’s important that you do not do it using an assignment, i.e.:

# This is bad! don't do it!
TableName = String(minLength=5)

class Broken(Structure):
    table = TableName

# the above *may* work in certain scenario, but it is broken code! Avoid it!

The example above is wrong. Instead, define a function that returns the field, as in the following Example:

def Names(): return Array[String]
def TableName(): return String(minLength=5)

class Foo(Structure):
    i = Integer
    foo_names = Names()
    table = TableName()

class Bar(Structure):
    bar_names = Names()
    i = Integer
    table = TableName()
From version 0.51, if you use Python 3.7+, you can also use type hints to let Typedpy know that this is a Field factory.
In this case, Typedpy will automatically inspect it, so you don’t need to call the function explicitly in the class
definition.
For example:
def Names() -> Type[Field]: return Array[String]
def TableName()-> Field: return String(minLength=3)

class Foo(Structure):
    foo_names = Names   # note we don't need to call Names()
    table = TableName
From version 2.00, you can use any custom class directly as a field. Typedpy will automatically wrap it as a Typedpy Field.
The caveat is that it is cannot be pickled and serialization is no a best-effort basis, since Typedpy
does not know anything about the class.

For example:

class MyClass:
    ....

class Foo(Structure):
    myclass: Field[MyClass]
    mymap: Map[String, MyClass]

Predefined Types

class Field(name=None, immutable=None, is_unique=None, default=None)[source]

Base class for a field(i.e. property) in a structure. Should not be used directly by developers.

Arguments:
immutable: optional

Marks the field as immutable. Typically the developer does not need to use it, as there is a high level API for making a field immutable

is_unique: optional

Marks a field as unique within this its Structure. as there is a high level API for making a field immutable

class SSID(String): pass

class Person(Structure):
        ssid: SSID(is_unique=True)
        name: String

Person(ssid="1234", name="john")
# the next line will raise an exception "Instance copy of field ssid in Person"
Person(ssid="1234", name="jeff")

Alternatively, you can use the “@unique” decorator on the class definition of the Field. Refer to “Uniqueness” section for more detail.

default: optional

default value in case no value was assigned. Setting it makes the field implicitly optional. Default values are validated based on the field definition like any other value assignment.

class Anything(name=None, immutable=None, is_unique=None, default=None)[source]

A field that can contain anything (similar to “any” in Typescript). Example:

class Foo(Structure):
    i = Integer
    some_content = Anything

# now we can assign anything to some_content property:
Foo(i=5, some_content = "whatever")
Foo(i=5, some_content = [1,2,3])
Foo(i=5, some_content = Bar())
class Function(name=None, immutable=None, is_unique=None, default=None)[source]
A function or method. Note that this can’t be any callable (it can’t be a class,

for example), but a real function

class ExceptionField(name=None, immutable=None, is_unique=None, default=None)[source]

As Exception. This is serialized as the string representation of the exception. It does not support deserialization.

class NoneField(name=None, immutable=None, is_unique=None, default=None)[source]

A field that maps to a single allowable value: None. By default, fields cannot be assigned None (i.e. “Null Safety”). NoneField allows to do so. This is useful to define optional fields or optional values such as:

class Foo(Structure):
    optional_1: typing.Optional[Array]     # NoneField is used implicitly
    optional_2: AnyOf[Array, NoneField]
    optional_3: AnyOf[Array, None]         # the conversion from None to NoneField is implicit

    arr_maybe_int_1: Array[AnyOf[Integer, NoneField]]
    arr_maybe_int_2: Array[AnyOf[Integer, None]]    # the conversion from None to NoneField is implicit
class Generator(name=None, immutable=None, is_unique=None, default=None)[source]

A Python generator. Not serializable.

class StructureReference(**kwargs)[source]

A Field that is an embedded structure within other structure. Allows to create hierarchy. This is useful if you want to inline your Structure, as opposed to create an explicit class for it. All the arguments are passed as attributes of the structure. Example:

StructureReference(
    _additionalProperties = False,
    id = String,
    name = String
    age = AnyOf[PositiveInt, PositiveFloat]
)

Important: Since Typedpy dynamically creates an internal class for it, this field cannot be pickled!

class SubClass(*args, clazz: type, **kwargs)[source]

A Subclass of an given class

Arguments:
clazz(type):

The class that the field is subclass of

class Foo(Structure): pass
class Bar(Foo): pass

class Container(Structure):
    data: dict[SubClass(clazz=Foo), str]

container = Container(data={Bar: "bar"})

Numerical

typedpy defines the following basic field types:

class Number(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

Base class for numerical fields. Based on Json schema draft4. Accepts and int or float.

Arguments:
multipleOf(int): optional

The number must be a multiple of this number

minimum(int or float): optional

value cannot be lower than this number

maximum(int or float): optional

value cannot be higher than this number

exclusiveMaximum(bool): optional

marks the maximum threshold above as exclusive

class Integer(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An extension of Number for an integer. Accepts int

class Float(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An extension of Number for a float. Also excepts an int, which will be converted to a float.

class DecimalNumber(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An extension of Number for a Decimal. Accepts anything that can be converted to a Decimal. It converts the value to a Decimal.

class Positive(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An extension of Number. Requires the number to be positive

class PositiveFloat(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Float and Positive

class PositiveInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Integer and Positive

class Negative(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An extension of Number. Requires the number to be negative

class NegativeFloat(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Float and Negative

class NegativeInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Integer and Negative

class NonPositive(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An extension of Number. Requires the number to be negative or 0

class NonPositiveFloat(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Float and NonPositive

class NonPositiveInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Integer and NonPositive

class NonNegative(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An extension of Number. Requires the number to be positive or 0

class NonNegativeFloat(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Float and NonNegative

class NonNegativeInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An combination of Integer and NonNegative

class Boolean(name=None, immutable=None, is_unique=None, default=None)[source]

Value of type bool. True or False.

String, Enums etc.

class String(*args, minLength=None, maxLength=None, pattern=None, **kwargs)[source]

A string value. Accepts input of str

Arguments:
minLength(int): optional

minimal length

maxLength(int): optional

maximal lengthr

pattern(str): optional

string of a regular expression

class Enum(*args, values, serialization_by_value: bool = False, **kwargs)[source]

Enum field. value can be one of predefined values.

Arguments:
values(list or set or tuple, alternatively an enum Type):

allowed values. Can be of any type. Alternatively, can be an enum.Enum type. See example below. When defined with an enum.Enum, serialization converts to strings, while deserialization expects strings (unless using serialization_by_value). In this case, strings are converted to the original enum values.

Another option is assign a list of specific values from an enum.Enum class. In this case, it will work like asigning an Enum class, but allowing only specific values of that enum (see example below).

serialization_by_value(bool): optional

When set to True and the values is an enum.Enum class, then instead of serializing by the name of the enum, serialize by its value, and similarly, when deserializing, expect the enum value instead of the name. Default is False. This is especially useful when you are interfacing with another system and the values

are strings that you don’t control, like the example below.

Examples:

class Values(enum.Enum):
     ABC = 1
     DEF = 2
     GHI = 3

class Example(Structure):
   arr = Array[Enum[Values]]
   e = Enum['abc', 'x', 'def', 3]

example = Example(arr=[Values.ABC, 'DEF'],e=3)
assert example.arr = [Values.ABC, Values.DEF]

# deserialization example:
deserialized = Deserializer(target_class=Example).deserialize({'arr': ['GHI', 'DEF', 'ABC'], 'e': 3})
assert deserialized.arr == [Values.GHI, Values.DEF, Values.ABC]

An example of serialization_by_value:

class StreamCommand(enum.Enum):
    open = "open new stream"
    close = "close current stream"
    delete = "delete steam"

class Action(Structure):
    command: Enum(values=StreamCommand, serialization_by_value=True)
    ....


assert Deserializer(Action).deserialize({"command": "delete stream"}).command is StreamCommand.delete

An example of allowing only specific values of an Enum class, referencging StreamCommand in the previous example:

 class Action(Structure):
      command: Enum(values=[StreamCommand.open, StreamCommand.close], serialization_by_value=True)
      ....

# command works like in the previous example, but allows open/close values from StreamCommand, thus
# the following line results in an exception:
Deserializer(Action).deserialize({"command": "delete stream"})
class EnumString(*args, values, serialization_by_value: bool = False, **kwargs)[source]

Combination of Enum and String. This is useful if you want to further limit your allowable enum values, using String attributes, such as pattern, maxLength.

Example:

predefined_list = ['abc', 'x', 'def', 'yy']

EnumString(values=predefined_list, minLength=3)
class Sized(*args, maxlen, **kwargs)[source]

The length of the value is limited to be at most the maximum given. The value can be any iterable.

Arguments:

maxlen(int):

maximum length

class DateString(*args, date_format='%Y-%m-%d', **kwargs)[source]

A string field of the format ‘%Y-%m-%d’ that can be converted to a date

Arguments:
date_format(str): optional

an alternative date format

class TimeString(name=None, immutable=None, is_unique=None, default=None)[source]

A string field of the format ‘%H:%M:%S’ that can be converted to a time

class DateField(*args, date_format='%Y-%m-%d', **kwargs)[source]

A datetime.date field. Can accept either a date object, or a string that can be converted to a date, using the date_format in the constructor.

Arguments:
date_format(str): optional

The date format used to convert to/from a string. Default is ‘%Y-%m-%d’

Example:

class Foo(Structure):
    date = DateField

foo(date = date.today())
foo(date = "2020-01-31")

This is a SerializableField, thus can be serialized/deserialized.

class DateTime(*args, datetime_format='%m/%d/%y %H:%M:%S', **kwargs)[source]

A datetime.datetime field. Can accept either a datetime object, or a string that can be converted to a date, using the date_format in the constructor.

Arguments:
datetime_format(str): optional

The format used to convert to/from a string. Default is ‘%m/%d/%y %H:%M:%S’

Example:

class Foo(Structure):
    timestamp = DateTime

foo(timestamp = datetime.now())
foo(timestamp = "01/31/20 07:15:45")

This is a SerializableField, thus can be serialized/deserialized.

class IPV4(*args, minLength=None, maxLength=None, pattern=None, **kwargs)[source]

A string field of a valid IP version 4

class JSONString(*args, minLength=None, maxLength=None, pattern=None, **kwargs)[source]

A string of a valid JSON

class HostName(*args, minLength=None, maxLength=None, pattern=None, **kwargs)[source]

A string field of a valid host name

EmailAddress - A String field that has the pattern of an email address.

Collections

class Array(*args, items=None, uniqueItems=None, additionalItems=None, **kwargs)[source]

An Array field, similar to a list. Supports the properties in JSON schema draft 4. Expected input is of type list.

Arguments:
minItems(int): optional

minimal size

maxItems(int): optional

maximal size

unqieItems(bool): optional

are elements required to be unique?

additionalItems(bool): optional

Relevant in case items parameter is a list of Fields. Is it allowed to have additional elements beyond the ones defined in “items”?

items(a Field or Structure, or a list/tuple of Field or Structure): optional

Describes the fields of the elements. If a items if a Field, then it applies to all items. If a items is a list, then every element in the content is expected to be of the corresponding field in items. Examples:

names = Array[String]
names = Array[String(minLengh=3)]
names = Array(minItems=5, items=String)
my_record = Array(items=[String, Integer(minimum=5), String])
my_lists = Array[Array[Integer]]
my_structs = Array[StructureReference(a=Integer, b=Float)]
# Let's say we defined a Structure "Person"
people = Array[Person]

# Assume Foo is an arbitrary (non-Typedpy) class
foos = Array[Foo]
class Set(*args, items=None, **kwargs)[source]

A set collection. Accepts input of type set

Arguments:
minItems(int): optional

minimal size

maxItems(int): optional

maximal size

items(Field or Structure): optional

The type of the content, can be a predefined Structure, Field or an arbitrary class. In case of an arbitrary class, an implicit Field class will be created for it behind the scenes. Always prefer an Explicit Typedpy Structure or Field if you can.

Examples:

Set[String]
Set(items=Integer(maximum=10), maxItems = 10)

# let's assume we defined a Structure 'Person', then we can use it too:
Set[Person]
class Tuple(*args, items, uniqueItems=None, **kwargs)[source]
A tuple field, supports unique items option.

Expected input is of type tuple.

Arguments:

unqieItems(bool): optional

are elements required to be unique?

items(list/tuple of Field or Structure): optional

Describes the fields of the elements. Every element in the content is expected to be of the corresponding Field in items.

Examples:

# a is a tuple of exactly 2 strings that are different from each other.
a = Tuple(uniqueItems=True, items = [String, String])

# b is a tuple of 3: string, string and a number up to 10.
b = Tuple(items = [String, String, Number(maximum=10)])

# c is a tuple of 3: integer, string, float.
c = Tuple[Integer, String, Float]

# The following define a tuple of any number of Integers
d = Tuple[Integer]

# It can also contain other structures:
# Assume we have something like: class Foo(Structure): pass
# e is a tuple of any number of Integers or Foo instances
e = Tuple[AnyOf[Integer, Foo]]

# It can also have arbitrary class
class MyCustomClass: pass
Tuple[MyCustomClass]
class Map(*args, items=None, **kwargs)[source]

A map/dictionary collection. Accepts input of type dict

Arguments:
minItems(int): optional

minimal size

maxItems(int): optional

maximal size

items(tuple of 2 Field or Structure elements): optional

The first element is the Field for keys, the second is for values. Examples:

age_by_name = Map[String, PositiveInt]
# Let's assume we defined a Structure "Person"
person_by_id = Map[String, Person]
# even Structure reference is supported for keys!
id_by_person = Map[Person, String]
id_by_person = Map[Person, String]
class Deque(*args, items=None, uniqueItems=None, additionalItems=None, **kwargs)[source]

An collections.deque field. Supports the properties in JSON schema draft 4. Expected input is of type collections.deque.

Arguments:
minItems(int): optional

minimal size

maxItems(int): optional

maximal size

unqieItems(bool): optional

are elements required to be unique?

additionalItems(bool): optional

Relevant in case items parameter is a list of Fields. Is it allowed to have additional elements beyond the ones defined in “items”?

items(a Field or Structure, or a list/tuple of Field or Structure): optional

Describes the fields of the elements. If a items if a Field, then it applies to all items. If a items is a list, then every element in the content is expected to be of the corresponding field in items. Examples:

names = Deque[String]
names = Deque[String(minLengh=3)]
names = Deque(minItems=5, items=String)
my_record = Deque(items=[String, Integer(minimum=5), String])
my_lists = Deque[Array[Integer]]
my_structs = Deque[StructureReference(a=Integer, b=Float)]
# Let's say we defined a Structure "Person"
people = Deque[Person]

# Assume Foo is an arbitrary (non-Typedpy) class
foos = Deque[Foo]

All collections support reference to another Structure . For example, this code is valid and will work the way you’d expect:

class Foo(Structure):
      s = String

class Bar(Structure):
      a = Set[Foo]
      b = Map [Foo, Integer]

Re-use

class AllOf(fields)[source]

Content must adhere to all requirements in the fields arguments. Arguments:

fields( list of Field): optional the content should match all of the fields in the list

Example:

AllOf[Number(maximum=20, minimum=-10), Integer, Positive]
class AnyOf(fields)[source]

Content must adhere to one or more of the requirements in the fields arguments. Arguments:

fields( list of Field): optional the content should match at least one of the fields in the list

Example:

AnyOf[Number(maximum=20, minimum=-10), Integer, Positive, String]
class OneOf(fields)[source]

Content must adhere to one, and only one, of the requirements in the fields arguments. Arguments:

fields( list of Field): optional the content should match one, and only one, of the fields in the list

Example:

OneOf[Number(maximum=20, minimum=-10), Integer, Positive, String]
class NotField(fields)[source]

Content must not adhere to any of the requirements in the fields arguments. Arguments:

fields( list of Field): optional

the content must not match any of the fields in the lists

Examples:

NotField([Number(multiplesOf=5, maximum=20, minimum=-10), String])
NotField[Positive]

All the field types under this category support reference to another Structure . For example, this code is valid and will work the way you’d expect:

class Foo(Structure):
      s = String

class Bar(Structure):
      a = Any[Foo, Integer]

And versions > 2.0 do not require Foo to be a structure, so the following code would also work:

@dataclass(unsafe_hash=True)
class Foo:
      s: str
      i: int

class Bar(Structure):
      int_by_foo: Map[Foo, Integer]

Immutability

class ImmutableField(name=None, immutable=None, is_unique=None, default=None)[source]

A mixin that makes a field class immutable. For Example:

class MyFieldType(Field): .....

class MyImmutableFieldType(ImmutableField, MyFieldType): pass

# that's all you have to do to make MyImmutableFieldType immutable.

ImmutableField class (as the class MyImmutableFieldType in the example above) are not allowed to be extended. This is to ensure any instance of ImmutableField is indeed immutable.

class ImmutableSet(*args, items=None, **kwargs)[source]

An immutable Set. Internally implemented by a Python frozenset, so it does not have any mutation methods. This makes it more developer-friendly.

class ImmutableMap(*args, items=None, **kwargs)[source]

An immutable version of Map

class ImmutableArray(*args, items=None, uniqueItems=None, additionalItems=None, **kwargs)[source]

An immutable version of Array

class ImmutableInteger(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An immutable version of Integer

class ImmutableFloat(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An immutable version of Float

class ImmutableNumber(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]

An immutable version of Number

class ImmutableDeque(*args, items=None, uniqueItems=None, additionalItems=None, **kwargs)[source]

An immutable version of Deque

Other Types With Explicit Support

The following types can be used as fields types and will be automatically converted to Typedpy fields:

  • str, int, float, dict, list, set, tuple, bool, frozenset, deque. Versions > 2.0 also support PEP585-style types.

  • From the “typing” module: Union, Any, Optional, List, Dict, Set, FrozenSet, Deque