diff options
| author | Florent Xicluna <florent.xicluna@gmail.com> | 2010-03-23 12:37:29 (GMT) |
|---|---|---|
| committer | Florent Xicluna <florent.xicluna@gmail.com> | 2010-03-23 12:37:29 (GMT) |
| commit | d474f3a23953d55a34588c75cfc2641c4d0da81b (patch) | |
| tree | bcbc6c546570fd28988ab9ded2d1e3389eb2cbc2 /Lib/_abcoll.py | |
| parent | dbac1689483ec160bb811792f5a70e09fefd55ec (diff) | |
| download | cpython-d474f3a23953d55a34588c75cfc2641c4d0da81b.zip cpython-d474f3a23953d55a34588c75cfc2641c4d0da81b.tar.gz cpython-d474f3a23953d55a34588c75cfc2641c4d0da81b.tar.bz2 | |
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.
........
Diffstat (limited to 'Lib/_abcoll.py')
| -rw-r--r-- | Lib/_abcoll.py | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/Lib/_abcoll.py b/Lib/_abcoll.py index d8cdc98..82ded37 100644 --- a/Lib/_abcoll.py +++ b/Lib/_abcoll.py @@ -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 |
