Skip to content

fix(monkeypatch): don't leave inherited attrs in instance __dict__ after undo - #14962

Closed
mturac wants to merge 1 commit into
pytest-dev:mainfrom
mturac:fix/issue-10821
Closed

fix(monkeypatch): don't leave inherited attrs in instance __dict__ after undo#14962
mturac wants to merge 1 commit into
pytest-dev:mainfrom
mturac:fix/issue-10821

Conversation

@mturac

@mturac mturac commented Sep 2, 2026

Copy link
Copy Markdown

fixes #10644

monkeypatch.setattr on an inherited attribute records the value from getattr() — wich is the class-level value. on undo it does setattr(target, name, old), writing that into the instance's own __dict__. after that the class attribute (including descriptors) is permanently shadowed.

fix: check vars(target) first. if the name isnt in the instance's own namespace, store the sentinel so undo uses delattr instead of setattr. same logic for delattr path.

three regression tests:

  • inherited attr not left in instance dict after undo
  • own instance attr still restored correctly
  • class-level descriptor not shadowed on subclass after undo

ran full testing/test_monkeypatch.py + testing/test_unittest.py: 109 passed, 10 skipped, 0 failed.

…ter undo

setattr recorded getattr(target, name) as the old value, which for
inherited attributes returns the class-level value.  undo() then
called setattr(target, name, old_value), writing that value into the
instance __dict__ and permanently shadowing the class attribute
(including descriptors like properties).

Now check vars(target) first — if the name isn't in the instance's
own namespace, record NOTSET so undo() uses delattr instead.

Fixes pytest-dev#10644
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided (automation) changelog entry is part of PR label Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:chronographer:provided (automation) changelog entry is part of PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MonkeyPatch.setattr leaves a new item in vars(target) after cleanup when overriding an inherited attribute of a non-class object

2 participants