Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(168240)

Side by Side Diff: Lib/abc.py

Issue 11610: Improving property to accept abstract methods
Patch Set: Created 8 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Doc/library/abc.rst ('k') | Lib/test/test_abc.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2007 Google, Inc. All Rights Reserved. 1 # Copyright 2007 Google, Inc. All Rights Reserved.
2 # Licensed to PSF under a Contributor Agreement. 2 # Licensed to PSF under a Contributor Agreement.
3 3
4 """Abstract Base Classes (ABCs) according to PEP 3119.""" 4 """Abstract Base Classes (ABCs) according to PEP 3119."""
5 5
6 from _weakrefset import WeakSet 6 from _weakrefset import WeakSet
7 7
8 def abstractmethod(funcobj): 8 def abstractmethod(funcobj):
9 """A decorator indicating abstract methods. 9 """A decorator indicating abstract methods.
10 10
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 Requires that the metaclass is ABCMeta or derived from it. A 71 Requires that the metaclass is ABCMeta or derived from it. A
72 class that has a metaclass derived from ABCMeta cannot be 72 class that has a metaclass derived from ABCMeta cannot be
73 instantiated unless all of its abstract properties are overridden. 73 instantiated unless all of its abstract properties are overridden.
74 The abstract properties can be called using any of the normal 74 The abstract properties can be called using any of the normal
75 'super' call mechanisms. 75 'super' call mechanisms.
76 76
77 Usage: 77 Usage:
78 78
79 class C(metaclass=ABCMeta): 79 class C(metaclass=ABCMeta):
80 @abstractproperty 80 @abstractproperty
81 def my_abstract_property(self): 81 @abstractmethod
gvanrossum 2011/03/21 03:25:07 You can't just change the semantics of @abstractpr
dsdale24 2011/03/21 13:09:06 The patch itself is actually completely backward-c
82 def x(self):
83 ...
84 @x.setter
dsdale24 2011/03/21 13:09:06 I forgot to insert an @abstractmethod after @x.set
85 def x(self, val):
82 ... 86 ...
83 87
84 This defines a read-only property; you can also define a read-write 88 You can also define an abstract property using the 'long' form of
85 abstract property using the 'long' form of property declaration: 89 property declaration:
86 90
87 class C(metaclass=ABCMeta): 91 class D(metaclass=ABCMeta):
88 def getx(self): ... 92 @abstractmethod
89 def setx(self, value): ... 93 def getx(self):
94 ...
95 @abstractmethod
96 def setx(self, value):
97 ...
90 x = abstractproperty(getx, setx) 98 x = abstractproperty(getx, setx)
99
100 Subclasses will not be instantiable until the property definition
101 is fully concrete:
102
103 class E(C):
104 @C.x.getter
105 def x(self):
106 ...
107
108 class F(E):
109 @D.x.setter
110 def x(self, val):
111 ...
112
113 In this example, 'E' is not instantiable, because the 'x' setter
114 is abstract. 'F.x' is a regular property , and 'F' is instantiable.
91 """ 115 """
116
92 __isabstractmethod__ = True 117 __isabstractmethod__ = True
118
119 def getter(self, fun):
120 "Descriptor to change the getter on a property"
121 return abstractproperty.create_property(fun, self.fset, self.fdel,
dsdale24 2011/03/22 22:45:04 I think the calls in getter, setter, deleter need
122 self.__doc__)
123
124 def setter(self, fun):
125 "Descriptor to change the setter on a property"
126 return abstractproperty.create_property(self.fget, fun, self.fdel,
127 self.__doc__)
128
129 def deleter(self, fun):
130 "Descriptor to change the deleter on a property"
131 return abstractproperty.create_property(self.fget, self.fset, fun,
132 self.__doc__)
133
134 @classmethod
135 def create_property(cls, fget=None, fset=None, fdel=None, doc=None):
136 for f in (fget, fset, fdel):
137 if (f is not None) and getattr(f, '__isabstractmethod__', False):
138 # has abstract methods, return an abstract property
139 return cls(fget, fset, fdel, doc)
140 # does not have abstract methods, return a concrete property
141 return property(fget, fset, fdel, doc)
93 142
94 143
95 class ABCMeta(type): 144 class ABCMeta(type):
96 145
97 """Metaclass for defining Abstract Base Classes (ABCs). 146 """Metaclass for defining Abstract Base Classes (ABCs).
98 147
99 Use this metaclass to create an ABC. An ABC can be subclassed 148 Use this metaclass to create an ABC. An ABC can be subclassed
100 directly, and then acts as a mix-in class. You can also register 149 directly, and then acts as a mix-in class. You can also register
101 unrelated concrete classes (even built-in classes) and unrelated 150 unrelated concrete classes (even built-in classes) and unrelated
102 ABCs as 'virtual subclasses' -- these and their descendants will 151 ABCs as 'virtual subclasses' -- these and their descendants will
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 cls._abc_cache.add(subclass) 255 cls._abc_cache.add(subclass)
207 return True 256 return True
208 # Check if it's a subclass of a subclass (recursive) 257 # Check if it's a subclass of a subclass (recursive)
209 for scls in cls.__subclasses__(): 258 for scls in cls.__subclasses__():
210 if issubclass(subclass, scls): 259 if issubclass(subclass, scls):
211 cls._abc_cache.add(subclass) 260 cls._abc_cache.add(subclass)
212 return True 261 return True
213 # No dice; update negative cache 262 # No dice; update negative cache
214 cls._abc_negative_cache.add(subclass) 263 cls._abc_negative_cache.add(subclass)
215 return False 264 return False
OLDNEW
« no previous file with comments | « Doc/library/abc.rst ('k') | Lib/test/test_abc.py » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+