blob: 515ba08f23cadab56bf009953eb9f7ace3f6ebdb [file] [log] [blame]
Guido van Rossumb5591132007-09-10 22:36:02 +00001# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
4"""Abstract Base Classes (ABCs) according to PEP 3119."""
5
Benjamin Petersonbde67df2010-06-22 18:09:02 +00006import types
7
Guido van Rossumb5591132007-09-10 22:36:02 +00008
Florent Xicluna47627d52010-03-08 15:20:28 +00009# Instance of old-style class
10class _C: pass
11_InstanceType = type(_C())
12
13
Guido van Rossumb5591132007-09-10 22:36:02 +000014def abstractmethod(funcobj):
15 """A decorator indicating abstract methods.
16
17 Requires that the metaclass is ABCMeta or derived from it. A
18 class that has a metaclass derived from ABCMeta cannot be
19 instantiated unless all of its abstract methods are overridden.
Walter Dörwald28277092009-05-04 16:03:03 +000020 The abstract methods can be called using any of the normal
Guido van Rossumb5591132007-09-10 22:36:02 +000021 'super' call mechanisms.
22
23 Usage:
24
Georg Brandlbcf7bf32009-02-28 21:33:10 +000025 class C:
26 __metaclass__ = ABCMeta
Guido van Rossumb5591132007-09-10 22:36:02 +000027 @abstractmethod
28 def my_abstract_method(self, ...):
29 ...
30 """
31 funcobj.__isabstractmethod__ = True
32 return funcobj
33
34
35class abstractproperty(property):
36 """A decorator indicating abstract properties.
37
38 Requires that the metaclass is ABCMeta or derived from it. A
39 class that has a metaclass derived from ABCMeta cannot be
40 instantiated unless all of its abstract properties are overridden.
Walter Dörwald28277092009-05-04 16:03:03 +000041 The abstract properties can be called using any of the normal
Guido van Rossumb5591132007-09-10 22:36:02 +000042 'super' call mechanisms.
43
44 Usage:
45
Georg Brandlbcf7bf32009-02-28 21:33:10 +000046 class C:
47 __metaclass__ = ABCMeta
Guido van Rossumb5591132007-09-10 22:36:02 +000048 @abstractproperty
49 def my_abstract_property(self):
50 ...
51
52 This defines a read-only property; you can also define a read-write
53 abstract property using the 'long' form of property declaration:
54
Georg Brandlbcf7bf32009-02-28 21:33:10 +000055 class C:
56 __metaclass__ = ABCMeta
Guido van Rossumb5591132007-09-10 22:36:02 +000057 def getx(self): ...
58 def setx(self, value): ...
59 x = abstractproperty(getx, setx)
60 """
61 __isabstractmethod__ = True
62
63
Guido van Rossumb5591132007-09-10 22:36:02 +000064class ABCMeta(type):
65
66 """Metaclass for defining Abstract Base Classes (ABCs).
67
68 Use this metaclass to create an ABC. An ABC can be subclassed
69 directly, and then acts as a mix-in class. You can also register
70 unrelated concrete classes (even built-in classes) and unrelated
71 ABCs as 'virtual subclasses' -- these and their descendants will
72 be considered subclasses of the registering ABC by the built-in
73 issubclass() function, but the registering ABC won't show up in
74 their MRO (Method Resolution Order) nor will method
75 implementations defined by the registering ABC be callable (not
76 even via super()).
77
78 """
79
80 # A global counter that is incremented each time a class is
81 # registered as a virtual subclass of anything. It forces the
82 # negative cache to be cleared before its next use.
83 _abc_invalidation_counter = 0
84
85 def __new__(mcls, name, bases, namespace):
Guido van Rossumb5591132007-09-10 22:36:02 +000086 cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
87 # Compute set of abstract method names
88 abstracts = set(name
89 for name, value in namespace.items()
90 if getattr(value, "__isabstractmethod__", False))
91 for base in bases:
92 for name in getattr(base, "__abstractmethods__", set()):
93 value = getattr(cls, name, None)
94 if getattr(value, "__isabstractmethod__", False):
95 abstracts.add(name)
Jeffrey Yasskin960b9b72008-02-28 04:45:36 +000096 cls.__abstractmethods__ = frozenset(abstracts)
Guido van Rossumb5591132007-09-10 22:36:02 +000097 # Set up inheritance registry
98 cls._abc_registry = set()
99 cls._abc_cache = set()
100 cls._abc_negative_cache = set()
101 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
102 return cls
103
104 def register(cls, subclass):
105 """Register a virtual subclass of an ABC."""
Benjamin Petersonbde67df2010-06-22 18:09:02 +0000106 if not isinstance(subclass, (type, types.ClassType)):
Guido van Rossumb5591132007-09-10 22:36:02 +0000107 raise TypeError("Can only register classes")
108 if issubclass(subclass, cls):
109 return # Already a subclass
110 # Subtle: test for cycles *after* testing for "already a subclass";
111 # this means we allow X.register(X) and interpret it as a no-op.
112 if issubclass(cls, subclass):
113 # This would create a cycle, which is bad for the algorithm below
114 raise RuntimeError("Refusing to create an inheritance cycle")
115 cls._abc_registry.add(subclass)
116 ABCMeta._abc_invalidation_counter += 1 # Invalidate negative cache
117
118 def _dump_registry(cls, file=None):
119 """Debug helper to print the ABC registry."""
120 print >> file, "Class: %s.%s" % (cls.__module__, cls.__name__)
121 print >> file, "Inv.counter: %s" % ABCMeta._abc_invalidation_counter
122 for name in sorted(cls.__dict__.keys()):
123 if name.startswith("_abc_"):
124 value = getattr(cls, name)
125 print >> file, "%s: %r" % (name, value)
126
127 def __instancecheck__(cls, instance):
128 """Override for isinstance(instance, cls)."""
Jeffrey Yasskinb9e15f72008-03-17 16:31:21 +0000129 # Inline the cache checking when it's simple.
130 subclass = getattr(instance, '__class__', None)
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000131 if subclass in cls._abc_cache:
132 return True
133 subtype = type(instance)
Florent Xicluna47627d52010-03-08 15:20:28 +0000134 # Old-style instances
135 if subtype is _InstanceType:
136 subtype = subclass
Jeffrey Yasskinb9e15f72008-03-17 16:31:21 +0000137 if subtype is subclass or subclass is None:
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000138 if (cls._abc_negative_cache_version ==
139 ABCMeta._abc_invalidation_counter and
Jeffrey Yasskinb9e15f72008-03-17 16:31:21 +0000140 subtype in cls._abc_negative_cache):
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000141 return False
142 # Fall back to the subclass check.
Jeffrey Yasskinb9e15f72008-03-17 16:31:21 +0000143 return cls.__subclasscheck__(subtype)
Jeffrey Yasskin57bd60b2008-02-13 17:58:04 +0000144 return (cls.__subclasscheck__(subclass) or
145 cls.__subclasscheck__(subtype))
Guido van Rossumb5591132007-09-10 22:36:02 +0000146
147 def __subclasscheck__(cls, subclass):
148 """Override for issubclass(subclass, cls)."""
149 # Check cache
150 if subclass in cls._abc_cache:
151 return True
152 # Check negative cache; may have to invalidate
153 if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
154 # Invalidate the negative cache
155 cls._abc_negative_cache = set()
156 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
157 elif subclass in cls._abc_negative_cache:
158 return False
159 # Check the subclass hook
160 ok = cls.__subclasshook__(subclass)
161 if ok is not NotImplemented:
162 assert isinstance(ok, bool)
163 if ok:
164 cls._abc_cache.add(subclass)
165 else:
166 cls._abc_negative_cache.add(subclass)
167 return ok
168 # Check if it's a direct subclass
Jeffrey Yasskinfd1c2452008-01-07 06:09:40 +0000169 if cls in getattr(subclass, '__mro__', ()):
Guido van Rossumb5591132007-09-10 22:36:02 +0000170 cls._abc_cache.add(subclass)
171 return True
172 # Check if it's a subclass of a registered class (recursive)
173 for rcls in cls._abc_registry:
174 if issubclass(subclass, rcls):
Nick Coghlan91ae3ea2008-09-02 10:14:47 +0000175 cls._abc_cache.add(subclass)
Guido van Rossumb5591132007-09-10 22:36:02 +0000176 return True
177 # Check if it's a subclass of a subclass (recursive)
178 for scls in cls.__subclasses__():
179 if issubclass(subclass, scls):
Nick Coghlan91ae3ea2008-09-02 10:14:47 +0000180 cls._abc_cache.add(subclass)
Guido van Rossumb5591132007-09-10 22:36:02 +0000181 return True
182 # No dice; update negative cache
183 cls._abc_negative_cache.add(subclass)
184 return False