Skip to content

gh-160948: Let class attributes shadow nonlocals in ForwardRef.evaluate() - #161630

Open
mesubash wants to merge 1 commit into
python:mainfrom
mesubash:gh-160948-forwardref-class-namespace
Open

mesubash wants to merge 1 commit into
python:mainfrom
mesubash:gh-160948-forwardref-class-namespace

Conversation

@mesubash

@mesubash mesubash commented Nov 8, 2026 •

Copy link
Copy Markdown

For a forward reference to a single name, ForwardRef.evaluate() returned the closure cell's value before the owner class's namespace was considered, so a nonlocal won over a class attribute of the same name. The dict-of-cells path already lets the class namespace win, which is why David's example gave 'nonlocal' for a but list['local'] for b.

This skips the single-cell shortcut when no explicit locals are passed, the owner is a class, and the name is defined in that class. As Jelle said on the issue, explicit globals/locals are not meant to override the captured scope, so that behaviour is unchanged.

Testing:

  • The new test fails without the change ('nonlocal' != 'local') and passes with it.
  • Unchanged with and without the patch: the function-owner example from the issue report (99 in all three calls), a class owner with locals={} passed, and a class that doesn't define the name.
  • test_annotationlib, test_typing, test_inspect, test_dataclasses, test_type_annotations, test_functools, test_type_params and test_pydoc pass.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants