[Python-bugs-list] [ python-Bugs-494904 ] Cannot pickle a class with a metaclass

noreply@sourceforge.net noreply@sourceforge.net
Tue, 18 Dec 2001 21:19:00 -0800


Bugs item #494904, was opened at 2001-12-18 20:52
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=494904&group_id=5470

Category: Type/class unification
>Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Dan Parisien (mathematician)
>Assigned to: Guido van Rossum (gvanrossum)
Summary: Cannot pickle a class with a metaclass

Initial Comment:
when pickle retrieves the __reduce__ method of a new 
style class that has a metaclass, instead of 
returning the metaclass's __reduce__ method bound to 
the class, it returns an unbound __reduce__ method of 
that class.

>>> class metaclass(type):
... 	def __reduce__(self):
... 		"""This is metaclass.__reduce__
... 		"""
... 		return type.__reduce__(self)
... 
>>> class newclass(object):
... 	__metaclass__ = metaclass
... 	def __reduce__(self):
... 		"""This is newclass.__reduce__
... 		"""
... 		return object.__reduce__(self)
... 
>>> print newclass.__reduce__.__doc__
This is newclass.__reduce__

when pickle calls object.__reduce__ on newclass, it 
returns an unbound newclass.__reduce__ and not a 
bound metaclass.__reduce__. This has the unfortunate 
side effect of not correctly 'reducing' the class. 
I'm trying to figure out a solution. 



----------------------------------------------------------------------

>Comment By: Tim Peters (tim_one)
Date: 2001-12-18 21:19

Message:
Logged In: YES 
user_id=31435

Assigned to Guido.

Dan, leading tabs vanish from the web view, but are visible 
in auto-emailed versions (it's a display issue, it's not 
that the database lost them) -- so don't worry about that.

----------------------------------------------------------------------

Comment By: Dan Parisien (mathematician)
Date: 2001-12-18 21:00

Message:
Logged In: YES 
user_id=118203

it's a shame the tabs do not appear above...
--- Solution

class metaclass(type):
    def __getattribute__(self, name):
        if name in ["__reduce__", "__getstate__", 
"__setstate__"]:
            return lambda s=self, f=getattr(type(self), 
name): f(s)
        return type.__getattribute__(self, name)

this fixed my bug, but it may not work for everybody. My 
suggestion is if you are to pickle a new style class, you 
should call 
type(new_style_class).__reduce__(new_style_class) instead 
of new_style_class.__reduce__()


----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=494904&group_id=5470