Skip to content

functions with kwargs #114

Closed
Closed
@HeinrichAD

Description

@HeinrichAD

The signature binding fails if the function contains kwarg_sources.

Reproduce

from varname import nameof

def fn(var, **kwargs):
    print(nameof(var, frame=2))
    # ...

x = 5
fn(x)       # OK
fn(x, y=6)  # Error
Traceback
Traceback (most recent call last):
  File "/home/hein_f0/dev/slki-code/.venv/lib/python3.11/site-packages/varname/core.py", line 469, in argname
    argument_sources = get_argument_sources(
                       ^^^^^^^^^^^^^^^^^^^^^
  File "/home/hein_f0/dev/slki-code/.venv/lib/python3.11/site-packages/varname/utils.py", line 442, in get_argument_sources
    bound_args = signature.bind_partial(*arg_sources, **kwarg_sources)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/inspect.py", line 3219, in bind_partial
    return self._bind(args, kwargs, partial=True)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/inspect.py", line 3201, in _bind
    raise TypeError(
TypeError: got an unexpected keyword argument 'y'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/hein_f0/dev/slki-code/test.py", line 11, in <module>
    fn(x, y=6)  # Error
    ^^^^^^^^^^
  File "/home/hein_f0/dev/slki-code/test.py", line 5, in fn
    print(nameof(var, frame=2))
          ^^^^^^^^^^^^^^^^^^^^
  File "/home/hein_f0/dev/slki-code/.venv/lib/python3.11/site-packages/varname/core.py", line 333, in nameof
    out = argname(
          ^^^^^^^^
  File "/home/hein_f0/dev/slki-code/.venv/lib/python3.11/site-packages/varname/core.py", line 476, in argname
    raise ImproperUseError(
varname.utils.ImproperUseError: Have you specified the right `frame` or `func`?

Problem

If I am not mistaken, the issue lies in line 442:

signature = inspect.signature(func, follow_wrapped=False)
# func(y, x, c=z)
# ['y', 'x'], {'c': 'z'}
arg_sources = [
argnode_source(source, argnode, vars_only) for argnode in node.args
]
kwarg_sources = {
argnode.arg: argnode_source(source, argnode.value, vars_only)
for argnode in node.keywords
if argnode.arg is not None
}
bound_args = signature.bind_partial(*arg_sources, **kwarg_sources)

The signature here is the nameof function: <Signature (var: Any, *more_vars: Any, frame: int = 1, vars_only: bool = True) -> Union[str, Tuple[str, ...]]> and therefore does not take any kwarg_sources from the source function fn.

Workaround

None, as far as I know.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions