New submission from Finn Mason <[email protected]>:
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.
----------
components: Library (Lib)
messages: 399814
nosy: finnjavier08
priority: normal
severity: normal
status: open
title: Add check_methods function to standard library
type: enhancement
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue44941>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com