-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
gh-125618: Make FORWARDREF format succeed more often #132818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Looks like this works in the case where the object is defined globally, but this still manages to fail if the object used in the annotation is defined (or even potentially redefined) within the function. Repro: from annotationlib import get_annotations, Format
def boom():
obj = object()
class RaisesAttributeError:
attriberr: obj.missing
get_annotations(RaisesAttributeError, format=Format.FORWARDREF)
boom() Output: Traceback (most recent call last):
File "C:\Users\ducks\Source\cpython\.cache\annotation_examine.py", line 9, in <module>
boom()
~~~~^^
File "C:\Users\ducks\Source\cpython\.cache\annotation_examine.py", line 7, in boom
get_annotations(RaisesAttributeError, format=Format.FORWARDREF)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ducks\Source\cpython\Lib\annotationlib.py", line 778, in get_annotations
ann = _get_and_call_annotate(obj, format)
File "C:\Users\ducks\Source\cpython\Lib\annotationlib.py", line 902, in _get_and_call_annotate
ann = call_annotate_function(annotate, format, owner=obj)
File "C:\Users\ducks\Source\cpython\Lib\annotationlib.py", line 629, in call_annotate_function
result = func(Format.VALUE_WITH_FAKE_GLOBALS)
File "C:\Users\ducks\Source\cpython\.cache\annotation_examine.py", line 6, in __annotate__
attriberr: obj.missing
^^^^^^^^^^^
File "C:\Users\ducks\Source\cpython\Lib\annotationlib.py", line 380, in __getattr__
return self.__make_new(ast.Attribute(self.__get_ast(), attr))
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ducks\Source\cpython\Lib\annotationlib.py", line 358, in __make_new
self.__stringifier_dict__.stringifiers.append(stringifier)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'builtin_function_or_method' object has no attribute 'stringifiers' This came up because this is how I'd written my test case for this (writing the test case was actually as far as I'd gone, because the first test case raised the other issue). def test_attributeerror_handled(self):
class MissingAttrib:
pass
class RaisesAttributeError:
attriberr: MissingAttrib.missing
with self.assertRaises(AttributeError):
get_annotations(RaisesAttributeError, format=Format.VALUE)
self.assertEqual(
get_annotations(RaisesAttributeError, format=Format.FORWARDREF),
{
"attriberr": support.EqualToForwardRef(
"MissingAttrib.missing",
owner=RaisesAttributeError,
is_class=True,
)
}
)
self.assertEqual(
get_annotations(RaisesAttributeError, format=Format.STRING),
{"attriberr": "MissingAttrib.missing"}
) |
Thanks! This was a silly bug that also broke |
Fixes #125618.
cc @DavidCEllis
AttributeError
is raised when__annotations__
is accessed #125618