New submission from Graham Dumpleton <graham.dumple...@gmail.com>:

The Python standard library has two effective implementations of helpers for 
the ABCMeta class. A C implementation, and a pure Python version which is only 
used if the C implementation isn't available (perhaps for PyPy).

* https://github.com/python/cpython/blob/3.9/Lib/abc.py#L89
* https://github.com/python/cpython/blob/3.9/Lib/_py_abc.py
* https://github.com/python/cpython/blob/3.9/Modules/_abc.c

These two implementations behave differently.

Specifically, the ABCMeta.__subclasscheck__() implementation for the C version 
doesn't support duck typing for the subclass argument to issubclass() when this 
delegates to ABCMeta.__subclasscheck__(). The Python implementation for this 
has no problems though.

In the pure Python version it uses isinstance().

* https://github.com/python/cpython/blob/3.9/Lib/_py_abc.py#L110

In the C implementation it uses PyType_Check() which doesn't give the same 
result.

* https://github.com/python/cpython/blob/3.9/Modules/_abc.c#L610

The consequence of this is that transparent object proxies used as decorators 
on classes (eg., as wrapt uses) will break when the C implementation us used 
with an error of:

        #       def __subclasscheck__(cls, subclass):
        #           """Override for issubclass(subclass, cls)."""
        #   >       return _abc_subclasscheck(cls, subclass)
        #   E       TypeError: issubclass() arg 1 must be a class

Example of tests from wrapt and how tests using C implementation must be 
disabled can be found at:

* 
https://github.com/GrahamDumpleton/wrapt/blob/develop/tests/test_inheritance_py37.py

If instead of using PyType_Check() the C implementation used 
PyObject_IsInstance() at that point it is possible that wrapt may then work if 
the remainder of the C implementation is true to how the pure Python version 
works (not been able to test if that is the case or not as yet).

----------
components: Library (Lib)
messages: 399060
nosy: grahamd
priority: normal
severity: normal
status: open
title: ABCMeta.__subclasscheck__() doesn't support duck typing.
type: behavior
versions: Python 3.10, Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue44847>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to