Imposing metaclass on library

Lulu of the Lotus-Eaters mertz at gnosis.cx
Tue Dec 17 22:20:59 EST 2002


I am having a problem with metaclass resolution order (I think).

Here is the situation:  I have a library of classes, and I do not want
to modify the library.  But I would like to cause all -descendents- of
library classes to be created with a custom metaclass (within my
application that uses the library).

The library can look like (trivial case):

    % cat library.py
    class Base1(object): pass
    class Base2(object): pass

Here is the application:

    % cat application.py
    class Meta(type):
        def __init__(cls, name, bases, dict):
            print "Making", name
            super(Meta, cls).__init__(name, bases, dict)

    # Basic tries at using metaclass Meta
    __metaclass__ = Meta
    class App1(object): pass    # Doesn't use Meta!
    class App2: pass            # Uses Meta
    class App3(object):         # Also uses Meta
        __metaclass__ = Meta

    # Now I want to create library children with metaclass Meta
    from library import *
    class App4(Base1): pass     # No go (even though global __metaclass__)
    class App5(Base1): pass     # No go ...
    class App6(Base2): pass     # No go ...

    # Here's a clumsy way to force it
    class Base1(Base1): __metaclass__ = Meta
    class App7(Base1): pass     # Works with redefined Base1
    class App8(Base1): pass     # ditto

    # Less forced looking attempt that fails.
    Base2.__metaclass__ = Meta
    class App9(Base2): pass     # But haven't done anything for Base2

The result is:

    % python application.py
    Making App2
    Making App3
    Making Base1
    Making App7
    Making App8

What I really want is some way to force ALL the AppN classes to be
created using Meta.  In my particular application, there will be a large
number of descendents of the limited number of library classes, so
explicitly adding the __metaclass__ attribute to every AppN class is
awkward.

In fact, in practice, a bunch of AppN classes are likely to be defined
in yet another support module, call it 'definitions.py'.  What I really
want is to be able to write my application like:

    from metaclasses import Meta
    #...something that imposes Meta on all the classes created...
    import library
    from definitions import App1, App2, App3  # Created with Meta
    class App4(library.Base1): ...            # also with Meta
    #...more stuff like created instances of AppN...

The person who write the library doesn't know about the definitions.
But the definitions inherit from some library class.  The person who
writes the definition do not know about the application.  But the
application wants to use the definitions (and the library), but creating
classes as instances of Meta.

Yours, Lulu...

--
    _/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY: Postmodern Enterprises _/_/_/
   _/_/    ~~~~~~~~~~~~~~~~~~~~[mertz at gnosis.cx]~~~~~~~~~~~~~~~~~~~~~  _/_/
  _/_/  The opinions expressed here must be those of my employer...   _/_/
 _/_/_/_/_/_/_/_/_/_/ Surely you don't think that *I* believe them!  _/_/





More information about the Python-list mailing list