python / python/cpython

ABC subclasses may break `issubclass(T, T)` invariant

Open
#119,699 3 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

extension-modules stdlib type-bug
Dominant language
Python
Stars
77.2k
Forks
36k
PR merge metrics
PR metrics pending

Description

Bug report

Bug description:

This was a nasty bug to track down. I really don't have a clue why this would happen. It seems to be triggered under these conditions:

  • A root class (Root) inherits from ABC
  • There's diamond-shaped inheritance for a sub-subclass (Multi)
  • In Root.__init_subclass__, when Multi is initializing, a check is performed to see if First is a subclass of Second
  • First is no longer a subclass of itself
from abc import ABC

class Root(ABC):
    def __init_subclass__(cls, **kwargs):
        if cls.__name__ == "Multi":
            # issubclass(Second, First)  # Wouldn't trigger the bug for Second
            issubclass(First, Second)  # Triggers the bug for First
            issubclass(Second, First)  # Doesn't trigger the bug for Second

class First(Root): ...
class Second(Root): ...
class Multi(First, Second): ...

assert not issubclass(First, First)  # This is the bug.
assert issubclass(Second, Second)

print("bug!")
CPython versions tested on:

3.12

Operating systems tested on:

macOS

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run the supplied Python reproducer on CPython 3.12 and trace ABC.init_subclass and issubclass during Multi initialization. Investigate why First no longer satisfies issubclass(First, First); done means the invariant assertions pass for the diamond hierarchy, with regression coverage for this case.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.