Skip to content

gh-150641: Fix evaluating forward references in STRING format can 'leak' internal names in typing#150648

Open
ByteFlowing1337 wants to merge 2 commits into
python:mainfrom
ByteFlowing1337:fix-150641
Open

gh-150641: Fix evaluating forward references in STRING format can 'leak' internal names in typing#150648
ByteFlowing1337 wants to merge 2 commits into
python:mainfrom
ByteFlowing1337:fix-150641

Conversation

@ByteFlowing1337
Copy link
Copy Markdown
Contributor

@ByteFlowing1337 ByteFlowing1337 commented May 31, 2026

@ByteFlowing1337 ByteFlowing1337 changed the title Fix evaluating forward references in STRING format can 'leak' internal names in typing gh-150641: Fix evaluating forward references in STRING format can 'leak' internal names in typing May 31, 2026
@AlexWaygood AlexWaygood removed their request for review May 31, 2026 09:22
Comment thread Lib/typing.py Outdated
@JelleZijlstra JelleZijlstra self-requested a review May 31, 2026 19:40
@cossor
Copy link
Copy Markdown

cossor commented Jun 1, 2026

Kudos for addressing this issue so quickly!

When ForwardRef.__extra_names__ is None, __resolved_str__ is identical to __forward_arg__, which should be a string containing the code that was evaluated to produce the ForwardRef. In short, adding __resolved_str__ did not eliminate the __forward_arg__ leak. That interface is still broken.

Renaming the new property might help, but I would not be surprised if additional effort is needed.

(I can imagine a world where evaluate_forward_ref is deprecated and ForwardRef.evaluate recursively evaluates nested forward references as needed.)

@ByteFlowing1337
Copy link
Copy Markdown
Contributor Author

In short, adding __resolved_str__ did not eliminate the __forward_arg__ leak. That interface is still broken.

I think the key is not eliminating the __forward_arg__ leak, but preventing the leak of internal names like __annotationlib_name_1__.

When ForwardRef.__extra_names__ is None, I believe directly returning __forward_arg__ would not leak the internal names.

Besides, this raises a question for me: should we add __resolved_arg__ documentation, since __forward_arg__ is documented?

@cossor
Copy link
Copy Markdown

cossor commented Jun 1, 2026

I think the key is not eliminating the __forward_arg__ leak, but preventing the leak of internal names like __annotationlib_name_1__.

I think we agree. When I wrote "the __forward_arg__ leak" I should have written "leaking internal names via __forward_arg__."

The description of __forward_arg__ in the documentation is a de facto contract. Its value should be appropriate when evaluating a forward reference with format=Format.STRING, and probably is appropriate when forward references are strings. (In my code, forward references are never strings.)

Note that __forward_arg__ is supported by annotationlib.pyi whereas __resolved_str__ is not. At this point, the new property is just an implementation detail. I mentioned renaming it, because I think it tries to be what __forward_arg__ should be.

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.

3 participants