test_enum.py
Overview
`test_enum.py` is a test module designed to validate the serialization behavior of various `enum` types when encoded using the `orjson` JSON library in Python. The file explores different types of Python enumerations (`enum.Enum` and its subclasses) including string-based, integer-based, floating-point, flags, and custom classes, ensuring that `orjson` correctly serializes these enums to JSON. It also tests custom serialization via a default function and verifies certain type restrictions and serialization options.
This file primarily serves as a **unit test suite** to guarantee compatibility and expected behavior for enum serialization in the context of `orjson`, a performant JSON library.
Modules and Libraries
datetime: Used for datetime objects in enum values.enum: Provides the base classes for creating enumerations.pytest: Testing framework used to define and run test cases.orjson: A fast JSON serialization library used to dump enum values to JSON bytes.
Classes and Functions
Enum Classes
The file defines multiple enum classes to test different enum types:
StrEnum(str, enum.Enum)
An enum subclass where members are string values.
Example member:
AAA = "aaa"
IntEnum(int, enum.Enum)
An enum subclass where members are integer values.
Example member:
ONE = 1
IntEnumEnum(enum.IntEnum)
Another variant of integer enum using
enum.IntEnum.Example member:
ONE = 1
IntFlagEnum(enum.IntFlag)
Enum for bitwise flags with integer values.
Example member:
ONE = 1
FlagEnum(enum.Flag)
Another flag enum class, supporting bitwise operations.
Example member:
ONE = 1
AutoEnum(enum.auto)
Incorrect usage shown in code (see Implementation Details).
Example member:
A = "a"
FloatEnum(float, enum.Enum)
Enum subclass where members are floating-point values.
Example member:
ONE = 1.1
UnspecifiedEnum(enum.Enum)
Mixed-type enum class containing:
String member:
A = "a"Integer member:
B = 1Float member:
C = FloatEnum.ONEDictionary member:
D = {"d": IntEnum.ONE}Custom object member:
E = Custom("c")Datetime member:
F = datetime.datetime(1970, 1, 1)
Custom Classes
Custom
A simple class holding a value to test serialization of custom objects inside enums.
Attributes:
val(any): Stored value passed during initialization.
Methods:
__init__(self, val): Constructor storingval.
Functions
default(obj)
Custom default serialization function for
orjson.dumps.Parameters:
obj(any): Object to serialize.
Returns:
The
.valattribute ifobjis an instance ofCustom.
Raises:
TypeErrorifobjis not aCustominstance.
Usage:
Passed as the
defaultargument toorjson.dumpsto handle serializing objects not natively supported byorjson.
Test Class: TestEnum
Contains multiple test methods validating serialization and behavior of enums.
Each test method uses `pytest` for assertions and exception handling.
Methods
test_cannot_subclass(self)Verifies that attempting to subclass an enum subclass (
StrEnum) raises aTypeError.This test confirms the immutability of enum subclasses, as Python enums use a metaclass that prevents subclassing.
test_arbitrary_enum(self)Tests serialization of
UnspecifiedEnummembers with different types.Checks output for string, integer, float, and dictionary values.
Example:
orjson.dumps(UnspecifiedEnum.A) == b'"a"' orjson.dumps(UnspecifiedEnum.D) == b'{"d":1}'
test_custom_enum(self)Tests serialization of an enum member wrapping a custom class (
Custom) using thedefaultfunction.Ensures the custom object's internal value serializes correctly.
test_enum_options(self)Tests serialization of a datetime enum member using
orjsonoptionOPT_NAIVE_UTCfor UTC normalization.Checks correct ISO 8601 output with UTC offset.
test_int_enum(self),test_intenum_enum(self),test_intflag_enum(self),test_flag_enum(self),test_auto_enum(self),test_float_enum(self),test_str_enum(self)Individual tests for serialization of the respective enum classes.
Verify that enum values serialize to their underlying primitive JSON representations.
test_bool_enum(self)Confirms that subclassing
boolandenum.Enumraises aTypeError.This is expected since
boolenums are not supported by Python's enum system.
test_non_str_keys_enum(self)Tests serialization of dictionaries with enum keys using the
OPT_NON_STR_KEYSoption.Ensures enum keys are converted to strings in JSON output.
Important Implementation Details and Algorithms
The file demonstrates that
orjson.dumpscan serialize enum members by their underlying values (string, int, float), supporting nested and complex enum values, including dictionaries and custom classes.The
defaultfunction is used as a fallback serialization handler for objectsorjsoncannot serialize by default (e.g., instances ofCustom).pytest.raises(TypeError)is used to ensure Python's enum metaclass constraints are enforced regarding subclassing and unsupported enum types.The
orjson.OPT_NON_STR_KEYSoption is demonstrated, allowing dictionaries with non-string keys (like enum members) to serialize with stringified keys.The file includes an erroneous example (
AutoEnum) whereenum.autois misused as a base class instead of as a value generator — this is likely intentional to test failure or edge cases.
Interaction with Other Parts of the System
This test file depends on the
orjsonlibrary for JSON serialization and onpytestfor testing functionality.It tests how enum objects are serialized, likely supporting or validating enum serialization logic in the broader project.
It indirectly tests the
orjsonlibrary's integration with Python enums, ensuring correct JSON output for various enum configurations.The
Customclass anddefaultfunction pattern showcase how to extendorjsonserialization in the system.
Usage Examples
import orjson
from test_enum import UnspecifiedEnum, default
# Serialize an enum member with a string value
json_bytes = orjson.dumps(UnspecifiedEnum.A) # b'"a"'
# Serialize an enum member with a custom class using default handler
json_bytes_custom = orjson.dumps(UnspecifiedEnum.E, default=default) # b'"c"'
# Serialize a dictionary with enum keys using non-str keys option
json_bytes_dict = orjson.dumps({UnspecifiedEnum.A: 1}, option=orjson.OPT_NON_STR_KEYS) # b'{"a":1}'
Mermaid Class Diagram
classDiagram
class StrEnum {
+AAA: str = "aaa"
}
class IntEnum {
+ONE: int = 1
}
class IntEnumEnum {
+ONE: int = 1
}
class IntFlagEnum {
+ONE: int = 1
}
class FlagEnum {
+ONE: int = 1
}
class AutoEnum {
+A: str = "a"
}
class FloatEnum {
+ONE: float = 1.1
}
class Custom {
-val: any
+__init__(val)
}
class UnspecifiedEnum {
+A: str = "a"
+B: int = 1
+C: float = FloatEnum.ONE
+D: dict = {"d": IntEnum.ONE}
+E: Custom = Custom("c")
+F: datetime = datetime.datetime(1970,1,1)
}
class TestEnum {
+test_cannot_subclass()
+test_arbitrary_enum()
+test_custom_enum()
+test_enum_options()
+test_int_enum()
+test_intenum_enum()
+test_intflag_enum()
+test_flag_enum()
+test_auto_enum()
+test_float_enum()
+test_str_enum()
+test_bool_enum()
+test_non_str_keys_enum()
}
StrEnum <|-- UnspecifiedEnum
IntEnum <|-- UnspecifiedEnum
FloatEnum <|-- UnspecifiedEnum
Custom <|-- UnspecifiedEnum
Summary
`test_enum.py` is a comprehensive test suite validating how different types of Python enums are serialized into JSON using the `orjson` library. It covers primitive value enums, flags, mixed-type enums, and custom serialization cases, while also verifying Python enum subclassing rules and serialization options. This file ensures that enums behave predictably and correctly in the context of JSON data interchange within the broader application ecosystem.