Using type annotations
Added in version 0.8.0.
Atom objects support both type hints and static type checking in addition to runtime validation.
Atom understands standard Python type hints, and uses them to infer the appropriate Atom members. Type hints can also be used to specify default values. Note that one can freely mix standard atom members and type annotations.
Note
Str-like annotations are not supported.
The following example creates a class that performs run-time type checking on all instance attributes, sets appropriate default values, and supports static type checking like any other atom object.
class MyAtom(Atom):
s: str = "Hello"
lst: list[int] = [1, 2, 3]
num: Optional[float]
n = Int()
The default attribute values for each instance are set to appropriate values.
my_atom = MyAtom()
assert my_atom.n == 0
typing.Optional
attributes have a default value of None
if no default
is specified.
assert my_atom.num is None
Mutable default values for list
and dict
are OK as the default value will
be copied for each new instance.
assert my_atom.lst == [1, 2, 3]
The following statements will fail static type checking and cause Atom to raise
a runtime TypeError
exception.
my_atom.n = "Not an integer"
my_atom.s = 5
Note
The above class definition is basically translated by atom into:
class MyAtom(Atom):
s = Str("Hello")
lst = List(Int(), default=[1, 2, 3])
num = Instance(float)
n = Int()
One can note that when inferring members from annotations, Instance
will
always be preferred over Typed
since the object to check may define a
custom instance check.
Note
By default, atom will generate runtime checks for the content of list, dict
and set but it will not check the content of inner containers. For example
for the annotation list[list[int]]
, atom will check that the provided
list contains list but it will not check that those list contains int.
The depth at which containers are validated is controlled by the metaclass keyword argument type_containers which default to 1. To fully omit validating the content of containers one can write:
class MyAtom(Atom, type_containers=0):
lst: list[int] = [1, 2, 3]
Which will be equivalent at runtime to, but allow type checker to validate the content of the list:
class MyAtom(Atom):
s = Str("Hello")
lst = List(default=[1, 2, 3])