[Python-Dev] PEP 351

Bengt Richter bokr at oz.net
Sun Feb 12 04:24:17 CET 2006


On Sat, 11 Feb 2006 12:55:10 -0800, Alex Martelli <aleaxit at gmail.com> wrote:

>
>On Feb 10, 2006, at 1:05 PM, Raymond Hettinger wrote:
>
>> [Guido van Rossum]
>>> PEP 351 - freeze protocol. I'm personally -1; I don't like the  
>>> idea of
>>> freezing arbitrary mutable data structures. Are there champions who
>>> want to argue this?
>>
>> It has at least one anti-champion.  I think it is a horrible idea  
>> and would
>> like to see it rejected in a way that brings finality.  If needed,  
>> I can
>> elaborate in a separate thread.
>
>Could you please do that?  I'd like to understand all of your  
>objections.  Thanks!
>
>
PMJI. I just read PEP 351, and had an idea for doing the same without pre-instantiating protected
subclasses, and doing the wrapping on demand instead. Perhaps of interest? (Or if already considered
and rejected, shouldn't this be mentioned in the PEP?)

The idea is to factor out freezing from the objects to be frozen. If it's going to involve copying anyway,
feeding the object to a wrapping class constructor doesn't seem like much extra overhead.

The examples in the PEP were very amenable to this approach, but I don't know how it would apply
to whatever Alex's use cases might be.

Anyhow, why shouldn't you be able to call freeze(an_ordinary_list) and get back freeze(xlist(an_ordinary_list))
automatically, based e.g. on a freeze_registry_dict[type(an_ordinary_list)] => xlist lookup, if plain hash fails?

Common types that might be usefully freezable could be pre-registered, and when a freeze fails
on a user object (presumably inheriting a __hash__ that bombs or because he wants it to) the programmer's
solution would be to define a suitable callable to produce the frozen object, and register that, but not modify his
unwrapped pre-freeze-mods object types and instantiations.

BTW, xlist wouldn't need to exist, since freeze_registry_dict[type(alist)] could just return the tuple type.
Otherwise the programmer would make a wrapper class taking the object as an __init__ (or maybe __new__) arg,
and intercepting the mutating methods etc., and stuff that in the freeze_registry_dict. IWT some metaclass stuff
might make it possible to parameterize a lot of wrapper class aspects, e.g., if you gave it a
__mutator_method_name_list__ to work with.

Perhaps freeze builtin could be a callable object with __call__ for the freeze "function" call
and with e.g. freeze.register(objtype, wrapper_class) as a registry API.

I am +0 on any of this in any case, not having had a use case to date, but I thought taking the
__freeze__ out of the objects (by not forcing them to be them pre-instantiatated as wrapped instances)
and letting registered freeze wrappers do it on demand instead might be interesting to someone.
If not, or if it's been discussed (no mention on the PEP tho) feel free to ignore ;-)

BTW freeze as just described might be an instance of

class Freezer(object):
    def __init__(self):
        self._registry_dict = {
            set:frozenset,
            list:tuple,
            dict:imdict}
    def __call__(self, obj):
        try: return hash(obj)
        except TypeError:
            freezer = self._registry_dict.get(type(obj))
            if freezer: return freezer(obj)
            raise TypeError('object is not freezable')
    def register(self, objtype, wrapper):
        self._registry_dict[objtype] = wrapper

(above refers to imdict from PEP 351) 
Usage example:

 >>> import alt351
 >>> freeze = alt351.Freezer()
(well, pretend freeze is builtin)

 >>> fr5 = freeze(range(5))
 >>> fr5
 (0, 1, 2, 3, 4)
 >>> d = dict(a=1,b=2)
 >>> d
 {'a': 1, 'b': 2}
 >>> fd = freeze(d)
 >>> fd
 {'a': 1, 'b': 2}
 >>> fd['a']
 1
 >>> fd['a']=3
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "alt351.py", line 7, in _immutable
     raise TypeError('object is immutable')
 TypeError: object is immutable
 >>> type(fd)
 <class 'alt351.imdict'>

+0 ;-)


Regards,
Bengt Richter



More information about the Python-Dev mailing list