From ee40b3e20d9b8d62a9b36b777dff42db1e9049d5 Mon Sep 17 00:00:00 2001 From: "Erlend E. Aasland" Date: Sun, 13 Aug 2023 01:46:00 +0200 Subject: [PATCH] gh-107883: Argument Clinic: Handle full module/class path in Function.fulldisplayname (#107884) Co-authored-by: Alex Waygood --- Lib/test/test_clinic.py | 54 +++++++++++++++++++++++++++++++++++++++++ Tools/clinic/clinic.py | 13 +++++++--- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index a649b5fe2201c8..55251b516d2b2f 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -1513,6 +1513,60 @@ def test_parameters_required_after_star(self): with self.subTest(block=block): self.expect_failure(block, err) + def test_fulldisplayname_class(self): + dataset = ( + ("T", """ + class T "void *" "" + T.__init__ + """), + ("m.T", """ + module m + class m.T "void *" "" + @classmethod + m.T.__new__ + """), + ("m.T.C", """ + module m + class m.T "void *" "" + class m.T.C "void *" "" + m.T.C.__init__ + """), + ) + for name, code in dataset: + with self.subTest(name=name, code=code): + block = self.parse(code) + func = block.signatures[-1] + self.assertEqual(func.fulldisplayname, name) + + def test_fulldisplayname_meth(self): + dataset = ( + ("func", "func"), + ("m.func", """ + module m + m.func + """), + ("T.meth", """ + class T "void *" "" + T.meth + """), + ("m.T.meth", """ + module m + class m.T "void *" "" + m.T.meth + """), + ("m.T.C.meth", """ + module m + class m.T "void *" "" + class m.T.C "void *" "" + m.T.C.meth + """), + ) + for name, code in dataset: + with self.subTest(name=name, code=code): + block = self.parse(code) + func = block.signatures[-1] + self.assertEqual(func.fulldisplayname, name) + def test_depr_star_invalid_format_1(self): block = """ module foo diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 70b066cce82fae..2d23f9d12875ff 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2682,9 +2682,16 @@ def displayname(self) -> str: @functools.cached_property def fulldisplayname(self) -> str: - if isinstance(self.module, Module): - return f"{self.module.name}.{self.displayname}" - return self.displayname + parent: Class | Module | Clinic | None + if self.kind.new_or_init: + parent = getattr(self.cls, "parent", None) + else: + parent = self.parent + name = self.displayname + while isinstance(parent, (Module, Class)): + name = f"{parent.name}.{name}" + parent = parent.parent + return name @property def render_parameters(self) -> list[Parameter]: