msg195150 - (view) |
Author: Christian Heimes (christian.heimes) *  |
Date: 2013-08-14 13:13 |
ABCs are missing one important introspection feature. They have no API to get registered virtual subclasses. The patch implements a new method get_virtual_subclasses(recurse=False). ABC.get_virtual_subclasses() returns the direct virtual subclasses of an ABC. ABC.get_virtual_subclasses(recuse=True) also takes subclasses of the ABC as well as subclasses of registered virtual classes into account. Example: >>> import numbers >>> numbers.Number.get_virtual_subclasses() set() >>> numbers.Number.get_virtual_subclasses(True) {<class 'float'>, <class 'bool'>, <class 'int'>, <class 'complex'>} >>> numbers.Integral.get_virtual_subclasses() {<class 'int'>} >>> numbers.Integral.get_virtual_subclasses(True) {<class 'int'>, <class 'bool'>} |
|
|
msg195151 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2013-08-14 13:17 |
I'm not sure "recurse" is a relevant distinction here. A subclass of a subclass is still a subclass. "Virtual" subclasses should not be different. At the very least, if "recurse" is kept, I would expect it to be True by default. |
|
|
msg195152 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2013-08-14 13:22 |
Another problem is what happens when an implementation uses non-"virtual" inheritance: >>> issubclass(collections.UserDict, collections.abc.Mapping) True >>> collections.UserDict in collections.abc.Mapping.get_virtual_subclasses(True) False IOW, I think this get_virtual_subclasses() proposal is too low-level to be commonly useful, since it depends on implementation details (whether subclassing is direct or not, whether registering is implicit or explicit). |
|
|
msg195155 - (view) |
Author: Christian Heimes (christian.heimes) *  |
Date: 2013-08-14 13:39 |
It's called get_VIRTUAL_subclasses() for a reason. You can get the real subclasses of an ABC with standard tool, e.g. recurse into __subclasses__(). For virtual subclasses you have to deal with the internals like _abc_registry. I could implement all four cases: recurse True/False, only virtual True/False. But I prefer not to do so. |
|
|
msg195158 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2013-08-14 13:47 |
> It's called get_VIRTUAL_subclasses() for a reason. You can get the > real subclasses of an ABC with standard tool, e.g. recurse into > __subclasses__(). What use case are you trying to solve? If I want to find out all classes which implement an ABC, I don't care whether they implement it "virtually" or not. OTOH, I do care that the results are stable and reliable, i.e. that they don't change when someone changes from virtual inheritance to real inheritance as an implementation detail. For comparison, issubclass() doesn't make a difference between real and virtual subclasses, or direct and recursive. > For virtual subclasses you have to deal with the > internals like _abc_registry. I could implement all four cases: > recurse True/False, only virtual True/False. I don't care about all four cases. What I'm saying is that only "recurse=True, only virtual=False" makes sense from an user's POV. |
|
|
msg195182 - (view) |
Author: Christian Heimes (christian.heimes) *  |
Date: 2013-08-14 15:47 |
I like to do something similar to marker interfaces [1] with ABCs. For introspection and documentation I need a way to get all non-abstract classes that are implemented by an ABC. How about I change the implementation to get_subclasses(direct=False) to return all virtual and real subclasses of an ABC? I can filter out abstract types with inspect.isabstract() later. [1] http://www.muthukadan.net/docs/zca.html#marker-interfaces |
|
|
msg195183 - (view) |
Author: Antoine Pitrou (pitrou) *  |
Date: 2013-08-14 15:54 |
> I like to do something similar to marker interfaces [1] with ABCs. > For introspection and documentation I need a way to get all > non-abstract classes that are implemented by an ABC. You mean that implement an ABC? But you also need to return real subclasses that implement the ABC (e.g. UserDict in the example above). > How about I change the implementation to get_subclasses(direct=False) > to return all virtual and real subclasses of an ABC? I can filter > out abstract types with inspect.isabstract() later. Sounds ok. |
|
|
msg404485 - (view) |
Author: Christian Heimes (christian.heimes) *  |
Date: 2021-10-20 16:11 |
My feature request has been around for 8 years without any progress. I don't even recall why I needed the feature in the first place. |
|
|