Type Checking
pyserde offers runtime type checking since v0.9. It was completely reworked at v0.14 using beartype and it became more sophisticated and reliable. It is highly recommended to enable type checking always as it helps writing type-safe and robust programs.
strict
Strict type checking is to check every field value against the declared type during (de)serialization and object construction. This is the default type check mode since v0.14. What will happen with this mode is if you declare a class with @serde
decorator without any class attributes, @serde(type_check=strict)
is assumed and strict type checking is enabled.
@serde
class Foo:
s: str
If you call Foo
with wrong type of object,
foo = Foo(10)
you get an error
beartype.roar.BeartypeCallHintParamViolation: Method __main__.Foo.__init__() parameter s=10 violates type hint <class 'str'>, as int 10 not instance of str.
NOTE: beartype exception instead of SerdeError is raised from constructor because beartype does not provide post validation hook as of Feb. 2024.
similarly, if you call (de)serialize APIs with wrong type of object,
print(to_json(foo))
again you get an error
serde.compat.SerdeError: Method __main__.Foo.__init__() parameter s=10 violates type hint <class 'str'>, as int 10 not instance of str.
NOTE: There are several caveats regarding type checks by beartype.
- beartype can not validate on mutated properties
The following code mutates the property "s" at the bottom. beartype can not detect this case.
@serde class Foo s: str f = Foo("foo") f.s = 100
- beartype can not validate every one of elements in containers. This is not a bug. This is desgin principle of beartype. See [Does beartype actually do anything?](https://beartype.readthedocs.io/en/latest/faq/#faq-o1].
coerce
Type coercing automatically converts a value into the declared type during (de)serialization. If the value is incompatible e.g. value is "foo" and type is int, pyserde raises an SerdeError
.
@serde(type_check=Coerce)
class Foo
s: str
foo = Foo(10)
# pyserde automatically coerce the int value 10 into "10".
# {"s": "10"} will be printed.
print(to_json(foo))
disabled
This is the default behavior until pyserde v0.8.3 and v0.9.x. No type coercion or checks are run. Even if a user puts a wrong value, pyserde doesn't complain anything.
@serde
class Foo
s: str
foo = Foo(10)
# pyserde doesn't complain anything. {"s": 10} will be printed.
print(to_json(foo))