Andrew Barnert wrote: > 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/2OZBPQ... > > Code of Conduct: http://python.org/psf/codeofconduct/ > >
Maybe so because I found a limitation with my code spike. Calling `register_explicit_only` doesn't bust the cache, so if `issubclass(<myclass>, TotallyOrderable)` is called prior to calling `TotallyOrderable.register_explicit_only(<myclass>)`, then it doesn't have any effect. Perhaps, that's also not a big deal as a documented limitation though? _______________________________________________ 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/NXM3ODHVPDBB2F26A2AFGMAPXG6GHTGK/ Code of Conduct: http://python.org/psf/codeofconduct/