You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
With argument autocompletion, context is not passed properly #942
Now I am getting an error when trying to use autocompletion:
$ ./testclick subcommand <TAB>Traceback (most recent call last):
File "./testclick", line 23, in <module>
entrypoint(obj={'completions': ['abc', 'def', 'ghi', ]})
File "/home/user/testclick/venv/lib/python3.6/site-packages/click/core.py", line 731, in __call__
return self.main(*args, **kwargs)
File "/home/user/testclick/venv/lib/python3.6/site-packages/click/core.py", line 701, in main
_bashcomplete(self, prog_name, complete_var)
File "/home/user/testclick/venv/lib/python3.6/site-packages/click/core.py", line 46, in _bashcomplete
if bashcomplete(cmd, prog_name, complete_var, complete_instr):
File "/home/user/testclick/venv/lib/python3.6/site-packages/click/_bashcomplete.py", line 216, in bashcomplete
return do_complete(cli, prog_name)
File "/home/user/testclick/venv/lib/python3.6/site-packages/click/_bashcomplete.py", line 205, in do_complete
for item in get_choices(cli, prog_name, args, incomplete):
File "/home/user/testclick/venv/lib/python3.6/site-packages/click/_bashcomplete.py", line 186, in get_choices
ctx, all_args, incomplete, param))
File "/home/user/testclick/venv/lib/python3.6/site-packages/click/_bashcomplete.py", line 124, in get_user_autocompletions
incomplete=incomplete)
File "./testclick", line 7, in _complete
return ctx.obj['completions']
TypeError: 'NoneType' object is not subscriptable
Expected behavior was to get a list of completions abc def ghi.
@LuckyJosh: Thanks for the hint, but that won’t suffice as a workaround. In the above example, I provided completions as a static dictionary just for the sake of simplicity. In my case, a network connection object would be passed via the context, and the _complete function would use it to retrieve possible completions. I don’t think context_settings can be used for that.
Alright, in that case I have another idea:
Are you sure that the kwarg obj to entrypoint should get passed to the context?
After having a glimps at the implementation of pass_context I would suspect, that obj={...} just get passed to the wrapped function and is not used any further. The context is passed as the first argument to the decorated function without any interaction with the other arguments it would seem.
This would explain the missing (None) ctx.obj the ErrorMessage is about.
The source code I am refering to is in decorators.py.
I don't understand what LuckyJosh is trying to say.
The custom context with obj attached is normally created in BaseCommand.main(). The problem is that in autocomplete mode, _bashcomplete() gets called before the context-creation code executes, and creates its own context (without obj) instead.
It looks to me like we want BaseCommand.main() to create its context in all circumstances, and pass it to _bashcomplete(). Would there be any drawbacks to this?
for now i'm doing things like this to at least init state based on env variables before calling out:
def get_entities(ctx, args, incomplete):
if not hasattr(ctx, 'server'):
ctx.server = os.environ.get('HASS_SERVER', const.DEFAULT_SERVER)
if not hasattr(ctx, 'token'):
ctx.token = os.environ.get('HASS_TOKEN')
if not hasattr(ctx, "timeout"):
ctx.timeout = os.environ.get('HASS_TIMEOUT', const.DEFAULT_TIMEOUT)
try:
x = req(ctx, "get", "states")
except HTTPError:
x = None
entities = []
if x is not None:
for entity in x:
entities.append((entity["entity_id"], ''))
return [c for c in entities if incomplete in c[0]]
else:
return entities
this lets the autocompletion work but its unforunate I have to relist the defaults and env parameters here. would be so much nicer if there was a way click could pass the right context or i at least could call something to generate the proper config/context.
Activity
LuckyJosh commentedon Mar 4, 2018
Im currently not able to test my idea, so please excuse me if for just thinking out loud. 😉
Instead of passing the settings dict to
entrypointyou could try passing it to thecontext_settingskwarg of the.groupor.commandfunction.Refer to the documentation for details:
http://click.pocoo.org/5/commands/#context-defaults
fqxp commentedon Mar 4, 2018
@LuckyJosh: Thanks for the hint, but that won’t suffice as a workaround. In the above example, I provided completions as a static dictionary just for the sake of simplicity. In my case, a network connection object would be passed via the context, and the
_completefunction would use it to retrieve possible completions. I don’t thinkcontext_settingscan be used for that.LuckyJosh commentedon Mar 5, 2018
Alright, in that case I have another idea:
Are you sure that the kwarg
objtoentrypointshould get passed to the context?After having a glimps at the implementation of
pass_contextI would suspect, thatobj={...}just get passed to the wrapped function and is not used any further. The context is passed as the first argument to the decorated function without any interaction with the other arguments it would seem.This would explain the missing (
None)ctx.objthe ErrorMessage is about.The source code I am refering to is in
decorators.py.foresto commentedon Jul 4, 2018
I don't understand what LuckyJosh is trying to say.
The custom context with
objattached is normally created in BaseCommand.main(). The problem is that in autocomplete mode, _bashcomplete() gets called before the context-creation code executes, and creates its own context (withoutobj) instead.It looks to me like we want BaseCommand.main() to create its context in all circumstances, and pass it to _bashcomplete(). Would there be any drawbacks to this?
Possibly related: #930
+1 on this issue. I, too, am trying to get autocomplete working with completions that come from network calls.
foresto commentedon Jul 5, 2018
To be clear, this issue limits the utility of #755. Until it is fixed, autocompletion callbacks have no clean way to access shared network resources.
maxandersen commentedon Nov 18, 2018
anyone found a workaround on this ?
for now i'm doing things like this to at least init state based on env variables before calling out:
this lets the autocompletion work but its unforunate I have to relist the defaults and env parameters here. would be so much nicer if there was a way click could pass the right context or i at least could call something to generate the proper config/context.
thx!
diegoroccia commentedon Oct 19, 2019
davidag commentedon Oct 23, 2019
I'm facing this issue too.
For now, my workaround is to factor out the
ctx.objcreation code and call it from bothcli()and the corresponding autocomplete methods.