Skip to content

Commit 044b8b3

Browse files
gh-107805: Fix signatures of module-level generated functions in turtle (#107807)
Co-authored-by: Alex Waygood <[email protected]>
1 parent 3edcf74 commit 044b8b3

File tree

3 files changed

+45
-19
lines changed

3 files changed

+45
-19
lines changed

Lib/test/test_turtle.py

+20
Original file line numberDiff line numberDiff line change
@@ -461,5 +461,25 @@ def test_teleport(self):
461461
self.assertTrue(tpen.isdown())
462462

463463

464+
class TestModuleLevel(unittest.TestCase):
465+
def test_all_signatures(self):
466+
import inspect
467+
468+
known_signatures = {
469+
'teleport':
470+
'(x=None, y=None, *, fill_gap: bool = False) -> None',
471+
'undo': '()',
472+
'goto': '(x, y=None)',
473+
'bgcolor': '(*args)',
474+
'pen': '(pen=None, **pendict)',
475+
}
476+
477+
for name in known_signatures:
478+
with self.subTest(name=name):
479+
obj = getattr(turtle, name)
480+
sig = inspect.signature(obj)
481+
self.assertEqual(str(sig), known_signatures[name])
482+
483+
464484
if __name__ == '__main__':
465485
unittest.main()

Lib/turtle.py

+24-19
Original file line numberDiff line numberDiff line change
@@ -3920,28 +3920,33 @@ def getmethparlist(ob):
39203920
function definition and the second is suitable for use in function
39213921
call. The "self" parameter is not included.
39223922
"""
3923-
defText = callText = ""
3923+
orig_sig = inspect.signature(ob)
39243924
# bit of a hack for methods - turn it into a function
39253925
# but we drop the "self" param.
39263926
# Try and build one for Python defined functions
3927-
args, varargs, varkw = inspect.getargs(ob.__code__)
3928-
items2 = args[1:]
3929-
realArgs = args[1:]
3930-
defaults = ob.__defaults__ or []
3931-
defaults = ["=%r" % (value,) for value in defaults]
3932-
defaults = [""] * (len(realArgs)-len(defaults)) + defaults
3933-
items1 = [arg + dflt for arg, dflt in zip(realArgs, defaults)]
3934-
if varargs is not None:
3935-
items1.append("*" + varargs)
3936-
items2.append("*" + varargs)
3937-
if varkw is not None:
3938-
items1.append("**" + varkw)
3939-
items2.append("**" + varkw)
3940-
defText = ", ".join(items1)
3941-
defText = "(%s)" % defText
3942-
callText = ", ".join(items2)
3943-
callText = "(%s)" % callText
3944-
return defText, callText
3927+
func_sig = orig_sig.replace(
3928+
parameters=list(orig_sig.parameters.values())[1:],
3929+
)
3930+
3931+
call_args = []
3932+
for param in func_sig.parameters.values():
3933+
match param.kind:
3934+
case (
3935+
inspect.Parameter.POSITIONAL_ONLY
3936+
| inspect.Parameter.POSITIONAL_OR_KEYWORD
3937+
):
3938+
call_args.append(param.name)
3939+
case inspect.Parameter.VAR_POSITIONAL:
3940+
call_args.append(f'*{param.name}')
3941+
case inspect.Parameter.KEYWORD_ONLY:
3942+
call_args.append(f'{param.name}={param.name}')
3943+
case inspect.Parameter.VAR_KEYWORD:
3944+
call_args.append(f'**{param.name}')
3945+
case _:
3946+
raise RuntimeError('Unsupported parameter kind', param.kind)
3947+
call_text = f'({', '.join(call_args)})'
3948+
3949+
return str(func_sig), call_text
39453950

39463951
def _turtle_docrevise(docstr):
39473952
"""To reduce docstrings from RawTurtle class for functions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix signatures of module-level generated functions in :mod:`turtle`.

0 commit comments

Comments
 (0)