diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index 77aac8bf2f0eb3..be3bc275817f50 100644 --- a/Lib/annotationlib.py +++ b/Lib/annotationlib.py @@ -4,6 +4,7 @@ import builtins import enum import functools +import keyword import sys import types @@ -156,10 +157,10 @@ def evaluate(self, *, globals=None, locals=None, type_params=None, owner=None): locals.pop(param_name, None) arg = self.__forward_arg__ - if arg.isidentifier(): + if arg.isidentifier() and not keyword.iskeyword(arg): if arg in locals: value = locals[arg] - elif globals is not None and arg in globals: + elif arg in globals: value = globals[arg] elif hasattr(builtins, arg): return getattr(builtins, arg) diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py index c0820556cc952b..cc051ef3b93658 100644 --- a/Lib/test/test_annotationlib.py +++ b/Lib/test/test_annotationlib.py @@ -332,6 +332,14 @@ def test_name_lookup_without_eval(self): with self.assertRaises(NameError): ForwardRef("doesntexist").evaluate() + def test_fwdref_invalid_syntax(self): + fr = ForwardRef("if") + with self.assertRaises(SyntaxError): + fr.evaluate() + fr = ForwardRef("1+") + with self.assertRaises(SyntaxError): + fr.evaluate() + class TestGetAnnotations(unittest.TestCase): def test_builtin_type(self):