Skip to content

Commit f0ef87f

Browse files
gh-157056: Remint NEWS and fold STRING-format tests into TestStringFormat
1 parent eba936d commit f0ef87f

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

Lib/annotationlib.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -998,29 +998,35 @@ def _is_runtime_constructed(value):
998998
def _contains_runtime_constructed(value):
999999
if _is_runtime_constructed(value):
10001000
return True
1001-
if isinstance(value, (list, tuple, set)):
1002-
return any(_contains_runtime_constructed(v) for v in value)
10031001
if isinstance(value, dict):
10041002
return any(
10051003
_contains_runtime_constructed(k) or _contains_runtime_constructed(v)
10061004
for k, v in value.items()
10071005
)
1006+
if isinstance(value, (list, tuple, set, frozenset)):
1007+
return any(_contains_runtime_constructed(v) for v in value)
10081008
return False
10091009

10101010

10111011
def _stringify_annotation_dict(annos, owner):
10121012
# Only read source when fake-globals produced a runtime object we cannot
1013-
# stringify (lambda, genexpr, or a container holding one).
1013+
# stringify (lambda, genexpr, or a container holding one), or when the
1014+
# fallback text still embeds a memory address.
10141015
sourced = _sentinel
10151016
result = {}
10161017
for key, val in annos.items():
1017-
if _contains_runtime_constructed(val):
1018+
text = _stringify_single(val)
1019+
needs_source = (
1020+
_contains_runtime_constructed(val)
1021+
or "0x" in text.lower()
1022+
)
1023+
if needs_source:
10181024
if sourced is _sentinel:
10191025
sourced = _string_annotations_from_source(owner)
10201026
if sourced is not None and key in sourced:
10211027
result[key] = sourced[key]
10221028
continue
1023-
result[key] = _stringify_single(val)
1029+
result[key] = text
10241030
return result
10251031

10261032

@@ -1038,6 +1044,11 @@ def _stringify_container(anno):
10381044
return "set()"
10391045
inner = ", ".join(_stringify_single(v) for v in anno)
10401046
return f"{{{inner}}}"
1047+
if isinstance(anno, frozenset):
1048+
if not anno:
1049+
return "frozenset()"
1050+
inner = ", ".join(_stringify_single(v) for v in anno)
1051+
return f"frozenset({{{inner}}})"
10411052
inner = ", ".join(
10421053
f"{_stringify_single(k)}: {_stringify_single(v)}"
10431054
for k, v in anno.items()
@@ -1057,7 +1068,10 @@ def _stringify_single(anno):
10571068
# Lambdas and generator expressions are syntax, not name lookups.
10581069
# repr() embeds a memory address; type_repr() is stable.
10591070
return type_repr(anno)
1060-
elif isinstance(anno, (list, tuple, set, dict)) and _contains_runtime_constructed(anno):
1071+
elif (
1072+
isinstance(anno, (list, tuple, set, frozenset, dict))
1073+
and _contains_runtime_constructed(anno)
1074+
):
10611075
return _stringify_container(anno)
10621076
else:
10631077
return repr(anno)

0 commit comments

Comments
 (0)