I'm trying to update django_pyodbc
for django 1.8 and it turns out that SQLDateCompiler
was removed from django completely in version 1.8. django_pyodbc
is extending SQLDateCompiler
(let's call it SQLDateCompilerPrime
) which now no longer exists.
I want to issue a deprecation error/exception when a user inherits from SQLDateCompiler
before the class is instantiated.
I'm aware of how to use python's warnings
library to raise an exception, but how can I raise an intelligible exception before the class is even used. I.e. as soon as a subclass is defined.
I could do:
class SQLDateCompilerPrime(object):
def __init__(self, *args, **kwargs):
warnings.warn(
'In the 1.8 release of django, `SQLDateCompiler` was removed. ' +
'This was the basis of `SQLDateCompilerPrime`, and thus ' +
'`SQLDateCompilerPrime` is no longer available.',
DeprecationWarning, stacklevel=2)
However, this will only fail when an instance of a subclass is created. I want to fail when the subclass is defined and issue the warning straight away. Removing the definition entirely would certainly cause a failure, but I don't want the user to have to look in other django_pyodbc
to figure out that it is no longer defined and that it just disappeared right out from under them.
答案 0 :(得分:1)
You can use a metaclass for this:
class DeprecatedMeta(type):
def __new__(cls, name, bases, attrs):
# if the metaclass is defined on the current class, it's not
# a subclass so we don't want to warn.
if attrs.get('__metaclass__') is not cls:
print 'deprecated:', name
return super(DeprecatedMeta, cls).__new__(cls, name, bases, attrs)
class Foo(object):
__metaclass__ = DeprecatedMeta
class Bar(Foo):
pass
class FooBar(Bar):
pass
This example results in the following output:
deprecated: Bar
deprecated: FooBar