epsy / clize

CLIze: Turn Python functions into command-line interfaces
http://clize.readthedocs.io/
MIT License
480 stars 26 forks source link

KeyError when decorator rewrites varargs #46

Open bersace opened 6 years ago

bersace commented 6 years ago

Hi,

$ pip show clize
Name: clize
Version: 4.0.3
Summary: Turn functions into command-line interfaces
Home-page: https://github.com/epsy/clize
Author: Yann Kaiser
Author-email: kaiser.yann@gmail.com
License: MIT
Location: .../lib/python3.6/site-packages
Requires: docutils, six, sigtools, od, attrs

Here is a sample program to reproduce the traceback.

from sigtools.wrappers import decorator
from clize import run

@decorator
def f(a, *args, name=False, **kwargs):
    args = args
    return a(*args, **kwargs)

@f
def g():
    pass

run(g)

Here is the crash :

$ python -m pdb my-sigtool.py  --help
Traceback (most recent call last):
  File "my-sigtool.py", line 16, in <module>
    run(g)
  File ".../lib/python3.6/site-packages/sigtools/modifiers.py", line 158, in __call__
    return self.func(*args, **kwargs)
  File ".../lib/python3.6/site-packages/clize/runner.py", line 360, in run
    ret = cli(*args)
  File ".../lib/python3.6/site-packages/clize/runner.py", line 220, in __call__
    return func(*posargs, **kwargs)
  File ".../lib/python3.6/site-packages/clize/runner.py", line 220, in __call__
    return func(*posargs, **kwargs)
  File ".../lib/python3.6/site-packages/sigtools/modifiers.py", line 158, in __call__
    return self.func(*args, **kwargs)
  File ".../lib/python3.6/site-packages/clize/help.py", line 887, in cli
    help = self.get_help()
  File ".../lib/python3.6/site-packages/clize/help.py", line 896, in get_help
    return self.builder(self.subject, self.owner)
  File ".../lib/python3.6/site-packages/clize/help.py", line 449, in from_subject
    ret.add_from_parameter_sources(subject)
  File ".../lib/python3.6/site-packages/clize/help.py", line 491, in add_from_parameter_sources
    for func in func_signature.sources[pname]:
KeyError: 'args'
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> .../lib/python3.6/site-packages/clize/help.py(491)add_from_parameter_sources()
-> for func in func_signature.sources[pname]:
(Pdb) pp func_signature.sources
{'+depths': {<function g at 0x7f700f11f950>: 3,
             <function _SimpleWrapped.__call__ at 0x7f70113f89d8>: 0,
             <function f at 0x7f7011d7d950>: 2,
             functools.partial(<function f at 0x7f7011d7d950>, <function g at 0x7f700f11f950>): 1},
 'name': [<function f at 0x7f7011d7d950>]}
(Pdb)

I expect a more insightful error. I'm wondering wheither the bug is in clize or sigtools.

I found a workaround : i edit kwargs instead of varargs.

maxxungao commented 2 years ago

I ran into this too. A more general way to reproduce this is:

from clize import run

def f1(a, *others):
    pass

def f2(b, *others):
    f1(b, *others)

run(f2)

Basically, this happens if the function (f2) has a parameter and it calls another function (f1) with a parameter of the same name, forwarding the parameter as is. In this case, the sigtools will remove the parameter from func_signature.sources thus cause the error.