He cambiado el nombre de una clase python que forma parte de una biblioteca. Estoy dispuesto a dejar la posibilidad de usar su nombre anterior durante algún tiempo, pero me gustaría advertir al usuario que está obsoleto y se eliminará en el futuro.Cómo advertir acerca de la desactivación de clase (nombre)
creo que para proporcionar compatibilidad con versiones anteriores, será suficiente para utilizar un alias de esa manera:
class NewClsName:
pass
OldClsName = NewClsName
no tengo idea de cómo marcar la OldClsName
como obsoletos de una manera elegante. Tal vez podría hacer OldClsName
una función que emite una advertencia (a registros) y construye el objeto NewClsName
desde sus parámetros (usando *args
y **kvargs
) pero no parece lo suficientemente elegante (¿o tal vez lo es?).
Sin embargo, no sé cómo funcionan las advertencias de desaprobación de la biblioteca estándar de Python. Me imagino que puede haber algo de magia agradable para lidiar con la desaprobación, p. permitiendo tratarlo como errores o silenciar dependiendo de la opción de línea de comando de algún intérprete.
La pregunta es: Cómo advertir a los usuarios sobre el uso de un alias de clase obsoleto (o clase obsoleta en general).
EDITAR: El enfoque de la función no funciona para mí (yo ya lo intentó) debido a que la clase tiene algunos métodos de clase (métodos de fábrica) que no se puede llamar cuando el OldClsName
se define como una función . Siguiente código no funcionará:
class NewClsName(object):
@classmethod
def CreateVariant1(cls, ...):
pass
@classmethod
def CreateVariant2(cls, ...):
pass
def OldClsName(*args, **kwargs):
warnings.warn("The 'OldClsName' class was renamed [...]",
DeprecationWarning)
return NewClsName(*args, **kwargs)
OldClsName.CreateVariant1(...)
Debido:
AttributeError: 'function' object has no attribute 'CreateVariant1'
es la herencia que mi única opción? Para ser honesto, no me parece muy limpio: afecta la jerarquía de clases mediante la introducción de una derivación innecesaria. Además, OldClsName is not NewClsName
lo que no es un problema en la mayoría de los casos, pero puede ser un problema en caso de código mal escrito que utiliza la biblioteca.
También podría crear una clase ficticia, no relacionada OldClsName
e implementar un constructor, así como envoltorios para todos los métodos de clase en él, pero es una solución aún peor, en mi opinión.
Apoyando la herencia debe ser fácil, así - acaba de escribir una clase 'OldClsName (NewClsName): # y sobrecarga __new__'. – delnan
+1 para confirmar que se usa esta solución y para mencionar el módulo 'warnings'. Desafortunadamente, la solución de función no funciona para mí (ver la pregunta editada). Tal vez tienes algunas otras soluciones limpias? : D –
Se actualizó con un ejemplo de uso de un objeto envoltorio que puede proxy de ambas llamadas y atributos de acceso a la nueva clase. – AdamKG