python / python/cpython

Side-effect of `ABC.__subclasshook__` / `_abc_instancecheck` ▶ `isinstance(..., Parent)` calls `__subclasscheck__` of uninvolved Child class -> RecursionError

Ouverte
#136,713 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

extension-modules stdlib type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Bug report

Bug description:

I realized there is strange error of __subclasshook__, or possibly _abc_instancecheck which creates a side-effect that __subclasshook__ is called on a Child class that is not even queried.

What is even more strange this error only occurs when the crucial statement B is called in a AB situation, just B or BAB is fine.

# At the end of his snippet are 3 test sets, Only the first causes an error the other 2 are fine.
import sys
sys.setrecursionlimit(59)
from abc import ABC


class Base(ABC): ...

class _ParentCheck(Base):

    @classmethod
    def __subclasshook__(cls, subclass):
        if not issubclass(subclass, Base):
            return NotImplemented
        if not hasattr(subclass, "f"):
            return False
        return True


class Parent(Base):
    f: int

    @classmethod
    def construct(cls, foo: int):
        class Child(cls, _ParentCheck):
            f = foo
        
        
        return Child


# Test Set 1: Error

assert issubclass(Parent.construct(1), Parent)  # Statement A
assert not isinstance(lambda: None, Parent)  # Statement B

# Test Set 2: OK

assert not isinstance(lambda: None, Parent)  # Statement B

# Test Set 3: OK

assert not isinstance(lambda: None, Parent)  # Statement B
assert issubclass(Parent.construct(1), Parent)  # Statement A
assert not isinstance(lambda: None, Parent)  # Statement B

CPython versions tested on:

3.14

Operating systems tested on:

Linux

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter le reproducer fourni sur CPython 3.14, en vous concentrant sur ABC.subclasshook, _abc_instancecheck et l’interaction entre Parent et _ParentCheck. Le travail est terminé lorsque Test Set 1 ne lève plus de RecursionError et que Test Sets 2 et 3 continuent de réussir.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
compilers
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.