I'm working with a Python 2.x framework, and a recent version of the framework has moved some widely used base classes from module A to module B (and the classes have been renamed to a clearer names in the process). Module A defines a backward compatible identifiers for the new class names. 
B.py:
class BaseClass(object):
    __metaclass__ = framework_meta # handles registration etc.
A.py:
import B
oldbase = B.BaseClass
Now in order to help people migrate their code, I would like to be able to issue a DeprecationWarning (using warnings.warn) whenever code using the framework defines a class deriving from A.oldbase telling the programmer to directly inherit from B.BaseClass. 
I expect this can be achieved with a metaclass. I tried to declare a new metaclass deriving from the framework metaclass
class deprecated_base_class(framework_meta):
    def __new__(meta, name, bases, attrs):
        warning = '%(class)s is deprecated'
        for b in bases:
            warning =  getattr(b, '__deprecation_warning__', None) or warning
        warn(warning % {'class': name}, DeprecationWarning, stacklevel=2)
        return super(deprecated_base_class, meta).__new__(meta, name, bases, attrs)
together with:
A.py:
class oldbase(B.BaseClass):
    __metaclass__ = deprecated_base_class
    __deprecation_warning__ = 'class oldbase is deprecated. Use B.BaseClass instead'
clientcode.py
class FooBar(oldbase):
    pass
The problem I have now, is that I get a DeprecationWarning for the definition of oldbase. How can I fix this?
You want to display the warning if any of the bases are deprecated:
class deprecated_base_class(framework_meta):
    def __new__(meta, name, bases, attrs):
        for b in bases:
            if isinstance(b, deprecated_base_class):
                warning = getattr(b, '__deprecation_warning__', '%(class)s is deprecated')
                warn(warning % {'class': b.__name__}, DeprecationWarning, stacklevel=2)
        return super(deprecated_base_class, meta).__new__(meta, name, bases, attrs)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With