`isinstance(obj, Hashable)` raises `TypeError` when both `obj` and `type(obj)` are unhashable
Personne n'a encore pris cette issue.
- Langage dominant
- Python
- Étoiles
- 77.2k
- Forks
- 36k
- Métriques de merge des PR
- Métriques de PR en attente
Description
Bug report
Bug description:
Assumption: isinstance(anything, any_type) should never raise.
The problem appears to be in _abc.c function _abc__abc_subclasscheck_impl (known at runtime as _abc._abc_subclasscheck()), which reads (in part):
/* 1. Check cache. */
incache = _in_weak_set(impl->_abc_cache, subclass);
The implementation assumes subclass is hashable. That's almost always true of classes, but not guaranteed.
Reproduction case:
from __future__ import annotations
from collections.abc import Hashable
class UnhashableMeta(type):
def __eq__(self, other: object) -> bool:
return super().__eq__(other)
class UnhashableClass(metaclass=UnhashableMeta):
def __eq__(self, other: object) -> bool:
return super().__eq__(other)
# any non-hashable instance of a non-hashable class
# ┌────────┴────────┐
isinstance(UnhashableClass(), Hashable)
Traceback for (cpython) Python 3.13.1:
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File ".../bug.py", line 14, in <module>
isinstance(UnhashableClass(), Hashable)
~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen abc>", line 119, in __instancecheck__
File "<frozen abc>", line 123, in __subclasscheck__
TypeError: unhashable type: 'UnhashableMeta'
Tracebacks are nearly identical with Python 3.8, 3.9, 3.10, 3.11, and 3.12, as well as Python 3.14.0a4.
CPython versions tested on:
3.13, 3.12, 3.11, 3.10, 3.9, 3.14
Operating systems tested on:
macOS
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Ouvrez Modules/_abc.c et commencez par _abc__abc_subclasscheck_impl, plus précisément par l’appel à _in_weak_set décrit dans l’issue. Exécutez sur CPython la reproduction fournie avec UnhashableMeta et UnhashableClass, puis vérifiez que isinstance(UnhashableClass(), Hashable) ne lève plus d’exception et que la régression est couverte par un test approprié.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- c, python
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Clairement spécifiée
- Accessibilité débutants
- 45/100