This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add check_methods function to standard library
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: eric.araujo, finnjavier08, kj, rhettinger, stutzbach
Priority: normal Keywords:

Created on 2021-08-18 02:06 by finnjavier08, last changed 2022-04-11 14:59 by admin.

Messages (5)
msg399814 - (view) Author: Finn Mason (finnjavier08) Date: 2021-08-18 02:06
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.
msg399877 - (view) Author: Finn Mason (finnjavier08) Date: 2021-08-18 23:54
I strongly feel that `check_methods` shouldn't be in collections.abc, even though that's where it's originally found, because it's not related specifically to collections but to ABCs and classes in general. I would prefer for it to be implemented in `abc` or similar.

I'm reverting to the original title until a module is decided on.

I'd be happy to do the implementation and pull request once approval is given and a module is decided on.
msg399905 - (view) Author: Ken Jin (kj) * (Python committer) Date: 2021-08-19 10:40
@finnjavier08 sorry, I'd misinterpreted your original message. Thanks for clarifying your intent!

> I'd be happy to do the implementation and pull request once approval is given and a module is decided on.

I can't comment because I'm not an expert on collections.abc/abc and friends, but you might want to post your idea on the python-ideas mailing list or https://discuss.python.org/c/ideas/6 to get other opinions first. I have the feeling more people read the former.
msg399990 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2021-08-20 19:03
FYI there was a ticket and a discussion before: https://mail.python.org/archives/list/python-ideas@python.org/thread/FCGDSVWHIJHBYKS2O4RHZVLXCGSGBLQH/#FCGDSVWHIJHBYKS2O4RHZVLXCGSGBLQH

Should be reviewed to see the arguments made and determine if things have changed to reopen the question!
msg400008 - (view) Author: Finn Mason (finnjavier08) Date: 2021-08-21 01:51
Thank you for the suggestions.

From what I could tell, the cited python-ideas discussion was more about checking the signature of a method. However, an issue cited by the ex-BDFL (issue9731) was helpful. It's a similar idea that verifies that a class implements an ABC. However, I'm looking at a function that simplifies writing the ABC itself.

I will post the idea to python-ideas and see what people think.
History
Date User Action Args
2022-04-11 14:59:48adminsetgithub: 89104
2021-08-21 01:51:04finnjavier08setmessages: + msg400008
2021-08-20 19:03:01eric.araujosetnosy: + eric.araujo
messages: + msg399990
2021-08-19 10:40:50kjsetnosy: + kj
messages: + msg399905
2021-08-18 23:54:01finnjavier08setmessages: + msg399877
title: Add check_methods function to collections.abc in standard library -> Add check_methods function to standard library
2021-08-18 10:19:15kjsetnosy: + rhettinger, stutzbach
title: Add check_methods function to standard library -> Add check_methods function to collections.abc in standard library

versions: + Python 3.11
2021-08-18 02:06:42finnjavier08create