I wanted to test following code from Tutorial but I get a TypeError: 'NoneType' object does not support item assignment
@click.group()
@click.option('--debug/--no-debug', default=False)
@click.pass_context
def cli(ctx, debug):
ctx.obj['DEBUG'] = debug
@cli.command()
@click.pass_context
def sync(ctx):
click.echo('Debug is %s' % (ctx.obj['DEBUG'] and 'on' or 'off'))
if __name__ == '__main__':
cli(obj={})
Where is the Error? Please fix tutorial? :8ball:
The code works. I just verified it.
You're right. Sorry. Somehow I can't reproduce the error.
@mitsuhiko: Unfortunately the code really does not work. I'm getting the same error on Fedora 22 as @OnionNinja:
[para@sanitarium clicktest]$ sudo python setup.py develop
[para@sanitarium clicktest]$ python clicktest.py test
(<click.core.Context object at 0x7f85bdaa0210>, {})
False
[para@sanitarium clicktest]$ clicktest test
(<click.core.Context object at 0x7f3a6556a390>, None)
Traceback (most recent call last):
File "/usr/bin/clicktest", line 9, in <module>
load_entry_point('clicktest==0.0.1', 'console_scripts', 'clicktest')()
File "/usr/lib/python2.7/site-packages/click/core.py", line 700, in __call__
return self.main(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/click/core.py", line 680, in main
rv = self.invoke(ctx)
File "/usr/lib/python2.7/site-packages/click/core.py", line 1024, in invoke
Command.invoke(self, ctx)
File "/usr/lib/python2.7/site-packages/click/core.py", line 873, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python2.7/site-packages/click/core.py", line 508, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/click/decorators.py", line 16, in new_func
return f(get_current_context(), *args, **kwargs)
File "build/bdist.linux-x86_64/egg/clicktest.py", line 16, in entry
TypeError: 'NoneType' object does not support item assignment
[para@sanitarium clicktest]$
I tried using Click4 and Click5 from Fedora RPMs. First I was blaming packaging, so I switched to pip version, but it did not help. Even switching from Python2.7 to Python3.4 didn't help. Code generating the exception can be seen here.
That's because you are using entry points and the entry point points to cli and that one is not passed the object. Only your __main__ is.
You will have to do something like this:
def main():
return entry(obj={})
And then point your setuptools entry point to main and not entry.
A better idea is to use make_pass_decorator however which can automatically create this object on first use.
Thanks for help.
Hello from 2.5 years in the future. I really appreciate this library but bumped into the same problem. Thanks @mitsuhiko for explaining a solution.
I'm wondering if this could be better documented in the click documentation. Possibly as a warning on that tutorial, since, at that stage, the click documentation does expect you to be using setuptools. Thoughts?
The example code from @paramite isn't there anymore, so it's kind of hard to tell what @mitsuhiko was referencing. I'm running into this currently.
I had this problem unit testing my CLI using click's CLI runner and eventually figured out it was because I wasn't passing the dict I was trying to use to the context in the invoke method. If this is your issue, make sure you add the necessary kwarg to invoke like so (assuming you want your context to contain a dict called obj): runner.invoke(main, ['command'], obj={})
Most helpful comment
That's because you are using entry points and the entry point points to
cliand that one is not passed the object. Only your__main__is.You will have to do something like this:
And then point your setuptools entry point to
mainand notentry.