test_dataclass.py
Overview
The [test_dataclass.py](/projects/287/67751) file provides a comprehensive suite of data class definitions and their corresponding unit tests focused on JSON serialization using the `orjson` library. The primary goal of this file is to verify the correct serialization behavior of various Python `dataclasses`, including features like default values, inheritance, slots, recursive and circular references, and integration with abstract base classes.
This file serves both as a test harness to ensure robust serialization of complex data classes and as a demonstration of best practices and edge cases when working with Python data classes and JSON serialization.
Classes and Functions
Enumerations
AnEnum (Enum)
A simple enumeration with two members:
Member | Value |
|---|---|
ONE | 1 |
TWO | 2 |
Data Classes
EmptyDataclass
A minimal dataclass with no fields.
Purpose: Test serialization of empty dataclasses.
Serialization output:
{}
EmptyDataclassSlots
Similar to
EmptyDataclassbut uses__slots__ = ()to prevent dynamic attribute creation.Purpose: Test serialization of empty dataclasses with slots.
Serialization output:
{}
Dataclass1
@dataclass
class Dataclass1:
name: str
number: int
sub: Optional["Dataclass1"]
Represents a recursive data structure where
subcan hold anotherDataclass1orNone.Used to test recursive serialization and circular references.
**Fields:**
Field | Type | Description |
|---|---|---|
name | `str` | Name identifier |
number | `int` | Numeric value |
sub | `Optional[Dataclass1]` | Optional nested instance or None |
Dataclass2
@dataclass
class Dataclass2:
name: Optional[str] = field(default="?")
Single-field dataclass with a default value
"?".Tests default values in serialization.
Dataclass3
@dataclass
class Dataclass3:
a: str
b: int
c: dict
d: bool
e: float
f: list
g: tuple
Dataclass with varied field types to test serialization of common Python built-in types.
Dataclass4
@dataclass
class Dataclass4:
a: str = field()
b: int = field(metadata={"unrelated": False})
c: float = 1.1
Shows use of
field()with metadata and default values.Metadata is not used in serialization but demonstrates field options.
Datasubclass
@dataclass
class Datasubclass(Dataclass1):
additional: bool
Inherits from
Dataclass1and adds anadditionalboolean field.Tests subclass serialization including inherited fields.
Slotsdataclass
@dataclass
class Slotsdataclass:
__slots__ = ("_c", "a", "b", "d")
a: str
b: int
_c: str
d: InitVar[str]
cls_var: ClassVar[str] = "cls"
Dataclass using
__slots__to restrict attributes.Contains an
InitVarand aClassVarwhich should not be serialized.Tests that serialization excludes non-instance fields like
_c,d, and class variables.
Defaultdataclass
@dataclass
class Defaultdataclass:
a: uuid.UUID
b: AnEnum
Contains fields of types requiring custom serialization logic (
uuid.UUIDandEnum).Used with a
defaultserialization function to convert complex types to JSON-compatible formats.
UnsortedDataclass
@dataclass
class UnsortedDataclass:
c: int
b: int
a: int
d: Optional[dict]
Fields deliberately declared out of alphabetic order.
Tests that
orjsondoes not reorder dataclass fields even whenOPT_SORT_KEYSis used.
InitDataclass
@dataclass
class InitDataclass:
a: InitVar[str]
b: InitVar[str]
cls_var: ClassVar[str] = "cls"
ab: str = ""
def __post_init__(self, a: str, b: str):
self._other = 1
self.ab = f"{a} {b}"
Uses
InitVarto accept initialization-only variables.Defines a
__post_init__method to combineaandbintoab.Contains a class variable and a private attribute (
_other) excluded from serialization.Tests that only instance fields (not
InitVarorClassVar) are serialized.
Abstract Base Class and Concrete Implementation
AbstractBase
class AbstractBase(abc.ABC):
@abc.abstractmethod
def key(self):
raise NotImplementedError
Abstract base class with an abstract method
key().Serves as a base for dataclasses that must implement
key().
ConcreteAbc
@dataclass(frozen=True)
class ConcreteAbc(AbstractBase):
__slots__ = ("attr",)
attr: float
def key(self):
return "dkjf"
Concrete frozen dataclass subclassing
AbstractBase.Implements
key()method.Uses
__slots__to optimize instance attribute storage.Tests serialization of dataclasses implementing abstract base classes.
Test Classes and Methods
TestDataclass
Contains multiple test methods validating serialization of the above dataclasses with `orjson.dumps`. Key tests include:
test_dataclass- Basic serialization ofDataclass1.test_dataclass_recursive- Serialization of nested recursive dataclasses.test_dataclass_circular- Detects circular references and expects a serialization error.test_dataclass_empty&test_dataclass_empty_slots- Serialization of empty dataclasses.test_dataclass_default_arg- Serialization with default field values.test_dataclass_types- Serialization of multiple field types.test_dataclass_metadata- Serialization ignoring field metadata.test_dataclass_classvar- Ensures class variables are not serialized.test_dataclass_subclass- Serialization including subclass fields.test_dataclass_slots- Serialization excluding__slots__non-instance attributes.test_dataclass_default- Uses adefaultfunction to serialize complex types (UUID,Enum).test_dataclass_sortandtest_dataclass_sort_sub- Sorting behavior withOPT_SORT_KEYS.test_dataclass_under- Serialization excluding underscored,InitVar, andClassVarfields.test_dataclass_option- Support for deprecated serialization option.
TestDataclassPassthrough
Tests behavior when the `OPT_PASSTHROUGH_DATACLASS` option is used:
test_dataclass_passthrough_raise- Without adefaulthandler, serialization raises.test_dataclass_passthrough_default- With adefaulthandler, dataclasses serialize correctly via fallback.
TestAbstractDataclass
test_dataclass_abc- Verifies serialization ofConcreteAbcimplementing abstract base class.
Important Implementation Details and Algorithms
The tests rely heavily on
orjson.dumpsfor fast JSON serialization of dataclasses.Use of
field(),InitVar,ClassVar, and__slots__demonstrates selective field inclusion/exclusion during serialization.Circular references are detected by
orjsonand raiseJSONEncodeErrorto prevent infinite loops.Recursive dataclasses are serialized by walking nested objects recursively.
Default serializers are provided to convert complex field types (e.g.,
uuid.UUIDandEnum) to JSON-compatible strings or values.The use of
pytestfor structured assertions and exception handling in tests.The test classes are designed to cover edge cases and ensure serialization fidelity across Python dataclass features.
Interaction with Other System Components
orjson: The file heavily tests and depends onorjsonfor JSON serialization.orjsonis a fast, C-backed JSON library with support for dataclasses.pytest: Used for unit testing framework to define and run tests.Python Standard Library: Uses
dataclasses,enum,uuid, andabcmodules to define data models and enforce abstraction.The file acts as a test module, likely integrated into a CI pipeline or test suite, validating serialization behavior for dataclasses used elsewhere in the application.
Usage Examples
Example: Serializing a recursive dataclass instance
obj = Dataclass1("root", 42, Dataclass1("child", 7, None))
json_bytes = orjson.dumps(obj)
print(json_bytes)
# Output: b'{"name":"root","number":42,"sub":{"name":"child","number":7,"sub":null}}'
Example: Custom serialization for UUID and Enum fields
def default(obj):
if isinstance(obj, uuid.UUID):
return str(obj)
elif isinstance(obj, Enum):
return obj.value
raise TypeError
obj = Defaultdataclass(uuid.uuid4(), AnEnum.ONE)
json_bytes = orjson.dumps(obj, default=default)
print(json_bytes)
Mermaid Class Diagram
classDiagram
class AnEnum {
<<Enum>>
+ONE = 1
+TWO = 2
}
class EmptyDataclass {
}
class EmptyDataclassSlots {
__slots__ = ()
}
class Dataclass1 {
+name: str
+number: int
+sub: Optional[Dataclass1]
}
class Dataclass2 {
+name: Optional[str] = "?"
}
class Dataclass3 {
+a: str
+b: int
+c: dict
+d: bool
+e: float
+f: list
+g: tuple
}
class Dataclass4 {
+a: str
+b: int
+c: float = 1.1
}
class Datasubclass {
+additional: bool
}
Dataclass1 <|-- Datasubclass
class Slotsdataclass {
__slots__: tuple = ("_c", "a", "b", "d")
+a: str
+b: int
-_c: str
+d: InitVar[str]
cls_var: ClassVar[str] = "cls"
}
class Defaultdataclass {
+a: uuid.UUID
+b: AnEnum
}
class UnsortedDataclass {
+c: int
+b: int
+a: int
+d: Optional[dict]
}
class InitDataclass {
+a: InitVar[str]
+b: InitVar[str]
+ab: str
cls_var: ClassVar[str] = "cls"
+__post_init__(a: str, b: str)
}
class AbstractBase {
<<abstract>>
+key()
}
class ConcreteAbc {
__slots__: tuple = ("attr",)
+attr: float
+key()
}
AbstractBase <|-- ConcreteAbc
Summary
The [test_dataclass.py](/projects/287/67751) file is a focused test module to ensure that Python dataclasses, under various configurations and complexities, are serialized correctly with `orjson`. It covers:
Basic and complex dataclass fields.
Recursive and circular references.
Use of
__slots__,InitVar,ClassVar.Subclassing and abstract base class integration.
Custom serialization via default handlers.
Serialization behavior with
orjsonoptions.
This file is critical for validating the robustness and correctness of JSON serialization for data models used throughout the application.