2

Previously I've used Signature.bind(argument_dict) to turn argument dictionary into BoundArguments object that has .args and .kwargs that can be passed to a function.

def foo(a: str, b: str, c: str): ...
    
argument_dict= {"a": "A", "c": "C", "b": "B"}

import inspect
sig = inspect.signature(foo)

bound_arguments = sig.bind(**argument_dict)
foo(*bound_arguments.args, **bound_arguments.kwargs)

But this does not seem to be possible when the function has positional-only parameters.

def foo(a: str, /, b: str, *, c: str): ...
    
import inspect
sig = inspect.signature(foo)

argument_dict= {"a": "A", "b": "B", "c": "C"}
bound_arguments = sig.bind(**argument_dict) # Error: "a" is positional-only

How do I programmatically call the function in this case?

Is these a native way to construct BoundArguments from an argument dictionary?

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
Ark-kun
  • 6,358
  • 2
  • 34
  • 70

1 Answers1

3

I could only find something like this, consuming the positional only parameters from the dict:

pos_only = [k for k, v in sig.parameters.items() if v.kind is inspect.Parameter.POSITIONAL_ONLY]
positionals = [argument_dict.pop(k) for k in pos_only]
bound_arguments = sig.bind(*positionals, **argument_dict)
wim
  • 338,267
  • 99
  • 616
  • 750