2012-09-17 9 views
7

Estoy trabajando con un framework Python 2.x, y una versión reciente del framework ha movido algunas clases base ampliamente usadas del módulo A al módulo B (y las clases han sido renombrados a nombres más claros en el proceso). El módulo A define los identificadores compatibles con versiones anteriores para los nuevos nombres de clase.Despreciar el uso de una clase como clase principal en Python

B.py:

class BaseClass(object): 
    __metaclass__ = framework_meta # handles registration etc. 

A.py:

import B 
oldbase = B.BaseClass 

Ahora con el fin de ayudar a las personas migran su código, me gustaría ser capaz de emitir un DeprecationWarning (usando advertencias. advertir) cuando el código que utiliza el marco define una clase derivada de A.oldbase que le dice al programador que herede directamente del B.BaseClass.

Espero que esto se pueda lograr con una metaclase. Traté de declarar un nuevo metaclase que deriva de la metaclase marco

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) 

junto con:

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 

El problema que tengo ahora, es que obtengo un DeprecationWarning para la definición de oldbase. ¿Cómo puedo arreglar esto?

Respuesta

2

desea mostrar la advertencia si cualquiera de las bases están en desuso:

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) 
Cuestiones relacionadas