msg306433 - (view) |
Author: Alex Corcoles (Alex Corcoles) |
Date: 2017-11-17 12:35 |
Hi, $ python3 Python 3.5.3 (default, Jan 19 2017, 14:11:04) >>> import abc >>> class Foo(abc.ABC): ... pass ... >>> Foo() <__main__.Foo object at 0x7f253e6dcb38> I think declaring a class as ABC without declaring any abstract method is an error. I've tried searching if this was already discussed, but did not find it. Maybe it is related to https://bugs.python.org/issue9731 Cheers, Álex |
|
|
msg306437 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2017-11-17 14:12 |
No, you could create an ABC whose only purpose was to be a target of register calls. As with the issue you reference, this is something better implemented in a linter. I'll leave this open for at least one other dev to concur and close, though. |
|
|
msg306449 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2017-11-17 17:50 |
I concur. |
|
|
msg306451 - (view) |
Author: Alex Corcoles (Alex Corcoles) |
Date: 2017-11-17 18:04 |
Are you referring to something akin to Java's marker interfaces? That is, a class with no methods which you inherit from just for semantic meaning (e.g. Java's serializable interface that you implement to indicate that the class is designed for pickling). In that case, I suppose the docs could mention this clearly so this is more "discoverable" to noobs like me and prevent further issues like this (I think mine wasn't an unreasonable expectation). In any case, it's a minor point and I don't feel I have enough authority to discuss this topic- it's fine to close this. |
|
|
msg306453 - (view) |
Author: R. David Murray (r.david.murray) *  |
Date: 2017-11-17 18:39 |
The docs start out with "as outlined in PEP 3119; see the PEP for why this was added to Python". I think it would be a good doc enhancement request to extract the motivation and other description out of that pep and put it in the main docs in a suitable form, and make sure this point is included. We used to just treat the peps as extensions of the documentation, but we've found over time that it is better to actually move the important parts of the text into the main docs, since the actual implementation and sometimes even how we talk about the feature tends to evolve away from the original PEP over time. |
|
|
msg306455 - (view) |
Author: Raymond Hettinger (rhettinger) *  |
Date: 2017-11-17 19:45 |
FWIW, I should have add a bit more explanation. The logic for ABCs instantiation is roughly: if any(method.is_abstract() for method in dir(cls)): raise TypeError('I refuse to instantiate') inst = instantiate(cls) The edge case for any() is to default to False for an empty input sequence and this logic applies to ABCs as well. Alternatively, you can think of the it as using all() style logic, "instantiate this class only if all of the methods are non-abstract even if the class has no methods at all". The edge case for all() is that it returns True for an empty input. Another way of describing the logic is that the normal case for instantiating a class is to create an instance unless there is still work to be done (as evidenced by the presence of one or more abstract methods). The abstract methods are essentially a todo list for subclassers. If there are no open todos (even if there were never any todos), instantiation can go forward -- "You can't build that building until you have all the permits, but there are no permit requirements in this case, so go ahead with the construction." |
|
|