Welcome, guest | Sign In | My Account | Store | Cart
"""freeze module

The freeze and unfreeze functions special-case some of the built-in
types.  If these types grow the appropriate methods then that will
become unnecessary.

"""


__all__
= ("Freezable", "UnFreezable", "freeze", "unfreeze")


import builtins
from abc import ABCMeta, abstractmethod


class Freezable(metaclass=ABCMeta):

   
@abstractmethod
   
def __freeze__(self):
       
"""Returns an immutable version of this object."""


class UnFreezable(metaclass=ABCMeta):

   
@abstractmethod
   
def __unfreeze__(self):
       
"""Returns a mutable version of this object."""


def freeze(obj):
   
"""Returns the immutable version of the object."""

   
if hasattr(type(obj), "__freeze__"):
       
return obj.__freeze__()
   
try:
        handler
= _freeze_registry[type(obj)]
   
except KeyError:
       
pass
   
else:
       
return handler(obj)
   
#if hasattr(type(obj), "__unfreeze__"):
   
#    return obj

    msg
= "Don't know how to freeze a {} object"
   
raise TypeError(msg.format(type(obj)))


def unfreeze(obj, strict=False):
   
if hasattr(type(obj), "__unfreeze__"):
       
return obj.__unfreeze__()
   
try:
        handler
= _unfreeze_registry[type(obj)]
   
except KeyError:
       
pass
   
else:
       
return handler(obj)
   
#if hasattr(type(obj), "__freeze__"):
   
#    return obj

    msg
= "Don't know how to unfreeze a {} object"
   
raise TypeError(msg.format(type(obj)))


#################################################
# special-casing built-in types

_freeze_registry
= {}
_unfreeze_registry
= {}
def register(f, cls=None):
    action
, typename = f.__name__.split("_")
   
if cls is None:
        cls
= getattr(builtins, typename)
   
if action == "freeze":
        _freeze_registry
[cls] = f
       
Freezable.register(cls)
   
elif action == "unfreeze":
        _unfreeze_registry
[cls] = f
       
UnFreezable.register(cls)
   
else:
       
raise TypeError
   
return f


@register
def freeze_dict(obj):
   
raise NotImplementedError

@register
def unfreeze_dict(obj):
   
return obj


@register
def freeze_list(obj):
   
return tuple(obj)

@register
def unfreeze_list(obj):
   
return obj


@register
def freeze_tuple(obj):
   
return obj

@register
def unfreeze_tuple(obj):
   
return list(obj)

History