Databind
Databind is a Python library, currently at version 4.5.4, designed for de-serializing and serializing Python dataclasses. Inspired by `jackson-databind`, it provides a flexible framework that understands most native Python types and dataclasses, primarily for configuration loading rather than high-performance use cases. It maintains a regular release cadence with recent updates fixing various serialization issues.
Common errors
-
databind.core.converter.NoMatchingConverter: no deserializer for `TypeHint(~T_Page)` and payload of type `dict`
cause A generic type (e.g., `list` or a custom generic dataclass) was used in a type hint without specifying its type parameters (e.g., `list[str]`), causing databind to not know how to deserialize the inner type.fixExplicitly define the type parameters for generic types. For example, change `list` to `list[YourType]` or `MyClass` to `MySpecificClass(MyClass['MySpecificClass'])`. -
RecursionError: maximum recursion depth exceeded
cause In versions prior to 4.5.4, complex inheritance chains combined with `Union` types could lead to infinite recursion during converter lookup due to an issue with MRO and Union settings.fixUpgrade to `databind` version 4.5.4 or newer. If upgrading is not immediately possible, consider simplifying `Union` definitions or inheritance structures. -
databind.core.converter.ConversionError: Unknown field 'extra_key'
cause The input payload contains keys that are not defined as fields in the target dataclass, and the `ExtraKeys` setting is not enabled to allow or record these additional fields.fixUse the `databind.core.ExtraKeys` setting. Apply `@ExtraKeys()` to the dataclass, use `Annotated[FieldType, ExtraKeys()]` for a specific field, or pass `settings=[ExtraKeys()]` to the `load()` function.
Warnings
- breaking The `databind.core` and `databind.json` packages were merged directly into the top-level `databind` package in version 4.5.0. Imports should be updated from `databind.core.foo` or `databind.json.bar` to `databind.foo` or `databind.bar` respectively. This version also dropped support for Python 3.6 and 3.7.
- gotcha Databind does not assume `Any` for missing type parameters in generics. If a generic type (e.g., `list`) is used without a specific type hint (e.g., `list[str]`), a `NoMatchingConverter` error will be raised during deserialization.
- gotcha Beware of inherited Union settings via Method Resolution Order (MRO), which historically led to `RecursionError` during serialization/deserialization. This was a known issue with complex inheritance hierarchies involving `Union` types.
- gotcha Fields from generic dataclasses with unspecified `TypeVar`s might not be serialized correctly. For instance, a generic dataclass `MyClass(Generic[T])` where `T` is not bound in a subclass can lead to `no deserializer for TypeHint(~T)`.
Install
-
pip install databind
Imports
- dump
from databind.core import dump
from databind.json import dump
- load
from databind.core import load
from databind.json import load
Quickstart
from dataclasses import dataclass
from databind.json import dump, load
@dataclass
class Server:
host: str
port: int
@dataclass
class Config:
server: Server
dict_payload = {"server": {"host": "localhost", "port": 8080}}
# Deserialize
loaded_config = load(dict_payload, Config)
print(f"Loaded Config: {loaded_config}")
assert loaded_config == Config(server=Server(host="localhost", port=8080))
# Serialize
dumped_payload = dump(loaded_config, Config)
print(f"Dumped Payload: {dumped_payload}")
assert dumped_payload == dict_payload