`pickle.loads` will crash with self-references inside a custom hash function
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:
here is a reproduction of the issue:
import pickle
class Foo:
def __init__(self):
self.x: object = {self}
def __hash__(self):
return hash(self.x)
foo = Foo()
print(pickle.loads(pickle.dumps(foo)))
running this will result in the following exception:
Traceback (most recent call last):
File "/home/charles/vyper/foo.py", line 10, in <module>
foo = Foo()
^^^^^
File "/home/charles/vyper/foo.py", line 5, in __init__
self.x: object = {self}
^^^^^^
File "/home/charles/vyper/foo.py", line 8, in __hash__
return hash(self.x)
^^^^^^
AttributeError: 'Foo' object has no attribute 'x'
a workaround to the issue has been described at https://stackoverflow.com/a/44888113. however, i consider this a bug in the cpython implementation, because pickle theoretically handles object cycles (e.g., replacing line 5 with self.x = [self] poses no problem to the unpickler).
i suspect that cpython rehashes all items when reconstructing a dict or set, which makes the issue even more problematic, e.g. if the hash function has any side-effects, they will be executed by the unpickler.
build info:
$ python
Python 3.11.10 (main, Sep 7 2024, 18:35:41) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
CPython versions tested on:
3.11
Operating systems tested on:
Linux
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
Le rapport fournit un reproducteur centré sur pickle.dumps et pickle.loads, mais ne nomme aucun fichier source de CPython ni aucun test. Commencez par l’exécuter dans l’environnement Python 3.11/Linux indiqué et retracez le chemin de désérialisation ; la tâche ne sera terminée qu’une fois défini un comportement convenu pour les hachages personnalisés autoréférentiels, ajoutée une couverture de régression et vérifiée l’absence d’effets secondaires de hachage involontaires.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- python
- Domaine
- backend
- Type d'issue
- Bug
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- À clarifier
- Accessibilité débutants
- 25/100