Skip to content

Commit 65f640c

Browse files
committed
gh-156515: Correctly filter conditional annotations in FORWARDREF and STRING formats
1 parent 0e29768 commit 65f640c

3 files changed

Lines changed: 23 additions & 0 deletions

File tree

Lib/annotationlib.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,11 @@ def _build_closure(annotate, owner, is_class, stringifier_dict, *, allow_evaluat
855855
cell_dict = {}
856856
for name, cell in zip(annotate.__code__.co_freevars, annotate.__closure__, strict=True):
857857
cell_dict[name] = cell
858+
# This is an internal name for ensuring we get the correct annotations,
859+
# so do not replace the original cell.
860+
if name == "__conditional_annotations__":
861+
new_closure.append(cell)
862+
continue
858863
new_cell = None
859864
if allow_evaluation:
860865
try:

Lib/test/test_annotationlib.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,6 +1206,22 @@ def __call__(self):
12061206
with self.subTest(format=format, obj=obj):
12071207
self.assertEqual(get_annotations(obj, format=format), {})
12081208

1209+
def test_conditional_annotations(self):
1210+
class ConditionalAnnotations:
1211+
x: int
1212+
if False:
1213+
y: str
1214+
1215+
self.assertEqual(get_annotations(ConditionalAnnotations), {"x": int})
1216+
self.assertEqual(
1217+
get_annotations(ConditionalAnnotations, format=Format.FORWARDREF),
1218+
{"x": int},
1219+
)
1220+
self.assertEqual(
1221+
get_annotations(ConditionalAnnotations, format=Format.STRING),
1222+
{"x": "int"},
1223+
)
1224+
12091225
def test_pep695_generic_class_with_future_annotations(self):
12101226
ann_module695 = inspect_stringized_annotations_pep695
12111227
A_annotations = get_annotations(ann_module695.A, eval_str=True)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix bug where :mod:`annotationlib` could return annotations located in code
2+
blocks that are not executed at runtime.

0 commit comments

Comments
 (0)