# Feature or enhancement ### Proposal: The new `ForwardRef.evaluate()` implementation had a fast path introduced in https://github.com/python/cpython/pull/124337 to _not_ call `eval()`: https://github.com/python/cpython/blob/cb394101110e13a27e08bbf2fe9f38d847db004c/Lib/annotationlib.py#L177-L187 However, when the `NameError` is raised, the format is different from the one raised by `eval()`: The exception message is defined as: https://github.com/python/cpython/blob/cb394101110e13a27e08bbf2fe9f38d847db004c/Python/ceval_macros.h#L308 and raised this way: https://github.com/python/cpython/blob/cb394101110e13a27e08bbf2fe9f38d847db004c/Python/ceval.c#L3339-L3351 To have consistent exceptions raised, would it be possible to change the Python fast path implementation to match the C eval code? ```diff diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index 731817a9973..c83a1573ccd 100644 --- a/Lib/annotationlib.py +++ b/Lib/annotationlib.py @@ -27,6 +27,9 @@ class Format(enum.IntEnum): _sentinel = object() +# Following `NAME_ERROR_MSG` in `ceval_macros.h`: +_NAME_ERROR_MSG = "name '{name:.200}' is not defined" + # Slots shared by ForwardRef and _Stringifier. The __forward__ names must be # preserved for compatibility with the old typing.ForwardRef class. The remaining @@ -184,7 +187,7 @@ def evaluate( elif is_forwardref_format: return self else: - raise NameError(arg) + raise NameError(_NAME_ERROR_MSG.format(name=arg), name=arg) else: code = self.__forward_code__ try: ``` This requires `_NAME_ERROR_MSG` to be in sync with the one from `ceval_macros.h`. Or at least, the `NameError` should have its `name` property set (especially as type stubs shows `NameError.name` as `str` currently). cc @JelleZijlstra. ### Has this already been discussed elsewhere? This is a minor feature, which does not need previous discussion elsewhere ### Links to previous discussion of this feature: _No response_ <!-- gh-linked-prs --> ### Linked PRs * gh-135663 * gh-135673 <!-- /gh-linked-prs -->