CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-frozendict

A simple immutable dictionary implementation with hashing support and performance optimizations

85

1.30x
Overview
Eval results
Files

json-integration.mddocs/

JSON Integration

Automatic JSON serialization support and monkeypatch utilities for seamless integration with JSON libraries. Provides custom encoders and system-wide patches for transparent frozendict serialization.

Capabilities

Automatic JSON Encoder

Custom JSON encoder that handles frozendict serialization by converting to regular dictionaries.

class FrozendictJsonEncoder(JSONEncoder):
    """
    JSON encoder that can serialize frozendict instances.
    
    Automatically converts frozendict objects to regular dicts during
    JSON serialization while preserving all other JSONEncoder functionality.
    """
    
    def default(self, obj):
        """
        Convert frozendict to dict for JSON serialization.
        
        Parameters:
        - obj: Object to serialize
        
        Returns:
        dict: Regular dict if obj is frozendict, otherwise delegates to parent
        """

Usage Example:

import json
from frozendict import frozendict, FrozendictJsonEncoder

# Create frozendict with nested data
data = frozendict({
    'name': 'Alice',
    'settings': frozendict({'theme': 'dark', 'notifications': True}),
    'tags': ['admin', 'developer']
})

# Serialize using custom encoder
json_string = json.dumps(data, cls=FrozendictJsonEncoder, indent=2)
print(json_string)
# {
#   "name": "Alice",
#   "settings": {
#     "theme": "dark",
#     "notifications": true
#   },
#   "tags": ["admin", "developer"]
# }

# Deserialize back to regular dicts
restored = json.loads(json_string)
# Note: restored will contain regular dicts, not frozendicts

JSON Module Patching

Patch the standard json module to automatically handle frozendict serialization.

def patchOrUnpatchJson(*, patch, warn=True):
    """
    Patch or unpatch JSON module to handle frozendict serialization.
    
    Parameters:
    - patch: bool, True to apply patch, False to remove patch
    - warn: bool, whether to show warnings about patching (default: True)
    
    Returns:
    None
    
    Effects:
    - When patched: json.dumps() automatically handles frozendict objects
    - When unpatched: json.dumps() raises TypeError for frozendict objects
    """

Usage Example:

import json
from frozendict import frozendict, patchOrUnpatchJson

# Enable automatic JSON support
patchOrUnpatchJson(patch=True, warn=False)

data = frozendict({'key': 'value', 'number': 42})

# Now json.dumps works directly with frozendict
json_string = json.dumps(data)
print(json_string)  # {"key": "value", "number": 42}

# Disable automatic support
patchOrUnpatchJson(patch=False)

# Now json.dumps would raise TypeError
try:
    json.dumps(data)
except TypeError as e:
    print(f"Error: {e}")  # Object of type frozendict is not JSON serializable

OrJSON Integration

Support for the high-performance orjson library with automatic frozendict handling.

def patchOrUnpatchOrjson(*, patch, warn=True):
    """
    Patch or unpatch orjson module to handle frozendict serialization.
    
    Parameters:
    - patch: bool, True to apply patch, False to remove patch
    - warn: bool, whether to show warnings about patching (default: True)
    
    Returns:
    None
    
    Effects:
    - When patched: orjson.dumps() automatically handles frozendict objects
    - When unpatched: orjson.dumps() raises TypeError for frozendict objects
    """

Usage Example:

# Requires: pip install orjson
import orjson
from frozendict import frozendict, patchOrUnpatchOrjson

# Enable orjson support
patchOrUnpatchOrjson(patch=True)

data = frozendict({'performance': 'high', 'speed': 'fast'})

# orjson now handles frozendict automatically
json_bytes = orjson.dumps(data)
json_string = json_bytes.decode('utf-8')
print(json_string)  # {"performance": "high", "speed": "fast"}

# Restore original behavior
patchOrUnpatchOrjson(patch=False)

Collections Integration

Patch collections.abc.MutableMapping to properly exclude frozendict from mutable mapping checks.

def patchOrUnpatchMutableMappingSubclasshook(*, patch, warn=True):
    """
    Patch or unpatch MutableMapping to exclude frozendict.
    
    Parameters:
    - patch: bool, True to apply patch, False to remove patch  
    - warn: bool, whether to show warnings about patching (default: True)
    
    Returns:
    None
    
    Effects:
    - When patched: isinstance(frozendict(), MutableMapping) returns False
    - When unpatched: isinstance(frozendict(), MutableMapping) might return True
    """

