test_default.py
Overview
The [test_default.py](/projects/287/68131) file contains a comprehensive set of unit tests designed to validate the behavior and robustness of the `orjson.dumps()` function when used with various `default` serialization handlers. The `default` parameter in `orjson.dumps()` allows users to provide a fallback serialization function or callable that converts unsupported Python objects into JSON-serializable types.
This test suite primarily focuses on:
Ensuring correct invocation and error handling of
defaultfunctions or callables.Verifying recursion limits and recursion reset during nested serialization.
Testing serialization of custom Python objects, including user-defined classes, sets, and numpy arrays (conditional).
Confirming no memory leaks via reference counting after serialization.
Handling edge cases, such as default functions returning
None, raising exceptions, or returning invalid JSON types.Testing
orjsonoptions such asOPT_PASSTHROUGH_SUBCLASSandOPT_SERIALIZE_NUMPYin combination with thedefaultparameter.
The tests use the `pytest` framework and the `orjson` high-performance JSON library.
Classes and Functions
Classes
Custom
**Purpose:** A simple user-defined class used to test serialization of arbitrary objects. Each instance has a unique `name` attribute initialized as a random UUID hex string.
**Attributes:**
name(str): A unique identifier generated at initialization.
**Methods:**
__init__(self): Initializesnamewith a UUID hex string.__str__(self) -> str: Returns a string representation of the form"Custom(<name>)".
**Usage Example:**
obj = Custom()
print(str(obj)) # e.g. "Custom(f3a1b2c4d5e6f7g8h9i0)"
Recursive
**Purpose:** A class designed to test recursive serialization behavior and recursion limits in `orjson.dumps()`.
**Attributes:**
cur(int): A counter used to track recursion depth.
**Methods:**
__init__(self, cur: int): Initializes the recursion counter.
**Usage Example:**
rec = Recursive(3)
Functions
default_recursive(obj: Recursive)
**Purpose:** A custom default serializer function for `Recursive` objects that decrements the `cur` attribute until zero, to test recursion behavior.
**Parameters:**
obj(Recursive): The object to serialize.
**Returns:**
Recursiveifcur > 0after decrementing (to continue recursion).Integer
0whencurreaches zero (to end recursion).
**Example:**
rec = Recursive(2)
default_recursive(rec) # modifies cur and returns either Recursive or 0
default_raises(obj)
**Purpose:** A default serializer function that always raises `TypeError`. Used to test error handling in `orjson.dumps()`.
**Parameters:**
obj: Any object.
**Raises:**
TypeError
Class TestType
A test suite class containing multiple `pytest` test methods, each validating a specific aspect of the `default` parameter functionality in `orjson.dumps()`.
Selected Test Methods with Details
test_default_not_callable(self)
**Description:** Tests that passing a non-callable object as the `default` parameter raises `orjson.JSONEncodeError`.
**Behavior:**
Calls
orjson.dumps()withdefault=NotImplementedError(non-callable).Expects an
orjson.JSONEncodeErrorwith message"default serializer exceeds recursion limit".
test_default_func(self)
**Description:** Tests using a user-defined function as the `default` serializer that returns a string representation of the object.
**Behavior:**
Defines
default(obj)returningstr(obj).Serializes a
Custominstance with thisdefault.Verifies the output JSON string matches the string representation of the object.
test_default_func_none(self)
**Description:** Tests a `default` function that returns `None`, which should serialize to JSON `null`.
test_default_func_exc(self)
**Description:** Tests that if the `default` function raises an exception, it is converted to `orjson.JSONEncodeError`.
test_default_vectorcall_str(self)
**Description:** Tests serialization of a subclass of `str` using `default=str` with `OPT_PASSTHROUGH_SUBCLASS`.
test_default_func_nested_str(self), test_default_func_list(self), test_default_func_nested_list(self)
**Description:** Test nested serialization scenarios where the `default` function returns strings or lists to ensure correct recursive serialization.
test_default_callable_ok(self)
**Description:** Tests using a callable class instance as the `default` serializer with caching.
test_default_recursion(self)
**Description:** Tests that recursion limit is respected during serialization using `default_recursive`.
test_reference_cleanup_default_custom_pass(self), test_reference_cleanup_default_custom_error(self)
**Description:** Tests that object references are cleaned up correctly after serialization to avoid memory leaks, verified via Python's reference count.
test_default_numpy(self)
**Description:** Tests serialization of numpy arrays using `default` to convert to list, conditional on numpy being installed.
test_default_set(self)
**Description:** Tests serialization of Python `set` objects using a `default` function converting sets to lists.
Important Implementation Details and Algorithms
Recursion Handling:
The tests use a customRecursiveclass and adefault_recursivefunction to simulate and test the recursion limit inorjson.dumps(). When the recursion counter reaches zero, recursion stops and the base value is serialized.Exception Wrapping:
orjson.dumps()wraps exceptions raised by thedefaultfunction intoorjson.JSONEncodeError. Tests verify this behavior by raising exceptions purposely.Reference Count Checks:
Several tests verify no memory leaks occur during serialization by comparing Python reference counts of objects before and after serialization.Use of
orjsonOptions:
Tests include interactions withorjsonoptions likeOPT_PASSTHROUGH_SUBCLASSandOPT_SERIALIZE_NUMPYto ensure compatibility withdefaultserializers.Handling of Special Return Types:
Thedefaultfunction can returnNone(serialized asnull), strings, lists, or other JSON-serializable types. Returning invalid types or bytes causes serialization errors.
Interaction with Other Parts of the System
orjsonLibrary:
The file extensively tests theorjson.dumps()function from theorjsonlibrary, particularly focusing on thedefaultparameter's behavior during JSON serialization.pytestFramework:
Usespytestfor structuring tests and asserting expected outcomes.Custom Utility Module (
.util.numpy):
The testtest_default_numpyconditionally tests numpy array serialization if numpy is available, imported via a local utility module.Python Standard Library:
Uses standard modules such asuuidfor unique identifiers,datetimefor date-time objects, andsysfor reference count inspection.
Usage Example
Here is a simplified example demonstrating how the `default` parameter can be used with `orjson.dumps()` based on patterns from the tests:
import orjson
class Custom:
def __str__(self):
return "CustomObject"
def default_serializer(obj):
# Convert unsupported types to string
return str(obj)
obj = Custom()
json_bytes = orjson.dumps(obj, default=default_serializer)
print(json_bytes) # Outputs: b'"CustomObject"'
Mermaid Class Diagram
classDiagram
class Custom {
+name: str
+__init__()
+__str__() str
}
class Recursive {
+cur: int
+__init__(cur: int)
}
class TestType {
+test_default_not_callable()
+test_default_func()
+test_default_func_none()
+test_default_func_empty()
+test_default_func_exc()
+test_default_exception_type()
+test_default_vectorcall_str()
+test_default_vectorcall_list()
+test_default_func_nested_str()
+test_default_func_list()
+test_default_func_nested_list()
+test_default_func_bytes()
+test_default_func_invalid_str()
+test_default_lambda_ok()
+test_default_callable_ok()
+test_default_recursion()
+test_default_recursion_reset()
+test_default_recursion_infinite()
+test_reference_cleanup_default_custom_pass()
+test_reference_cleanup_default_custom_error()
+test_reference_cleanup_default_subclass()
+test_reference_cleanup_default_subclass_lambda()
+test_default_numpy()
+test_default_set()
}
Custom <.. TestType : uses
Recursive <.. TestType : uses
Summary
The [test_default.py](/projects/287/68131) file is a specialized test suite validating the `default` serialization mechanism in the `orjson` JSON library. It verifies correct serialization outputs, error handling, recursion management, and resource cleanup for custom and built-in Python types. The tests ensure that `orjson.dumps()` behaves predictably and robustly when users provide custom default serialization logic, which is critical for extending JSON serialization to complex or non-standard Python objects.