Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

monkeypatch.setattr fails to undo on objects with a custom __setattr__ (regression from #14969)

Abierto Apto para principiantes
#15,099 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@Maurenz2530 ya está trabajando en esto.

Desde el 26/9/2026.

  • #15104 de @Maurenz2530 — abierto
  • #15106 de @chen-maker999 — cerrado sin fusionar
  • #15118 de @Tejas5405 — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python
Área
testing-qa

Línea de trabajo

Empieza por la nueva rama en MonkeyPatch.setattr y compárala con el comportamiento anterior descrito en el issue. Añade un caso de regresión a test_proxy.py usando el objeto personalizado setattr/getattr, y ejecuta esa prueba para verificar que undo restaura el valor original y que el valor parcheado no se filtra a pruebas posteriores.

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

Descripción

Since #14969 (0c601d510, not released yet), monkeypatch.setattr doesn't restore attributes on objects that store them somewhere other than __dict__ through a custom __setattr__/__getattr__. Undo raises AttributeError, and the patched value leaks into later tests.

class Config:
    """Stores attributes in a private dict instead of __dict__."""
    def __init__(self):
        object.__setattr__(self, "_data", {"debug": False})
    def __getattr__(self, name):
        try:
            return self._data[name]
        except KeyError:
            raise AttributeError(name) from None
    def __setattr__(self, name, value):
        self._data[name] = value

cfg = Config()

def test_patch(monkeypatch):
    monkeypatch.setattr(cfg, "debug", True)
    assert cfg.debug is True

def test_restored():
    assert cfg.debug is False

On main:

ERROR test_proxy.py::test_patch - AttributeError: 'Config' object has no attribute 'debug'
FAILED test_proxy.py::test_restored - assert True is False
1 failed, 1 passed, 1 error

Just before 0c601d510, the same file passes (2 passed).

The new branch in MonkeyPatch.setattr takes the old value from target.__dict__.get(name, NOTSET) whenever target has a __dict__. It assumes that a plain setattr() writes into that dict. With a custom __setattr__ it doesn't, so the old value is recorded as NOTSET. undo() then calls delattr(cfg, "debug") instead of setting it back to False. That delattr fails, and the value stays patched.

@Shriprasad-P pointed out this exact case in a review on #14969, but it wasn't addressed before the merge. I'm opening this issue so it gets fixed before the next release.

One possible direction: only use the __dict__ lookup when name is actually present in the instance __dict__, or when the type uses object.__setattr__. Otherwise fall back to the value from getattr(), as before.

pytest 9.2.0.dev345+g872117358, Python 3.13.5, Windows 11.

Lenguaje dominante
Python
Estrellas
14.6k
Forks
3.4k
Merge medio
2 d 7 h
PR fusionados (30 d)
29

Preparar el entorno

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.

Más de pytest-dev/pytest

Todos los issues de pytest-dev/pytest

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.