
On Mar 5, 2020, at 11:05, Steve Jorgensen stevej@stevej.name wrote:
Steve Jorgensen wrote:
Steve Jorgensen wrote:
<snip> > The problem I came up with trying to spike out my > proposal last night is that there > doesn't seem to be anyway to implement it without creating infinite recursion in the > issublcass call.
Is this something we should be looking to add to the ABC mechanism in general?
Would a way to “unregister” classes that would be implicitly accepted be simpler than a way to “register_explicit_only” classes so they skip the implicit test?
If I make Orderable a real or virtual subclass of ProtoOrderable and Orderable's __subclasshook__ or metaclass __subclasscheck__ (I tried both ways) tries to check whether C is a subclass of ProtoOrderable, then an infinite recursion occurs. It wasn't immediately obvious to me why that is the case, but when I thought about it deeply, I can see why that must happen. An alternative that I thought about previously but seems very smelly to me for several reasons is to have both Orderable and NonOrderable ABCs. In that case, what should be done to prevent a class from being both orderable and non-orderable or figure out which should take precedence in that case? As a meta-solution (wild-assed idea) what if metaclass registration could accept keyword arguments, similar to passing keyword arguments to a class definition? That way, a single ABC (ProtoOrderable or whatever better name) could be a real or virtual subclass that is explicitly orderable or non-orderable depending on orderable=<True/False>. I have been unable to implement the class hierarchy that I proposed, and I think
I've determined that it's just not a practical fit with how the virtual bas class mechanism works, so… Maybe just a single TotalOrdered or TotalOrderable ABC with a register_explicit_only method. The __subclasshook__ method would skip the rich comparison methods check and return NotImplemented for any class registered using register_explicit_only (or any of its true subclasses). The only weird edge case in the above is that is someone registers another ABC using TotalOrdered.register_explicit_only and uses that as a virtual base class of something else, the register_explicit_only registration will not apply to the virtual subclass. I'm thinking that's completely acceptable as a known limitation if documented?
Code spike of that idea:
from abc import ABCMeta from weakref import WeakSet class TotallyOrderable(metaclass=ABCMeta): _explicit_only_registry = WeakSet() @classmethod def register_explicit_only(cls, C): if cls is not TotallyOrderable: raise NotImplementedError( f"{cls.__name__} does not implement 'register_explicit_only'") cls._explicit_only_registry.add(C) @classmethod def __subclasshook__(cls, C): if cls is not TotallyOrderable: return NotImplemented for B in C.__mro__: if B in cls._explicit_only_registry: return NotImplemented return cls._check_overrides_rich_comparison_methods(C) @classmethod def _check_overrides_rich_comparison_methods(cls, C): mro = C.__mro__ for method in ('__lt__', '__le__', '__gt__', '__ge__'): for B in mro: if B is not object and method in B.__dict__: if B.__dict__[method] is None: return NotImplemented break else: return NotImplemented return True
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2OZBPQ... Code of Conduct: http://python.org/psf/codeofconduct/