Skip to main content

TypeRegistry

Types the codecs can store without pickle: per-type encode and decode functions, or a dataclass’s

Usage

Source

TypeRegistry()

fields.

A registered value is stored as a tagged map, {"$t:<name>": body}, in both serializers. Reads look the name up in the registry of the reading process: an unregistered name is a ForeignValueError, and the row is left in place. Nothing is ever imported by name, which is what keeps this safe where pickle isn’t.

diskcache_oxide.registry is the process-wide instance, used by every cache; register_type() and its siblings act on it. A Cache(types=TypeRegistry()) consults its own registry first, then the global one.

Examples

from bson import ObjectId
import diskcache_oxide

diskcache_oxide.register_type(ObjectId, name='bson.ObjectId', encode=str, decode=ObjectId)
diskcache_oxide.register_type(Episode, name='tp.Episode')   # a dataclass: no functions needed

cache.set('session', {'id': ObjectId(), 'episode': Episode(491, 'Rust and Python')})
cache.get('session')['id']   # an ObjectId again

Methods

Name Description
register() Register cls under name.
registered() The registrations, as {name: cls}.
unregister() Remove cls’s registration. Returns whether there was one. Rows already written with it become

register()

Register cls under name.

Usage

Source

register(cls, *, name, encode=None, decode=None)

With encode and decode, encode(instance) must return a value the codec can already store (registered types included, nested) and decode(value) must give the instance back. With neither, cls must be a dataclass: its init=True fields are stored and read back with getattr, and it is rebuilt with cls(**fields), so defaults and __post_init__ run. A field removed or made required between the write and the read makes that row a CorruptValueError.

Lookup is by exact type: a subclass of a registered class is not registered. Last registration wins, by class and by name, so a reloaded module can register its new class object again.

Parameters
cls: type[T]

The class. Not one of the codec’s own exact types (str, int, dict, datetime, …), whose wire form is fixed; their subclasses are fine.

name: str

The tag written into every row. Yours, so a class rename never orphans stored rows.

encode: Callable[[T], object] | None = None

Instance to a storable value.

decode: Callable[[Any], T] | None = None
That value back to an instance.
Raises
ValueError

An empty name, or one of the codec’s own types.

TypeError
cls isn’t a class; only one of encode/decode was given; neither was given and cls isn’t a dataclass, or is one with an InitVar field (the constructor needs it but no instance holds it: pass explicit functions).

registered()

The registrations, as {name: cls}.

Usage

Source

registered()

unregister()

Remove cls’s registration. Returns whether there was one. Rows already written with it become

Usage

Source

unregister(cls)

ForeignValueError on read until it is registered again.