From 24e985d569d7db5bfac9dadfb70e4344b64577f6 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Thu, 6 Aug 2026 15:39:15 +0200 Subject: [PATCH 1/2] gh-155278: Avoid needlessly accessing `ForwardRef.__forward_code__` in `evaluate_forward_ref()` --- Lib/typing.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Lib/typing.py b/Lib/typing.py index 809c0ff88607a59..d1d9ad41ed97cca 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -25,6 +25,7 @@ import collections.abc import copyreg import functools +import keyword import operator import sys import types @@ -998,8 +999,12 @@ def _make_forward_ref(code, *, parent_fwdref=None, **kwargs): if parent_fwdref.__owner__ is not None: kwargs['owner'] = parent_fwdref.__owner__ forward_ref = annotationlib.ForwardRef(code, **kwargs) - # For compatibility, eagerly compile the forwardref's code. - forward_ref.__forward_code__ + # For compatibility, eagerly compile the forwardref's code so that any + # SyntaxError is raised immediately rather than when the forward + # reference is evaluated. Similar to 'ForwardRef.evaluate(), we only compile + # it if necessary: + if not (code.isidentifier() and not keyword.iskeyword(code)): + forward_ref.__forward_code__ return forward_ref From ca262b1cb6d8bd22e8be64383ed1a61fe9c8bc91 Mon Sep 17 00:00:00 2001 From: Victorien <65306057+Viicos@users.noreply.github.com> Date: Fri, 7 Aug 2026 09:51:01 +0200 Subject: [PATCH 2/2] Apply suggestion from @Viicos --- Lib/typing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/typing.py b/Lib/typing.py index d1d9ad41ed97cca..8587813a9ebe9ff 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1001,7 +1001,7 @@ def _make_forward_ref(code, *, parent_fwdref=None, **kwargs): forward_ref = annotationlib.ForwardRef(code, **kwargs) # For compatibility, eagerly compile the forwardref's code so that any # SyntaxError is raised immediately rather than when the forward - # reference is evaluated. Similar to 'ForwardRef.evaluate(), we only compile + # reference is evaluated. Similar to 'ForwardRef.evaluate()', we only compile # it if necessary: if not (code.isidentifier() and not keyword.iskeyword(code)): forward_ref.__forward_code__