From f14fcb43b4e54f9a4994a6a03e9c6460e938a794 Mon Sep 17 00:00:00 2001 From: Anh71me Date: Thu, 18 Aug 2022 22:16:07 +0800 Subject: [PATCH 1/6] GH-96073: Fix wild replacement in formatannotation --- Lib/inspect.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index cbc0632484b832..f54463a878d245 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1448,7 +1448,12 @@ def getargvalues(frame): def formatannotation(annotation, base_module=None): if getattr(annotation, '__module__', None) == 'typing': - return repr(annotation).replace('typing.', '') + def repl(match): + text = match.group() + if text.startswith('typing.'): + return text[len('typing.'):] + return text + return re.sub(r'[\w\.]+', repl, repr(annotation)) if isinstance(annotation, types.GenericAlias): return str(annotation) if isinstance(annotation, type): From 1f4b638cace276701a893bce74527eaf3ab3a408 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 29 Aug 2022 12:35:30 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst diff --git a/Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst b/Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst new file mode 100644 index 00000000000000..d7f0e1618bb77b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst @@ -0,0 +1 @@ +Fix inspect formatannotation wild replacement on ``repr(typing_obj)`` From ba9ec594b723e2574d934ff696dfc960b53e220c Mon Sep 17 00:00:00 2001 From: iyume Date: Mon, 29 Aug 2022 21:20:02 +0800 Subject: [PATCH 3/6] Add test case --- Lib/test/test_inspect.py | 7 +++++++ Lib/test/typingdata/__init__.py | 0 Lib/test/typingdata/typing.py | 13 +++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 Lib/test/typingdata/__init__.py create mode 100644 Lib/test/typingdata/typing.py diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index be9f29e04ae110..a4ac031a72e551 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1421,6 +1421,13 @@ def wrapper(a, b): self.assertEqual(inspect.get_annotations(isa.MyClassWithLocalAnnotations, eval_str=True), {'x': int}) +class TestFormatAnnotation(unittest.TestCase): + def test_typing_replacement(self): + from test.typingdata.typing import ann, ann1 + self.assertEqual(inspect.formatannotation(ann), 'Union[List[str], int]') + self.assertEqual(inspect.formatannotation(ann1), 'Union[List[testModule.typing.A], int]') + + class TestIsDataDescriptor(unittest.TestCase): def test_custom_descriptors(self): diff --git a/Lib/test/typingdata/__init__.py b/Lib/test/typingdata/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/Lib/test/typingdata/typing.py b/Lib/test/typingdata/typing.py new file mode 100644 index 00000000000000..290c66886c644b --- /dev/null +++ b/Lib/test/typingdata/typing.py @@ -0,0 +1,13 @@ +# This module is for test_inspect formatannotation + +from typing import Union, List + +ann = Union[List[str], int] + +# mock typing._type_repr behaviour +class A: ... + +A.__module__ = 'testModule.typing' +A.__qualname__ = 'A' + +ann1 = Union[List[A], int] From a9139821b7c3e88b1d6f123453c35b7f005f808e Mon Sep 17 00:00:00 2001 From: Anh71me Date: Wed, 31 Aug 2022 14:44:17 +0800 Subject: [PATCH 4/6] Update Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst Co-authored-by: Jelle Zijlstra --- .../next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst b/Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst index d7f0e1618bb77b..0e6dd8d360cbc9 100644 --- a/Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst +++ b/Misc/NEWS.d/next/Library/2022-08-29-12-35-28.gh-issue-96073.WaGstf.rst @@ -1 +1 @@ -Fix inspect formatannotation wild replacement on ``repr(typing_obj)`` +In :mod:`inspect`, fix overeager replacement of "`typing.`" in formatting annotations. From 9e1a9ccd4296ec1d09aa1392dcbbfff5e01074a7 Mon Sep 17 00:00:00 2001 From: iyume Date: Wed, 31 Aug 2022 15:05:13 +0800 Subject: [PATCH 5/6] using removeprefix and rename typingdata to typinganndata --- Lib/inspect.py | 4 +--- Lib/test/test_inspect.py | 2 +- Lib/test/{typingdata => typinganndata}/__init__.py | 0 Lib/test/{typingdata/typing.py => typinganndata/inspect.py} | 0 4 files changed, 2 insertions(+), 4 deletions(-) rename Lib/test/{typingdata => typinganndata}/__init__.py (100%) rename Lib/test/{typingdata/typing.py => typinganndata/inspect.py} (100%) diff --git a/Lib/inspect.py b/Lib/inspect.py index f54463a878d245..5f7574c194ff2b 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1450,9 +1450,7 @@ def formatannotation(annotation, base_module=None): if getattr(annotation, '__module__', None) == 'typing': def repl(match): text = match.group() - if text.startswith('typing.'): - return text[len('typing.'):] - return text + return text.removeprefix('typing.') return re.sub(r'[\w\.]+', repl, repr(annotation)) if isinstance(annotation, types.GenericAlias): return str(annotation) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index a4ac031a72e551..b561d52a1bb5de 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1423,7 +1423,7 @@ def wrapper(a, b): class TestFormatAnnotation(unittest.TestCase): def test_typing_replacement(self): - from test.typingdata.typing import ann, ann1 + from test.typinganndata.inspect import ann, ann1 self.assertEqual(inspect.formatannotation(ann), 'Union[List[str], int]') self.assertEqual(inspect.formatannotation(ann1), 'Union[List[testModule.typing.A], int]') diff --git a/Lib/test/typingdata/__init__.py b/Lib/test/typinganndata/__init__.py similarity index 100% rename from Lib/test/typingdata/__init__.py rename to Lib/test/typinganndata/__init__.py diff --git a/Lib/test/typingdata/typing.py b/Lib/test/typinganndata/inspect.py similarity index 100% rename from Lib/test/typingdata/typing.py rename to Lib/test/typinganndata/inspect.py From ad19bf6278c7caaf826f466aeef0430377944694 Mon Sep 17 00:00:00 2001 From: iyume Date: Sat, 3 Sep 2022 20:11:40 +0800 Subject: [PATCH 6/6] rename inspect.py to ann_module9.py --- Lib/test/test_inspect.py | 2 +- Lib/test/typinganndata/{inspect.py => ann_module9.py} | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) rename Lib/test/typinganndata/{inspect.py => ann_module9.py} (69%) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index b561d52a1bb5de..c030be77e80fb5 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1423,7 +1423,7 @@ def wrapper(a, b): class TestFormatAnnotation(unittest.TestCase): def test_typing_replacement(self): - from test.typinganndata.inspect import ann, ann1 + from test.typinganndata.ann_module9 import ann, ann1 self.assertEqual(inspect.formatannotation(ann), 'Union[List[str], int]') self.assertEqual(inspect.formatannotation(ann1), 'Union[List[testModule.typing.A], int]') diff --git a/Lib/test/typinganndata/inspect.py b/Lib/test/typinganndata/ann_module9.py similarity index 69% rename from Lib/test/typinganndata/inspect.py rename to Lib/test/typinganndata/ann_module9.py index 290c66886c644b..952217393e1ff7 100644 --- a/Lib/test/typinganndata/inspect.py +++ b/Lib/test/typinganndata/ann_module9.py @@ -1,4 +1,5 @@ -# This module is for test_inspect formatannotation +# Test ``inspect.formatannotation`` +# https://github.com/python/cpython/issues/96073 from typing import Union, List