Usage Example:

from collections.abc import MutableMapping, Mapping
from frozendict import frozendict, patchOrUnpatchMutableMappingSubclasshook

# Apply the patch
patchOrUnpatchMutableMappingSubclasshook(patch=True)

d = frozendict({'a': 1, 'b': 2})

# frozendict is correctly identified as non-mutable
print(isinstance(d, Mapping))        # True (it is a mapping)
print(isinstance(d, MutableMapping)) # False (it is not mutable)

# Remove the patch
patchOrUnpatchMutableMappingSubclasshook(patch=False)

Comprehensive Patching

Apply or remove all monkeypatches at once for complete integration.

def patchOrUnpatchAll(*, patch, warn=True, raise_orjson=False):
    """
    Apply or remove all monkeypatches at once.
    
    Parameters:
    - patch: bool, True to apply all patches, False to remove all patches
    - warn: bool, whether to show warnings about patching (default: True)
    - raise_orjson: bool, raise exception if orjson patch fails (default: False)
    
    Returns:
    None
    
    Effects:
    Applies/removes all of:
    - JSON module patching
    - OrJSON module patching (if available)
    - MutableMapping subclass hook patching
    """

Usage Example:

import json
from frozendict import frozendict, patchOrUnpatchAll

# Enable all integrations
patchOrUnpatchAll(patch=True, warn=False)

# Now everything works seamlessly
data = frozendict({'integrated': True, 'seamless': True})
json_result = json.dumps(data)  # Works automatically

# Disable all integrations
patchOrUnpatchAll(patch=False, warn=False)

Warning Classes

class MonkeypatchWarning(Warning):
    """
    Warning class for monkeypatch operations.
    
    Issued when monkeypatch operations encounter potentially
    problematic situations or when patches are applied/removed.
    """

Usage Example:

import warnings
from frozendict import patchOrUnpatchAll, MonkeypatchWarning

# Monitor monkeypatch warnings
with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter("always")
    
    # This might issue warnings about patching
    patchOrUnpatchAll(patch=True, warn=True)
    
    for warning in w:
        if issubclass(warning.category, MonkeypatchWarning):
            print(f"Monkeypatch warning: {warning.message}")

Automatic Initialization

When importing frozendict, the following occurs automatically:

# Automatically executed on import:
patchOrUnpatchAll(patch=True, warn=False)

This means that JSON serialization support is enabled by default when you import frozendict, providing seamless integration without explicit setup.

Advanced Integration Patterns

Custom JSON Encoder Extension

Extending FrozendictJsonEncoder for additional custom types:

import json
from frozendict import FrozendictJsonEncoder
from datetime import datetime

class ExtendedJsonEncoder(FrozendictJsonEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        return super().default(obj)

# Use extended encoder
data = frozendict({
    'timestamp': datetime.now(),
    'nested': frozendict({'key': 'value'})
})

json_string = json.dumps(data, cls=ExtendedJsonEncoder)

Selective Patching

Apply only specific patches for controlled integration:

from frozendict import (
    patchOrUnpatchJson,
    patchOrUnpatchMutableMappingSubclasshook
)

# Enable only JSON support, not orjson
patchOrUnpatchJson(patch=True, warn=False)
patchOrUnpatchMutableMappingSubclasshook(patch=True, warn=False)

# orjson patching is not applied, giving more control

Context-Managed Patching

Temporarily enable patches for specific operations:

import json
from contextlib import contextmanager
from frozendict import frozendict, patchOrUnpatchJson

@contextmanager
def json_patched():
    patchOrUnpatchJson(patch=True, warn=False)
    try:
        yield
    finally:
        patchOrUnpatchJson(patch=False, warn=False)

# Use within context
data = frozendict({'temp': 'patch'})

with json_patched():
    result = json.dumps(data)  # Works with patch
    
# Outside context, patch is removed

Install with Tessl CLI

npx tessl i tessl/pypi-frozendict

docs

core-dictionary.md

deep-freezing.md

index.md

json-integration.md

tile.json