On Mar 5, 2020, at 11:05, Steve Jorgensen <ste...@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-le...@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/2OZBPQPYIFFG2E6BS2EYLDJF2QP5FRTG/ > Code of Conduct: http://python.org/psf/codeofconduct/ _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@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/ACTYQZOPO7SH4AXLGTWQIVRBJ6M6ZBHB/ Code of Conduct: http://python.org/psf/codeofconduct/