Merged revisions 78800 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r78800 | florent.xicluna | 2010-03-08 16:20:28 +0100 (lun, 08 mar 2010) | 2 lines

  #7624: Fix isinstance(foo(), collections.Callable) for old-style classes.
........
This commit is contained in:
Florent Xicluna 2010-03-23 12:37:29 +00:00
parent dbac168948
commit d474f3a239
4 changed files with 62 additions and 11 deletions

View file

@ -21,6 +21,14 @@ __all__ = ["Hashable", "Iterable", "Iterator",
### ONE-TRICK PONIES ###
def _hasattr(C, attr):
try:
return any(attr in B.__dict__ for B in C.__mro__)
except AttributeError:
# Old-style class
return hasattr(C, attr)
class Hashable:
__metaclass__ = ABCMeta
@ -31,11 +39,16 @@ class Hashable:
@classmethod
def __subclasshook__(cls, C):
if cls is Hashable:
for B in C.__mro__:
if "__hash__" in B.__dict__:
if B.__dict__["__hash__"]:
return True
break
try:
for B in C.__mro__:
if "__hash__" in B.__dict__:
if B.__dict__["__hash__"]:
return True
break
except AttributeError:
# Old-style class
if getattr(C, "__hash__", None):
return True
return NotImplemented
@ -50,7 +63,7 @@ class Iterable:
@classmethod
def __subclasshook__(cls, C):
if cls is Iterable:
if any("__iter__" in B.__dict__ for B in C.__mro__):
if _hasattr(C, "__iter__"):
return True
return NotImplemented
@ -69,7 +82,7 @@ class Iterator(Iterable):
@classmethod
def __subclasshook__(cls, C):
if cls is Iterator:
if any("next" in B.__dict__ for B in C.__mro__):
if _hasattr(C, "next"):
return True
return NotImplemented
@ -84,7 +97,7 @@ class Sized:
@classmethod
def __subclasshook__(cls, C):
if cls is Sized:
if any("__len__" in B.__dict__ for B in C.__mro__):
if _hasattr(C, "__len__"):
return True
return NotImplemented
@ -99,7 +112,7 @@ class Container:
@classmethod
def __subclasshook__(cls, C):
if cls is Container:
if any("__contains__" in B.__dict__ for B in C.__mro__):
if _hasattr(C, "__contains__"):
return True
return NotImplemented
@ -114,7 +127,7 @@ class Callable:
@classmethod
def __subclasshook__(cls, C):
if cls is Callable:
if any("__call__" in B.__dict__ for B in C.__mro__):
if _hasattr(C, "__call__"):
return True
return NotImplemented