python / python/cpython

dir() can crash with cyclic __bases__

Ouverte
#155,452 15 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

interpreter-core pending type-crash
Langage dominant
Python
Étoiles
77.2k
Forks
35.9k
Métriques de merge des PR
Métriques de PR en attente

Description

Crash report

What happened?

dir() can cause a native stack overflow when an object's __class__
provides a cyclic __bases__ attribute.

Minimal reproducer:

class Fake:
    pass

a = Fake()
a.__bases__ = (a,)

class C:
    @property
    def __class__(self):
        return a

print("entering", flush=True)
dir(C())
print("survived", flush=True)
Observed Result

On CPython 3.16.0a0 built from commit 5107fd700d7:

entering
timeout: the monitored command dumped core
Segmentation fault
rc=139

The crash occurs because object.__dir__() obtains the object's __class__ and merge_class_dict() recursively traverses __bases__ without a recursion guard. A cyclic __bases__ therefore causes unbounded native recursion and eventually a SIGSEGV.

The analogous __bases__ traversal in abstract_issubclass() already uses _Py_EnterRecursiveCall().

I also verified that adding a recursion guard to merge_class_dict() changes the failure from a native crash to a catchable exception:

RecursionError: Stack overflow (used 8120 kB) in __bases__

A regression test covering the cyclic __bases__ case was also added to Lib/test/test_builtin.py and passes with:

./python -m test test_builtin -m test_dir
== Tests result: SUCCESS ==
1 test OK.
CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Output from running 'python -VV' on the command line:

Python 3.16.0a0 (heads/investigate-0071-dir-cyclic-bases-dirty:5107fd700d7, Aug 9 2026, 21:10:20) [GCC 13.3.0]

Linked PRs
  • gh-155453

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 merge_class_dict() et le reproducteur de bases cycliques décrit dans l’issue, puis lisez le test de régression dans Lib/test/test_builtin.py. Exécutez ./python -m test test_builtin -m test_dir ; le travail est terminé lorsque le cas lève une RecursionError interceptable au lieu de provoquer un débordement de la pile native.

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é
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

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