Skip to content

Commit

Permalink
placeholder arg and pre-placeholder instance conversions to positional
Browse files Browse the repository at this point in the history
  • Loading branch information
dg-pb committed Jun 25, 2024
1 parent 1185510 commit 266b4fa
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
2 changes: 0 additions & 2 deletions Doc/library/functools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,6 @@ The :mod:`functools` module defines the following functions:

>>> from functools import partial, Placeholder
>>> say_to_world = partial(print, Placeholder, Placeholder, "world!")
>>> say_to_world.placeholder_count
2
>>> say_to_world('Hello', 'dear')
Hello dear world!

Expand Down
15 changes: 12 additions & 3 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -2052,9 +2052,13 @@ def _signature_get_partial(wrapped_sig, partial, extra_args=()):
new_params[param_name] = param.replace(default=arg_value)
else:
# was passed as a positional argument
# But do not remove if it is a Placeholder
if arg_value is not functools.Placeholder:
new_params.pop(param.name)
# Do not pop if it is a Placeholder
# and change kind to positional only
if arg_value is functools.Placeholder:
new_param = param.replace(kind=_POSITIONAL_ONLY)
new_params[param_name] = new_param
else:
new_params.pop(param_name)
continue

if param.kind is _KEYWORD_ONLY:
Expand Down Expand Up @@ -2548,6 +2552,11 @@ def _signature_from_callable(obj, *,
sig_params = tuple(sig.parameters.values())
assert (not sig_params or
first_wrapped_param is not sig_params[0])
# If there were placeholders set,
# first param is transformaed to positional only
if partialmethod.args.count(functools.Placeholder):
first_wrapped_param = first_wrapped_param.replace(
kind=Parameter.POSITIONAL_ONLY)
new_params = (first_wrapped_param,) + sig_params
return sig.replace(parameters=new_params)

Expand Down
19 changes: 14 additions & 5 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -3311,13 +3311,13 @@ def test(a, b, *, c, d):

# With Placeholder
self.assertEqual(self.signature(partial(test, Placeholder, 1)),
((('a', ..., ..., "positional_or_keyword"),
((('a', ..., ..., "positional_only"),
('c', ..., ..., "keyword_only"),
('d', ..., ..., "keyword_only")),
...))

self.assertEqual(self.signature(partial(test, Placeholder, 1, c=2)),
((('a', ..., ..., "positional_or_keyword"),
((('a', ..., ..., "positional_only"),
('c', 2, ..., "keyword_only"),
('d', ..., ..., "keyword_only")),
...))
Expand Down Expand Up @@ -3369,6 +3369,15 @@ def test(a, *args, b, **kwargs):
('kwargs', ..., ..., "var_keyword")),
...))

# With Placeholder
p = partial(test, Placeholder, Placeholder, 1, b=0, test=1)
self.assertEqual(self.signature(p),
((('a', ..., ..., "positional_only"),
('args', ..., ..., "var_positional"),
('b', 0, ..., "keyword_only"),
('kwargs', ..., ..., "var_keyword")),
...))

def test(a, b, c:int) -> 42:
pass

Expand Down Expand Up @@ -3505,12 +3514,12 @@ def test(it, a, b, *, c) -> 'spam':

# With Placeholder
self.assertEqual(self.signature(Spam.bar, eval_str=False),
((('it', ..., ..., 'positional_or_keyword'),
('a', ..., ..., 'positional_or_keyword'),
((('it', ..., ..., 'positional_only'),
('a', ..., ..., 'positional_only'),
('c', 1, ..., 'keyword_only')),
'spam'))
self.assertEqual(self.signature(Spam().bar, eval_str=False),
((('a', ..., ..., 'positional_or_keyword'),
((('a', ..., ..., 'positional_only'),
('c', 1, ..., 'keyword_only')),
'spam'))

Expand Down

0 comments on commit 266b4fa

Please sign in to comment.