Skip to content Skip to sidebar Skip to footer

Portable Meta Class Between Python2 And Python3

I'm trying to get a python2 program working in python3, it has the following Meta class definition. Which works just fine on Py2. What's the 'best' way to have this be compatible

Solution 1:

You could use the MetaDocument() metaclass as a factory to produce a class replacing your Document class, re-using the class attributes:

class Document(object):
    # various and sundry methods and attributes

body = vars(Document).copy()
body.pop('__dict__', None)
body.pop('__weakref__', None)

Document = MetaDocument(Document.__name__, Document.__bases__, body)

This doesn't require you to build the 3rd argument, the class body, manually.

You can turn this into a class decorator:

defwith_metaclass(mcls):
    defdecorator(cls):
        body = vars(cls).copy()
        # clean out class body
        body.pop('__dict__', None)
        body.pop('__weakref__', None)
        return mcls(cls.__name__, cls.__bases__, body)
    return decorator

then use as:

@with_metaclass(MetaDocument)classDocument(object):
    # various and sundry methods and attributes

Alternatively, use the six library for this:

@six.add_metaclass(MetaDocument)
classDocument(object):

where the @six.add_metaclass() decorator also takes care of any __slots__ you may have defined; my simpler version above doesn't.

six also has a six.with_metaclass() base-class factory:

class Document(six.with_metaclass(MetaDocument)):

which injects an extra base class into the MRO.

Solution 2:

six has a utility for this.

classDocument(six.with_metaclass(MetaDocument, object)):
    # classdefinition, without the __metaclass__

The only side effect is that the class hierarchy changes from

>>> Document.__mro__
(<class'test.Document'>, <type'object'>)

to

>>> Document.__mro__
(<class'test.Document'>, <class'test.NewBase'>, <type'object'>)

because with_metaclass actually returns a new class with the appropriate metaclass.

Post a Comment for "Portable Meta Class Between Python2 And Python3"