dictstruct
I made this library because I wanted to use msgspec to decode Ethereum RPC responses but I still needed the resulting objects to be compatible with the standard dictionary API
You may find yourself in a similar position. You may find yourself using dictstruct to solve your problem. You may find yourself elated to focus on better things.
And you may ask yourself, “Well, how did I get here!?”
- class dictstruct.DictStruct[source]
Bases:
Struct
A base class that extends the
msgspec.Struct
class to provide dictionary-like access to struct fields.Allows iteration over the fields of a struct and provides a dictionary-like interface for retrieving values by field name.
Note
Attempting to access an attribute that is set to
UNSET
will raise anAttributeError
when accessed as an attribute, or aKeyError
when accessed using dictionary-style access. This behavior indicates that the attribute/key is not present on the DictStruct object.Example
>>> class MyStruct(DictStruct): ... field1: str ... field2: int ... field3: int = UNSET >>> s = MyStruct(field1="value", field2=42) >>> list(s.keys()) ['field1', 'field2'] >>> s['field1'] 'value' >>> s.field3 Traceback (most recent call last): ... AttributeError: "'MyStruct' object has no attribute 'field3'" >>> s['field3'] Traceback (most recent call last): ... KeyError: ('field3', MyStruct(field1='value'))
- __bool__()[source]
Unlike a dictionary, a Struct will always exist.
Example
>>> class MyStruct(DictStruct): ... pass >>> bool(MyStruct()) True
- Return type:
Literal[True]
- __contains__(key)[source]
Check if a key is in the struct.
- Parameters:
key (str) – The key to check.
- Returns:
True if the key is present and not
UNSET
, False otherwise.- Return type:
Example
>>> class MyStruct(DictStruct): ... field1: str >>> s = MyStruct(field1="value") >>> 'field1' in s True >>> 'field2' in s False
- __getattribute__(attr)[source]
Get the value of an attribute, raising AttributeError if the value is
UNSET
.- Parameters:
attr (str) – The name of the attribute to fetch.
- Raises:
AttributeError – If the attribute is not found or is considered unset (
UNSET
).- Return type:
Example
>>> class MyStruct(DictStruct): ... field1: str = UNSET >>> s = MyStruct() >>> s.field1 Traceback (most recent call last): ... AttributeError: "'MyStruct' object has no attribute 'field1'"
See also
__getitem__()
for dictionary-style access.
- __getitem__(attr)[source]
Lookup an attribute value via dictionary-style access.
- Parameters:
attr (str) – The name of the attribute to access.
- Raises:
KeyError – If the provided key is not a member of the struct.
- Return type:
Example
>>> class MyStruct(DictStruct): ... field1: str >>> s = MyStruct(field1="value") >>> s['field1'] 'value' >>> s['field2'] Traceback (most recent call last): ... KeyError: ('field2', MyStruct(field1='value'))
- __hash__()[source]
A frozen Struct is hashable but only if the fields are all hashable as well.
This modified hash function attempts to hash the fields directly and converts any list fields to tuples if a TypeError is raised.
Example
>>> class MyStruct(DictStruct, frozen=True): ... field1: str ... field2: list >>> s = MyStruct(field1="value", field2=[1, 2, 3]) >>> hash(s) 123456789 # Example output, actual value will vary
- __iter__()[source]
Iterate through the keys of the Struct.
Example
>>> class MyStruct(DictStruct): ... field1: str ... field2: int >>> s = MyStruct(field1="value", field2=42) >>> list(iter(s)) ['field1', 'field2']
- __len__()[source]
The number of keys in the Struct.
Example
>>> class MyStruct(DictStruct): ... field1: str ... field2: int >>> s = MyStruct(field1="value", field2=42) >>> len(s) 2
- Return type:
- get(key, default=None)[source]
Get the value associated with a key, or a default value if the key is not present.
- Parameters:
key (str) – The key to look up.
default (optional) – The value to return if the key is not present.
- Return type:
Example
>>> class MyStruct(DictStruct): ... field1: str >>> s = MyStruct(field1="value") >>> s.get('field1') 'value' >>> s.get('field2', 'default') 'default'
- items()[source]
Returns an iterator over the struct’s field name and value pairs.
Example
>>> class MyStruct(DictStruct): ... field1: str ... field2: int >>> s = MyStruct(field1="value", field2=42) >>> list(s.items()) [('field1', 'value'), ('field2', 42)]
- keys()[source]
Returns an iterator over the field names of the struct.
Example
>>> class MyStruct(DictStruct): ... field1: str ... field2: int >>> s = MyStruct(field1="value", field2=42) >>> list(s.keys()) ['field1', 'field2']
- values()[source]
Returns an iterator over the struct’s field values.
Example
>>> class MyStruct(DictStruct): ... field1: str ... field2: int >>> s = MyStruct(field1="value", field2=42) >>> list(s.values()) ['value', 42]
- __dict__
- __module__ = 'dictstruct._main'
- __slots__ = ('__dict__',)
- class dictstruct.LazyDictStruct[source]
Bases:
DictStruct
A subclass of
DictStruct
that supports Just-In-Time (JIT) decoding of field values.LazyDictStruct is designed for developers who need to efficiently handle large or complex data structures, particularly when working with serialized data formats like JSON. By storing field values in a raw, undecoded format, this class allows for deferred decoding, meaning that data is only decoded when accessed. This approach can lead to significant performance improvements and reduced memory usage, especially in scenarios where not all fields are always needed.
Key Features: - JIT Decoding: Decode data only when accessed, saving processing time and memory. - Immutable Structure: As a frozen dataclass, instances are immutable, ensuring data integrity after creation. - Compatibility: Inherits from
DictStruct
, making it compatible with the standard dictionary API, allowing for easy integration with existing codebases that rely on dictionary-like data structures.Use Cases: - Handling large JSON responses from APIs where only a subset of the data is needed at any given time. - Optimizing applications that process data lazily, improving startup times and reducing resource consumption.
Example
>>> import msgspec >>> from functools import cached_property >>> class MyStruct(LazyDictStruct): ... _myField: msgspec.Raw = msgspec.field(name='myField') ... @cached_property ... def myField(self) -> YourGiantJsonObject: ... '''Decode the raw JSON data into a python object when accessed.''' ... return msgspec.json.decode(self._myField, type=YourGiantJsonObject) ... >>> # Encode data into a raw JSON format >>> raw_data = msgspec.json.encode({"myField": "some value"}) >>> # Create an instance of MyStruct with the raw data >>> my_struct = MyStruct(_myField=raw_data) >>> # Access the decoded field value >>> print(my_struct.myField) "some value"
See also
DictStruct
for the base class implementation.- classmethod __init_subclass__(*args, **kwargs)[source]
Initialize a subclass of
LazyDictStruct
.This method resolves any lazy field names (prefixed with an underscore) and overwrites cls.__struct_fields__ so it contains the names of the materialized properties defined on your subclass.
- Parameters:
*args – Positional arguments.
**kwargs – Keyword arguments.
See also
DictStruct
for the base class implementation.
- __annotations__ = {}
- __module__ = 'dictstruct._lazy'
- __slots__ = ()