aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/abc.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/abc.py')
-rw-r--r--Lib/abc.py88
1 files changed, 57 insertions, 31 deletions
diff --git a/Lib/abc.py b/Lib/abc.py
index 02e48a1bb32..a6c2dc48779 100644
--- a/Lib/abc.py
+++ b/Lib/abc.py
@@ -3,15 +3,8 @@
"""Abstract Base Classes (ABCs) according to PEP 3119."""
-import types
-
from _weakrefset import WeakSet
-# Instance of old-style class
-class _C: pass
-_InstanceType = type(_C())
-
-
def abstractmethod(funcobj):
"""A decorator indicating abstract methods.
@@ -23,8 +16,7 @@ def abstractmethod(funcobj):
Usage:
- class C:
- __metaclass__ = ABCMeta
+ class C(metaclass=ABCMeta):
@abstractmethod
def my_abstract_method(self, ...):
...
@@ -33,6 +25,46 @@ def abstractmethod(funcobj):
return funcobj
+class abstractclassmethod(classmethod):
+ """A decorator indicating abstract classmethods.
+
+ Similar to abstractmethod.
+
+ Usage:
+
+ class C(metaclass=ABCMeta):
+ @abstractclassmethod
+ def my_abstract_classmethod(cls, ...):
+ ...
+ """
+
+ __isabstractmethod__ = True
+
+ def __init__(self, callable):
+ callable.__isabstractmethod__ = True
+ super().__init__(callable)
+
+
+class abstractstaticmethod(staticmethod):
+ """A decorator indicating abstract staticmethods.
+
+ Similar to abstractmethod.
+
+ Usage:
+
+ class C(metaclass=ABCMeta):
+ @abstractstaticmethod
+ def my_abstract_staticmethod(...):
+ ...
+ """
+
+ __isabstractmethod__ = True
+
+ def __init__(self, callable):
+ callable.__isabstractmethod__ = True
+ super().__init__(callable)
+
+
class abstractproperty(property):
"""A decorator indicating abstract properties.
@@ -44,8 +76,7 @@ class abstractproperty(property):
Usage:
- class C:
- __metaclass__ = ABCMeta
+ class C(metaclass=ABCMeta):
@abstractproperty
def my_abstract_property(self):
...
@@ -53,8 +84,7 @@ class abstractproperty(property):
This defines a read-only property; you can also define a read-write
abstract property using the 'long' form of property declaration:
- class C:
- __metaclass__ = ABCMeta
+ class C(metaclass=ABCMeta):
def getx(self): ...
def setx(self, value): ...
x = abstractproperty(getx, setx)
@@ -84,11 +114,11 @@ class ABCMeta(type):
_abc_invalidation_counter = 0
def __new__(mcls, name, bases, namespace):
- cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
+ cls = super().__new__(mcls, name, bases, namespace)
# Compute set of abstract method names
- abstracts = set(name
+ abstracts = {name
for name, value in namespace.items()
- if getattr(value, "__isabstractmethod__", False))
+ if getattr(value, "__isabstractmethod__", False)}
for base in bases:
for name in getattr(base, "__abstractmethods__", set()):
value = getattr(cls, name, None)
@@ -104,7 +134,7 @@ class ABCMeta(type):
def register(cls, subclass):
"""Register a virtual subclass of an ABC."""
- if not isinstance(subclass, (type, types.ClassType)):
+ if not isinstance(subclass, type):
raise TypeError("Can only register classes")
if issubclass(subclass, cls):
return # Already a subclass
@@ -118,32 +148,28 @@ class ABCMeta(type):
def _dump_registry(cls, file=None):
"""Debug helper to print the ABC registry."""
- print >> file, "Class: %s.%s" % (cls.__module__, cls.__name__)
- print >> file, "Inv.counter: %s" % ABCMeta._abc_invalidation_counter
+ print("Class: %s.%s" % (cls.__module__, cls.__name__), file=file)
+ print("Inv.counter: %s" % ABCMeta._abc_invalidation_counter, file=file)
for name in sorted(cls.__dict__.keys()):
if name.startswith("_abc_"):
value = getattr(cls, name)
- print >> file, "%s: %r" % (name, value)
+ print("%s: %r" % (name, value), file=file)
def __instancecheck__(cls, instance):
"""Override for isinstance(instance, cls)."""
- # Inline the cache checking when it's simple.
- subclass = getattr(instance, '__class__', None)
- if subclass is not None and subclass in cls._abc_cache:
+ # Inline the cache checking
+ subclass = instance.__class__
+ if subclass in cls._abc_cache:
return True
subtype = type(instance)
- # Old-style instances
- if subtype is _InstanceType:
- subtype = subclass
- if subtype is subclass or subclass is None:
+ if subtype is subclass:
if (cls._abc_negative_cache_version ==
ABCMeta._abc_invalidation_counter and
- subtype in cls._abc_negative_cache):
+ subclass in cls._abc_negative_cache):
return False
# Fall back to the subclass check.
- return cls.__subclasscheck__(subtype)
- return (cls.__subclasscheck__(subclass) or
- cls.__subclasscheck__(subtype))
+ return cls.__subclasscheck__(subclass)
+ return any(cls.__subclasscheck__(c) for c in {subclass, subtype})
def __subclasscheck__(cls, subclass):
"""Override for issubclass(subclass, cls)."""