diff --git a/Lib/annotationlib.py b/Lib/annotationlib.py index 8204c762cce8a2..5fd0b25780f459 100644 --- a/Lib/annotationlib.py +++ b/Lib/annotationlib.py @@ -855,6 +855,11 @@ def _build_closure(annotate, owner, is_class, stringifier_dict, *, allow_evaluat cell_dict = {} for name, cell in zip(annotate.__code__.co_freevars, annotate.__closure__, strict=True): cell_dict[name] = cell + # This is an internal name for ensuring we get the correct annotations, + # so do not replace the original cell. + if name == "__conditional_annotations__": + new_closure.append(cell) + continue new_cell = None if allow_evaluation: try: diff --git a/Lib/test/test_annotationlib.py b/Lib/test/test_annotationlib.py index 530114161701b5..ee02d5d91ac09c 100644 --- a/Lib/test/test_annotationlib.py +++ b/Lib/test/test_annotationlib.py @@ -1206,6 +1206,22 @@ def __call__(self): with self.subTest(format=format, obj=obj): self.assertEqual(get_annotations(obj, format=format), {}) + def test_conditional_annotations(self): + class ConditionalAnnotations: + x: int + if False: + y: str + + self.assertEqual(get_annotations(ConditionalAnnotations), {"x": int}) + self.assertEqual( + get_annotations(ConditionalAnnotations, format=Format.FORWARDREF), + {"x": int}, + ) + self.assertEqual( + get_annotations(ConditionalAnnotations, format=Format.STRING), + {"x": "int"}, + ) + def test_pep695_generic_class_with_future_annotations(self): ann_module695 = inspect_stringized_annotations_pep695 A_annotations = get_annotations(ann_module695.A, eval_str=True) diff --git a/Misc/NEWS.d/next/Library/2026-08-28-06-22-30.gh-issue-156515.f-GVyF.rst b/Misc/NEWS.d/next/Library/2026-08-28-06-22-30.gh-issue-156515.f-GVyF.rst new file mode 100644 index 00000000000000..ac57dc3242080f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-28-06-22-30.gh-issue-156515.f-GVyF.rst @@ -0,0 +1,2 @@ +Fix bug where :mod:`annotationlib` could return annotations located in code +blocks that are not executed at runtime.