[Python-Dev] metaclass insanity

Guido van Rossum guido@python.org
Mon, 04 Nov 2002 17:34:57 -0500

> > In the case of nested classes, a possible solution might be for
> > X.Y.__name__ to be "X.Y" rather than plain "Y".  Then a simple change
> > to pickle (or to getattr :-) could allow the correct unpickling.
> I'd rather expect that X.Y.__module__ is "Foo.X".

Also possible.  There are problems with each though; if X is a class
in module Foo, __import__("Foo.X") doesn't work.  Example:

>>> class C:
      class N: pass
>>> C.N.__module__
>>> C.N.__module__ = '__main__.C'
>>> import pickle
>>> s = pickle.dumps(C.N())
>>> pickle.loads(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/local/lib/python2.3/pickle.py", line 1071, in loads
    return Unpickler(file).load()
  File "/usr/local/lib/python2.3/pickle.py", line 675, in load
  File "/usr/local/lib/python2.3/pickle.py", line 852, in load_inst
    klass = self.find_class(module, name)
  File "/usr/local/lib/python2.3/pickle.py", line 907, in find_class
ImportError: No module named C

Given that we have to fix pickle.py and cPickle.c in either case, I
think I'd prefer setting __name__ to a dotted name reflecting the full
name of the class inside its module over setting __module__ to
something that's not a module.

--Guido van Rossum (home page: http://www.python.org/~guido/)