Skip to content

gh-153772: Make abc isinstance() tolerate instances without __class__#154149

Open
fedonman wants to merge 1 commit into
python:mainfrom
fedonman:fix-gh-153772-abc-instancecheck-no-class
Open

gh-153772: Make abc isinstance() tolerate instances without __class__#154149
fedonman wants to merge 1 commit into
python:mainfrom
fedonman:fix-gh-153772-abc-instancecheck-no-class

Conversation

@fedonman

Copy link
Copy Markdown
Contributor

The built-in isinstance() reads an instance's __class__ with a lookup that suppresses AttributeError and falls back to the object's type, so a value whose __class__ access raises still checks cleanly:

>>> class NoClass:
...     def __getattribute__(self, name):
...         if name == "__class__":
...             raise AttributeError(name)
...         return super().__getattribute__(name)
...
>>> isinstance(NoClass(), int)
False

ABCMeta.__instancecheck__ read __class__ directly instead, so the same object leaked the AttributeError when checked against a collections.abc class:

>>> from collections.abc import Mapping
>>> isinstance(NoClass(), Mapping)
AttributeError: __class__

This makes the abstract base class machinery fall back to type(instance) when __class__ is unavailable, in both the C (Modules/_abc.c) and the pure-Python (Lib/_py_abc.py) implementations, so it matches the built-in isinstance():

>>> isinstance(NoClass(), Mapping)
False

Objects without a __class__ are unusual, but they do turn up in the wild (for example some Qt widgets, as noted in the issue).

…lass__

The built-in isinstance() reads an instance's __class__ with a lookup that
suppresses AttributeError and falls back to the object's type, so
isinstance(obj, int) returns False for an object whose __class__ access
raises. ABCMeta.__instancecheck__ read __class__ directly instead, so
isinstance(obj, Mapping) leaked that AttributeError.

Fall back to type(instance) when __class__ is unavailable, in both the C
and the pure-Python implementations, so the abstract base classes behave
like the built-in isinstance(). Such objects are unusual, but they do turn
up in the wild (for example some Qt widgets).
@python-cla-bot

python-cla-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant