Merge pull request #584 from dangra/581-deprecated-subclass-fix

Fix wrong checks on subclassing of deprecated classes
This commit is contained in:
Daniel Graña 2014-02-05 13:48:40 -08:00
commit 3d4fe60e47
2 changed files with 19 additions and 2 deletions

View File

@ -145,6 +145,9 @@ class WarnWhenSubclassedTest(unittest.TestCase):
class OutdatedUserClass1(DeprecatedName):
pass
class OutdatedUserClass1a(DeprecatedName):
pass
class UnrelatedClass(object):
pass
@ -159,6 +162,8 @@ class WarnWhenSubclassedTest(unittest.TestCase):
assert not issubclass(UnrelatedClass, DeprecatedName)
assert not issubclass(OldStyleClass, DeprecatedName)
assert not issubclass(OldStyleClass, DeprecatedName)
assert not issubclass(OutdatedUserClass1, OutdatedUserClass1a)
assert not issubclass(OutdatedUserClass1a, OutdatedUserClass1)
self.assertRaises(TypeError, issubclass, object(), DeprecatedName)
@ -175,6 +180,9 @@ class WarnWhenSubclassedTest(unittest.TestCase):
class OutdatedUserClass2(DeprecatedName):
pass
class OutdatedUserClass2a(DeprecatedName):
pass
class UnrelatedClass(object):
pass
@ -186,6 +194,9 @@ class WarnWhenSubclassedTest(unittest.TestCase):
assert isinstance(UpdatedUserClass2(), DeprecatedName)
assert isinstance(UpdatedUserClass2a(), DeprecatedName)
assert isinstance(OutdatedUserClass2(), DeprecatedName)
assert isinstance(OutdatedUserClass2a(), DeprecatedName)
assert not isinstance(OutdatedUserClass2a(), OutdatedUserClass2)
assert not isinstance(OutdatedUserClass2(), OutdatedUserClass2a)
assert not isinstance(UnrelatedClass(), DeprecatedName)
assert not isinstance(OldStyleClass(), DeprecatedName)

View File

@ -79,12 +79,18 @@ def create_deprecated_class(name, new_class, clsdict=None,
for c in {type(inst), inst.__class__})
def __subclasscheck__(cls, sub):
if cls is not DeprecatedClass.deprecated_class:
# we should do the magic only if second `issubclass` argument
# is the deprecated class itself - subclasses of the
# deprecated class should not use custom `__subclasscheck__`
# method.
return super(DeprecatedClass, cls).__subclasscheck__(sub)
if not inspect.isclass(sub):
raise TypeError("issubclass() arg 1 must be a class")
mro = getattr(sub, '__mro__', ())
candidates = {cls, new_class}
return any(c in candidates for c in mro)
return any(c in {cls, new_class} for c in mro)
def __call__(cls, *args, **kwargs):
old = DeprecatedClass.deprecated_class