summaryrefslogtreecommitdiffstats
path: root/Lib/inspect.py
diff options
context:
space:
mode:
authordgpb <3577712+dg-pb@users.noreply.github.com>2024-09-26 01:04:38 (GMT)
committerGitHub <noreply@github.com>2024-09-26 01:04:38 (GMT)
commitd9296529eb0a65f988e8600d3073977dff0ce5a9 (patch)
tree4874e745e6856305ee27feb828b14bad52ddccc2 /Lib/inspect.py
parent4defb58d3812a80d556410077e3391bb81a1c0b7 (diff)
downloadcpython-d9296529eb0a65f988e8600d3073977dff0ce5a9.zip
cpython-d9296529eb0a65f988e8600d3073977dff0ce5a9.tar.gz
cpython-d9296529eb0a65f988e8600d3073977dff0ce5a9.tar.bz2
gh-119127: functools.partial placeholders (gh-119827)
Diffstat (limited to 'Lib/inspect.py')
-rw-r--r--Lib/inspect.py24
1 files changed, 22 insertions, 2 deletions
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 90c44cf..2b25300 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -1930,7 +1930,12 @@ def _signature_get_partial(wrapped_sig, partial, extra_args=()):
if param.kind is _POSITIONAL_ONLY:
# If positional-only parameter is bound by partial,
# it effectively disappears from the signature
- new_params.pop(param_name)
+ # However, if it is a Placeholder it is not removed
+ # And also looses default value
+ if arg_value is functools.Placeholder:
+ new_params[param_name] = param.replace(default=_empty)
+ else:
+ new_params.pop(param_name)
continue
if param.kind is _POSITIONAL_OR_KEYWORD:
@@ -1952,7 +1957,17 @@ 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
- new_params.pop(param.name)
+ # Do not pop if it is a Placeholder
+ # also change kind to positional only
+ # and remove default
+ if arg_value is functools.Placeholder:
+ new_param = param.replace(
+ kind=_POSITIONAL_ONLY,
+ default=_empty
+ )
+ new_params[param_name] = new_param
+ else:
+ new_params.pop(param_name)
continue
if param.kind is _KEYWORD_ONLY:
@@ -2446,6 +2461,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 transformed 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)