Pickling classes (not class instances)
Nicolas M. Thiéry
Nicolas.Thiery at u-psud.fr
Sat Feb 14 09:19:53 CET 2009
Dear python developers,
I got no answer to my previous post on this thread "Pickling classes
(not class instances)".
This issue is a show stopper for our project. Any suggestion for where
Thanks in advance!
> Purpose of this e-mail:
> How to customize how a class (not an instance of a class!!!) is
> class metaclass(type):
> def __new__(mcs, name, bases, dict):
> print " running metaclass.__new__"
> return type.__new__(mcs, name, bases, dict)
> def __reduce_class__(self):
> print "reducing a class"
> # do the real work
> c = metaclass("foo", (object,), dict())
> import copy_reg
> copy_reg.pickle(metaclass, metaclass.__reduce_class__)
> PicklingError Traceback (most recent call
> PicklingError: Can't pickle <class '__main__.foo'>: it's not found as
> I am working on the Sage project (www.sagemath.org), and more
> precisely on the category infrastructure. The code is building lots of
> classes on the fly by composing preexisting classes by inheritance
> (for the curious, see the doc of the class Category inhttp://sage.math.washington.edu:2144/file/1567cea09170/categories-nt....).
> Since those classes are built on the fly, they cannot be pickled with
> the default mechanism of name lookup. A proper pickling would be to
> rebuild the class anew. Nothing problematic, except for the question
> It sounds like copy_reg would be the natural way to go (as in the
> example above). However, its documentation suggests that it explicitly
> is not intended for pickling classes, e.g. first paragraph of:
> The copy_reg module provides support for the pickle and cPickle
> modules. The copy module is likely to use this in the future as
> well. It provides configuration information about object
> constructors which are not classes. Such constructors may be factory
> functions or class instances.
> And indeed, looking up at the code of pickle (l. 289-299 of pickle.py)
> (and similarly in cpickle), the copy-reg dispatch is explicit bypassed
> for metaclasses:
> # Check for a class with a custom metaclass; treat as regular
> issc = issubclass(t, TypeType)
> except TypeError: # t is not a class (old Boost; see SF
> issc = 0
> if issc:
> # Check copy_reg.dispatch_table
> reduce = dispatch_table.get(t)
> Which causes the failure above.
> Is there a specific reason for this restriction?
> Would it be thinkable to move up the copy reg dispatch before the
> metaclass treatment in pickle and cPickle? I did it locally, and it
> fixed my problem.
> If not, what would be the right way to achieve this?
> Many thanks in advance!
> Best regards,
> Nicolas M. Thiéry "Isil" <nthi... at users.sf.net>http://Nicolas.Thiery.name/
More information about the Python-list