Hello,

This to thread has gotten no responses at all, so:
Ping!

On Sun, Aug 22, 2021, 3:16 PM Finn Mason <finnjavie...@gmail.com> wrote:

> Sorry, the formatting was terrible. I copy and pasted it from the original
> issue without really thinking about it.
> Here's the same thing, but actually readable:
>
> In _collections_abc.py is a private function titled _check_methods(). It
> takes a class and a number of method names (as strings), checks if the
> class has all of the methods, and returns NotImplemented if any are
> missing. The code is below:
>
>  def _check_methods(C, *methods):
>      mro = C.__mro__
>      for method in methods:
>         for B in mro:
>              if method in B.__dict__:
>                  if B.__dict__[method] is None:
>                      return NotImplemented
>                      break
>              else:
>                      return NotImplemented
>      return True
>
> This is an incredibly convenient function (referred to as check_methods
> here on out) for creating abstract base classes, and is much simpler than
> using hasattr for each method you want to check. For example:
>
>  from abc import ABCMeta
>  # Without check_methods
>  class A(metaclass=ABCMeta):
>      @classmethod
>      def __subclasshook__(cls, subclass):
>          return (hasattr(subclass, 'foo') and
>          callable(subclass.foo) and
>          hasattr(subclass, 'bar') and
>          callable(subclass.bar) or
>          NotImplemented)
>
>  # With check_methods
>  class B(metaclass=ABCMeta):
>      @classmethod
>      def __subclasshook(cls, subclass):
>          return check_methods(subclass, 'foo', 'bar')
>
> This would be a great function to add to the standard lib, perhaps in the
> abc module. One problem with check_methods() as defined in
> _collections_abc.py is that it doesn't check if the name is callable. Also,
> type hints and more readable variables may be desirable. The final code, if
> implemented, may look something like this:
>
>  # In imports section: from typing import Literal
>  def check_methods(Class: type, *methods: str) -> Literal[True,
> NotImplemented]:
>      """Check if class `Class` has methods `methods`."""
>      mro = Class.__mro__
>      for method in methods:
>          for Base in mro:
>              if (attr := getattr(Base, method, None)) is not None:
>                  if not callable(attr):
>                      return NotImplemented
>                      break
>                  else:
>                      return NotImplemented
>      return True
>
> Again, this would be a great function to add to the `abc` module or a
> similar one. I've proposed this in issue 44941.
> Another possible implementation may be similar to a dataclass that
> implements __subclasshook__ for you with the desired method checks.
>
> --
> Finn
>
_______________________________________________
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/GCOXW4CJUDRWFRYGTAU2LJO5RUANYQMR/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to