python / python/cpython

`pickle.loads` will crash with self-references inside a custom hash function

Abierto
#124,937 24 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

extension-modules stdlib topic-dataclasses type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
36k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

El informe proporciona un reproductor centrado en pickle.dumps y pickle.loads, pero no menciona ningún archivo de código fuente de CPython ni ninguna prueba. Empieza ejecutándolo en el entorno Python 3.11/Linux indicado y siguiendo el recorrido de deserialización; para darlo por terminado se requiere un comportamiento acordado para hashes personalizados autorreferenciales, cobertura de regresión y ningún efecto secundario de hash no intencionado.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
backend
Tipo de issue
Error
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.