annotate Lib/abc.py @ 58765:2ba7677bfa95 legacy-trunk

testCopysign was defined twice in test_math; combine the definitions
author Mark Dickinson <dickinsm@gmail.com>
date Sat, 06 Feb 2010 23:11:25 +0000
parents 9575ce0db204
children 6710a43f193f d92878bba7bb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 # Copyright 2007 Google, Inc. All Rights Reserved.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
2 # Licensed to PSF under a Contributor Agreement.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
3
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
4 """Abstract Base Classes (ABCs) according to PEP 3119."""
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
5
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
6
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 def abstractmethod(funcobj):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
8 """A decorator indicating abstract methods.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
9
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 Requires that the metaclass is ABCMeta or derived from it. A
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
11 class that has a metaclass derived from ABCMeta cannot be
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
12 instantiated unless all of its abstract methods are overridden.
53736
3088d2ebf7be Merged revisions 72278 via svnmerge from
Walter Dörwald <walter@livinglogic.de>
parents: 51927
diff changeset
13 The abstract methods can be called using any of the normal
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 'super' call mechanisms.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
15
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
16 Usage:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
17
51927
2a458106afbf Merged revisions 70078 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48957
diff changeset
18 class C:
2a458106afbf Merged revisions 70078 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48957
diff changeset
19 __metaclass__ = ABCMeta
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 @abstractmethod
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
21 def my_abstract_method(self, ...):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 ...
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
23 """
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 funcobj.__isabstractmethod__ = True
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 return funcobj
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
26
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
27
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
28 class abstractproperty(property):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 """A decorator indicating abstract properties.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
30
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 Requires that the metaclass is ABCMeta or derived from it. A
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
32 class that has a metaclass derived from ABCMeta cannot be
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 instantiated unless all of its abstract properties are overridden.
53736
3088d2ebf7be Merged revisions 72278 via svnmerge from
Walter Dörwald <walter@livinglogic.de>
parents: 51927
diff changeset
34 The abstract properties can be called using any of the normal
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 'super' call mechanisms.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
36
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 Usage:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
38
51927
2a458106afbf Merged revisions 70078 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48957
diff changeset
39 class C:
2a458106afbf Merged revisions 70078 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48957
diff changeset
40 __metaclass__ = ABCMeta
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 @abstractproperty
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 def my_abstract_property(self):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 ...
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
44
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 This defines a read-only property; you can also define a read-write
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 abstract property using the 'long' form of property declaration:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
47
51927
2a458106afbf Merged revisions 70078 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48957
diff changeset
48 class C:
2a458106afbf Merged revisions 70078 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48957
diff changeset
49 __metaclass__ = ABCMeta
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 def getx(self): ...
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
51 def setx(self, value): ...
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
52 x = abstractproperty(getx, setx)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 """
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 __isabstractmethod__ = True
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
55
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
56
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 class ABCMeta(type):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
58
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 """Metaclass for defining Abstract Base Classes (ABCs).
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
60
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
61 Use this metaclass to create an ABC. An ABC can be subclassed
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
62 directly, and then acts as a mix-in class. You can also register
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
63 unrelated concrete classes (even built-in classes) and unrelated
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 ABCs as 'virtual subclasses' -- these and their descendants will
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
65 be considered subclasses of the registering ABC by the built-in
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 issubclass() function, but the registering ABC won't show up in
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 their MRO (Method Resolution Order) nor will method
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
68 implementations defined by the registering ABC be callable (not
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 even via super()).
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
70
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
71 """
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
72
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 # A global counter that is incremented each time a class is
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
74 # registered as a virtual subclass of anything. It forces the
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 # negative cache to be cleared before its next use.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 _abc_invalidation_counter = 0
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
77
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
78 def __new__(mcls, name, bases, namespace):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
79 cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 # Compute set of abstract method names
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 abstracts = set(name
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 for name, value in namespace.items()
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
83 if getattr(value, "__isabstractmethod__", False))
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 for base in bases:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
85 for name in getattr(base, "__abstractmethods__", set()):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
86 value = getattr(cls, name, None)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
87 if getattr(value, "__isabstractmethod__", False):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
88 abstracts.add(name)
45543
6592e5a90c2c Move abc._Abstract into object by adding a new flag Py_TPFLAGS_IS_ABSTRACT,
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 45310
diff changeset
89 cls.__abstractmethods__ = frozenset(abstracts)
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
90 # Set up inheritance registry
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
91 cls._abc_registry = set()
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
92 cls._abc_cache = set()
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
93 cls._abc_negative_cache = set()
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
94 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
95 return cls
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
96
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
97 def register(cls, subclass):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
98 """Register a virtual subclass of an ABC."""
58531
9575ce0db204 raise a clear TypeError when trying to register a non-class
Benjamin Peterson <benjamin@python.org>
parents: 53736
diff changeset
99 if not isinstance(subclass, type):
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
100 raise TypeError("Can only register classes")
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
101 if issubclass(subclass, cls):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 return # Already a subclass
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
103 # Subtle: test for cycles *after* testing for "already a subclass";
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
104 # this means we allow X.register(X) and interpret it as a no-op.
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
105 if issubclass(cls, subclass):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
106 # This would create a cycle, which is bad for the algorithm below
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
107 raise RuntimeError("Refusing to create an inheritance cycle")
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
108 cls._abc_registry.add(subclass)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 ABCMeta._abc_invalidation_counter += 1 # Invalidate negative cache
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
110
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
111 def _dump_registry(cls, file=None):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
112 """Debug helper to print the ABC registry."""
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
113 print >> file, "Class: %s.%s" % (cls.__module__, cls.__name__)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
114 print >> file, "Inv.counter: %s" % ABCMeta._abc_invalidation_counter
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
115 for name in sorted(cls.__dict__.keys()):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
116 if name.startswith("_abc_"):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
117 value = getattr(cls, name)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
118 print >> file, "%s: %r" % (name, value)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
119
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
120 def __instancecheck__(cls, instance):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
121 """Override for isinstance(instance, cls)."""
45788
4d39d4a6a9db Make isinstance(OldstyleClass, NewstyleClass) return False instead of raising
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 45543
diff changeset
122 # Inline the cache checking when it's simple.
4d39d4a6a9db Make isinstance(OldstyleClass, NewstyleClass) return False instead of raising
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 45543
diff changeset
123 subclass = getattr(instance, '__class__', None)
45310
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
124 if subclass in cls._abc_cache:
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
125 return True
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
126 subtype = type(instance)
45788
4d39d4a6a9db Make isinstance(OldstyleClass, NewstyleClass) return False instead of raising
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 45543
diff changeset
127 if subtype is subclass or subclass is None:
45310
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
128 if (cls._abc_negative_cache_version ==
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
129 ABCMeta._abc_invalidation_counter and
45788
4d39d4a6a9db Make isinstance(OldstyleClass, NewstyleClass) return False instead of raising
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 45543
diff changeset
130 subtype in cls._abc_negative_cache):
45310
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
131 return False
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
132 # Fall back to the subclass check.
45788
4d39d4a6a9db Make isinstance(OldstyleClass, NewstyleClass) return False instead of raising
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 45543
diff changeset
133 return cls.__subclasscheck__(subtype)
45310
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
134 return (cls.__subclasscheck__(subclass) or
c5205587b2ab Working on issue #1762: Brought
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 44551
diff changeset
135 cls.__subclasscheck__(subtype))
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
136
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
137 def __subclasscheck__(cls, subclass):
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
138 """Override for issubclass(subclass, cls)."""
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
139 # Check cache
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
140 if subclass in cls._abc_cache:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
141 return True
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
142 # Check negative cache; may have to invalidate
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
143 if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
144 # Invalidate the negative cache
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
145 cls._abc_negative_cache = set()
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
146 cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
147 elif subclass in cls._abc_negative_cache:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
148 return False
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
149 # Check the subclass hook
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
150 ok = cls.__subclasshook__(subclass)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
151 if ok is not NotImplemented:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
152 assert isinstance(ok, bool)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
153 if ok:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
154 cls._abc_cache.add(subclass)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
155 else:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
156 cls._abc_negative_cache.add(subclass)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
157 return ok
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
158 # Check if it's a direct subclass
44551
f9c950e8f2e0 Fix issue 1747: allow classic classes to be checked for being subclasses of
Jeffrey Yasskin <jyasskin@gmail.com>
parents: 43958
diff changeset
159 if cls in getattr(subclass, '__mro__', ()):
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
160 cls._abc_cache.add(subclass)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
161 return True
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
162 # Check if it's a subclass of a registered class (recursive)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
163 for rcls in cls._abc_registry:
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
164 if issubclass(subclass, rcls):
48957
4da4f9679672 Issue 3747: Fix caching in ABCMeta.__subclasscheck__ (R: Georg Brandl)
Nick Coghlan <ncoghlan@gmail.com>
parents: 45788
diff changeset
165 cls._abc_cache.add(subclass)
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
166 return True
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
167 # Check if it's a subclass of a subclass (recursive)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
168 for scls in cls.__subclasses__():
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
169 if issubclass(subclass, scls):
48957
4da4f9679672 Issue 3747: Fix caching in ABCMeta.__subclasscheck__ (R: Georg Brandl)
Nick Coghlan <ncoghlan@gmail.com>
parents: 45788
diff changeset
170 cls._abc_cache.add(subclass)
43327
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
171 return True
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
172 # No dice; update negative cache
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
173 cls._abc_negative_cache.add(subclass)
33817da53fd7 Patch # 1026 by Benjamin Aranguren (with Alex Martelli):
Guido van Rossum <guido@python.org>
parents:
diff changeset
174 return False