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:
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.
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.
With Typedpy we can define a Structure as immutable, which is much more powerful than dataclass “frozen” setting.
Typedpy offers flexible serialization/deserialization, as well as JSON Schema mapping.
Typedpy inheritance is cleaner than dataclasses.
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)
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
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¶
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¶
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 anyField
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()
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
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]¶
- class PositiveInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]¶
- 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]¶
- class NegativeInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]¶
- 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
andNonPositive
- class NonPositiveInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]¶
An combination of
Integer
andNonPositive
- 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
andNonNegative
- class NonNegativeInt(*args, multiplesOf=None, minimum=None, maximum=None, exclusiveMaximum=None, **kwargs)[source]¶
An combination of
Integer
andNonNegative
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
andString
. This is useful if you want to further limit your allowable enum values, usingString
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
orStructure
, or a list/tuple ofField
orStructure
): 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
orStructure
): 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 TypedpyStructure
orField
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:
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
orStructure
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
orStructure
, or a list/tuple ofField
orStructure
): 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 listExample:
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 listExample:
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 listExample:
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]
- fields( list of
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 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
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