A simple immutable dictionary implementation with hashing support and performance optimizations
85
Recursive immutability system that converts objects and all nested objects to their immutable counterparts. Provides extensible type conversion with custom converters and comprehensive support for deeply nested data structures.
Converts objects recursively to immutable versions, handling nested structures like lists, dicts, sets, and custom types.
def deepfreeze(o, custom_converters=None, custom_inverse_converters=None):
"""
Convert object and all nested objects to immutable counterparts recursively.
Parameters:
- o: Object to freeze (any type)
- custom_converters: dict, optional custom type converters for freezing
- custom_inverse_converters: dict, optional custom inverse converters for thawing
Returns:
Immutable version of the object with all nested objects also made immutable
Built-in conversions:
- dict -> frozendict
- list/tuple -> tuple
- set -> frozenset
- Recursive application to all nested containers
"""Usage Example:
from frozendict import deepfreeze
# Freeze nested data structures
data = {
'users': [
{'name': 'Alice', 'roles': {'admin', 'user'}},
{'name': 'Bob', 'roles': {'user'}}
],
'settings': {
'debug': True,
'features': ['auth', 'logging']
}
}
frozen_data = deepfreeze(data)
# Result: frozendict with all nested dicts as frozendicts,
# lists as tuples, and sets as frozensets
# The frozen structure is completely immutable
print(type(frozen_data)) # frozendict
print(type(frozen_data['users'])) # tuple
print(type(frozen_data['users'][0])) # frozendict
print(type(frozen_data['users'][0]['roles'])) # frozensetRegister custom converters for specific types to extend deep freezing functionality.
def register(to_convert, converter, *, inverse=False):
"""
Add a converter for a type used by deepfreeze().
Parameters:
- to_convert: type, the type to convert
- converter: callable, function to convert instances of the type
- inverse: bool, if True, register as inverse converter for thawing (default: False)
Returns:
None
"""
def unregister(type, inverse=False):
"""
Remove a type from custom conversion.
Parameters:
- type: type, the type to remove from conversion
- inverse: bool, if True, remove from inverse converters (default: False)
Returns:
None
"""Usage Example:
from frozendict import register, unregister, deepfreeze
from collections import namedtuple
# Define a custom type
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
# Create an immutable version
FrozenPoint = namedtuple('FrozenPoint', ['x', 'y'])
def point_converter(point):
return FrozenPoint(point.x, point.y)
# Register the converter
register(Point, point_converter)
# Now deepfreeze can handle Point objects
data = {'center': Point(10, 20), 'radius': 5}
frozen = deepfreeze(data)
print(type(frozen['center'])) # FrozenPoint
# Remove the converter when no longer needed
unregister(Point)Inspect and access the current type conversion mappings.
def getFreezeConversionMap():
"""
Return the current freeze conversion map.
Returns:
dict: Mapping from types to their freeze converter functions
"""
def getFreezeConversionInverseMap():
"""
Return the current inverse freeze conversion map.
Returns:
dict: Mapping from types to their inverse converter functions
"""Usage Example:
from frozendict import getFreezeConversionMap, getFreezeConversionInverseMap
# Inspect current converters
freeze_map = getFreezeConversionMap()
print(freeze_map.keys()) # View registered types
inverse_map = getFreezeConversionInverseMap()
print(inverse_map.keys()) # View registered inverse typesclass FreezeError(Exception):
"""
Exception raised by freeze-related operations.
Raised when deepfreeze encounters an error during conversion,
such as unsupported types or circular references.
"""
class FreezeWarning(Warning):
"""
Warning for freeze-related operations.
Issued when deepfreeze encounters potentially problematic
situations that don't prevent operation completion.
"""Usage Example:
from frozendict import deepfreeze, FreezeError, FreezeWarning
import warnings
# Handle freeze errors
try:
# Some complex object that might fail to freeze
result = deepfreeze(some_complex_object)
except FreezeError as e:
print(f"Failed to freeze object: {e}")
# Monitor freeze warnings
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
result = deepfreeze(some_object)
for warning in w:
if issubclass(warning.category, FreezeWarning):
print(f"Freeze warning: {warning.message}")Using both freeze and inverse converters for round-trip conversion:
from frozendict import register, deepfreeze
from datetime import datetime, date
# Register bidirectional converters for datetime objects
def freeze_datetime(dt):
return dt.isoformat()
def thaw_datetime(iso_string):
return datetime.fromisoformat(iso_string)
register(datetime, freeze_datetime)
register(str, thaw_datetime, inverse=True)
# Now datetime objects are converted to strings when frozen
data = {'timestamp': datetime.now(), 'name': 'event'}
frozen = deepfreeze(data)
# frozen['timestamp'] is now a stringHandling complex nested structures with multiple custom types:
from frozendict import register, deepfreeze
from collections import namedtuple
# Define custom types and their immutable versions
class User:
def __init__(self, name, email):
self.name, self.email = name, email
class Project:
def __init__(self, name, users):
self.name, self.users = name, users
FrozenUser = namedtuple('FrozenUser', ['name', 'email'])
FrozenProject = namedtuple('FrozenProject', ['name', 'users'])
# Register converters
register(User, lambda u: FrozenUser(u.name, u.email))
register(Project, lambda p: FrozenProject(p.name, deepfreeze(p.users)))
# Deep freeze complex nested structures
project = Project('MyApp', [User('Alice', 'alice@example.com')])
frozen_project = deepfreeze(project)
# All levels are now immutableInstall with Tessl CLI
npx tessl i tessl/pypi-frozendictevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10