Helper Functions#
Utility functions used throughout the serialization system.
Function Reference#
Get the fully qualified name of a class. |
|
|
Check if an object is an instance of the specified type(s). |
Detailed Documentation#
get_full_qualified_name#
- jangada.serialization.get_full_qualified_name(cls: type) str#
Get the fully qualified name of a class.
Returns the module path and class name (e.g., ‘mypackage.module.ClassName’). For builtin types without a module, returns just the qualified name.
- Parameters:
- clstype
The class for which to get the qualified name.
- Returns:
- str
The fully qualified name in the format ‘module.qualname’.
Notes
This function is used internally to create unique identifiers for classes in the serialization registry.
Examples
>>> class MyClass: ... pass >>> get_full_qualified_name(MyClass) '__main__.MyClass'
>>> get_full_qualified_name(int) 'int'
Returns the fully qualified name of a class in the format module.qualname.
This is used to create unique identifiers for classes in the serialization registry.
Examples:
>>> from mypackage import MyClass
>>> get_full_qualified_name(MyClass)
'mypackage.MyClass'
>>> get_full_qualified_name(int)
'int'
>>> get_full_qualified_name(list)
'list'
Usage in Serialization:
# The __class__ key in serialized data uses qualified names
class MyClass(Serializable):
value = SerializableProperty(default=0)
obj = MyClass(value=42)
data = Serializable.serialize(obj)
print(data['__class__'])
# Output: 'mymodule.MyClass'
Notes:
Builtin types (like
int,str,list) return just thequalnameUser-defined classes return
module.qualnameNested classes include their parent:
'module.OuterClass.InnerClass'
check_types#
- jangada.serialization.check_types(obj: Any, types: type | tuple[type], can_be_none: bool = False, raise_error: bool = True) bool#
Check if an object is an instance of the specified type(s).
- Parameters:
- objAny
The object to check.
- typestype | tuple[type]
A single type or tuple of types to check against.
- can_be_nonebool, optional
If True, None is considered a valid value. Default is False.
- raise_errorbool, optional
If True, raise TypeError on type mismatch. If False, return False instead. Default is True.
- Returns:
- bool
True if the object matches the expected type(s), False otherwise (only when raise_error=False).
- Raises:
- TypeError
If the object does not match the expected type(s) and raise_error=True.
Examples
>>> check_types(5, int) True
>>> check_types("hello", (int, str)) True
>>> check_types(None, int, can_be_none=True) True
>>> check_types(5, str, raise_error=False) False
>>> check_types(5, str) Traceback (most recent call last): ... TypeError: Expected instance of one of the following classes: str. Given int instead
Type checking utility with optional None handling and flexible error behavior.
Basic Usage:
>>> check_types(42, int)
True
>>> check_types("hello", str)
True
>>> check_types([1, 2, 3], list)
True
Multiple Types:
>>> check_types(42, (int, float))
True
>>> check_types(3.14, (int, float))
True
>>> check_types("text", (int, float), raise_error=False)
False
Allowing None:
>>> check_types(None, int, can_be_none=True)
True
>>> check_types(42, int, can_be_none=True)
True
>>> check_types(None, int, can_be_none=False)
Traceback (most recent call last):
...
TypeError: Expected instance of one of the following classes: int...
Error Behavior:
# With raise_error=True (default)
>>> check_types(42, str) # doctest: +SKIP
Traceback (most recent call last):
...
TypeError: Expected instance of one of the following classes: str. Given int instead
# With raise_error=False
>>> check_types(42, str, raise_error=False)
False
>>> check_types("hello", str, raise_error=False)
True
Usage in Validation:
def process_data(data):
# Validate input type
check_types(data, dict)
# Process data...
pass
# Or with optional None
def process_optional_data(data):
check_types(data, dict, can_be_none=True)
if data is not None:
# Process data...
pass
Error Messages:
The error message includes the fully qualified names of expected and actual types:
>>> check_types(MyCustomClass(), ExpectedClass)
TypeError: Expected instance of one of the following classes:
mypackage.ExpectedClass. Given mypackage.MyCustomClass instead
Use Cases#
Class Name Resolution#
get_full_qualified_name is essential for the serialization registry:
# When a class is defined
class MyClass(Serializable):
pass
# The metaclass registers it:
qualname = get_full_qualified_name(MyClass)
Serializable._subclasses[qualname] = MyClass
# Later, during deserialization:
data = {'__class__': 'mymodule.MyClass', ...}
cls = Serializable[data['__class__']] # Retrieves MyClass
Type Validation#
check_types is used throughout the codebase for validation:
# In Serializable._initialize_from_data
def _initialize_from_data(self, data):
check_types(data, dict) # Ensure data is a dict
# ... rest of initialization
# In property parsers
@property.parser
def property(self, value):
check_types(value, (int, float))
return float(value)
# In custom validation
def validate_input(obj):
check_types(obj, Serializable, can_be_none=False)
# ... further validation
API Consistency#
Using these helpers ensures consistent:
Error messages across the codebase
Type checking behavior
Class name formatting
Implementation Notes#
get_full_qualified_name#
Edge Cases:
Anonymous classes (
lambda,type()) may have unusual qualified namesClasses defined in
__main__will have'__main__'as their moduleNested classes include parent:
'Outer.Inner'
Performance:
This function is called frequently during (de)serialization. It’s kept simple for performance - just attribute access and string formatting.
check_types#
Implementation Details:
When can_be_none=True, the function adds type(None) to the types tuple:
if can_be_none:
if isinstance(types, tuple):
types = (*types, type(None))
else:
types = (types, type(None))
This allows isinstance(None, types) to succeed.
Why Not Use typing.isinstance()?:
check_typesis simpler and more explicitProvides custom error messages with qualified names
Handles the
can_be_noneflag cleanlyNo dependency on
typingmodule
Performance:
Type checking is fast (uses built-in isinstance). The error message
construction only happens on failure, so the happy path is efficient.
See Also#
serializable - Main class using these helpers
serializable_metatype - Metaclass that uses get_full_qualified_name
serializable_property - Property descriptor that may use check_types