Commits

Hong Minhee committed 5dfa36c

Other than abc.ABCMeta also could be abstract base (meta)classes.

  • Participants
  • Parent commits 9c1b3cd

Comments (0)

Files changed (1)

File typequery.py

 existing types.
 
 """
-try:
-    import abc
-except ImportError:
-    abc = None
+import sys
 
 __copyright__ = 'Copyright 2012, Hong Minhee'
 __license__ = 'MIT License'
 __version__ = '0.1.1'
 
 
+if sys.version_info < (2, 6, 0):
+    # Python 2.5:
+    # ABC (abstract base classes) were introduced since Python 2.6.
+    # So we don't care in Python 2.5.
+    # See PEP 3119 -- http://www.python.org/dev/peps/pep-3119/
+    def is_abc(cls):
+        return True
+elif hasattr(sys, 'pypy_version_info'):
+    # PyPy:
+    # PyPy metaclasses share the same reference to __subclasscheck__.im_func
+    # function object until these are explicitly overridden.
+    def is_abc(cls):
+        return (type(cls).__subclasscheck__.im_func is not
+                type.__subclasscheck__.im_func)
+elif hasattr(sys, 'JYTHON_JAR'):
+    # Jython 2.7a1:
+    # Jython metaclasses don't have __subclasscheck__ method until these
+    # are explicitly overridden.
+    def is_abc(cls):
+        return hasattr(type(cls), '__subclasscheck__')
+elif (2, 6, 0) <= sys.version_info < (2, 7, 0):
+    # CPython 2.6 (probably):
+    # CPython 2.6+ metaclasses (other than built-in types.TypeType)
+    # expose '__subclasscheck__' key through its __dict__ attribute
+    # only if these explictly override __subclasscheck__ method.
+    def is_abc(cls):
+        return (type(cls) is not type and
+                '__subclasscheck__' in type(cls).__dict__)
+else:
+    # CPython 2.7+ (probably):
+    # CPython 2.7+ metaclasses share the same reference to __subclasscheck__
+    # method object until these are explicitly overridden.
+    def is_abc(cls):
+        return type(cls).__subclasscheck__ is not type.__subclasscheck__
+
+
 class GenericMethod(object):
     """Generic method object.
 
         self.functions[cls] = function
         self.latest_added_function = function
         self.abc_cache = {}
-        if abc is not None and isinstance(cls, abc.ABCMeta):
+        if is_abc(cls):
             abcs = self.abcs
             for subcls in cls.mro()[1:]:
                 bases = abcs.setdefault(subcls, [])