click-contrib / click-plugins Goto Github PK
View Code? Open in Web Editor NEWRegister CLI commands via setuptools entry-points.
License: Other
Register CLI commands via setuptools entry-points.
License: Other
pkg_resources
is deprecated, it would be nice have the docs clarify how to use click-plugins
with importlib_metadata
/ importlib.metadata
instead.
ATTENTION
Use of pkg_resources is deprecated in favor of importlib.resources, importlib.metadata and their backports (importlib_resources, importlib_metadata). Some useful APIs are also provided by packaging (e.g. requirements and version parsing). Users should refrain from new usage of pkg_resources and should work to port to importlib-based solutions.
I've replaced this:
from pkg_resources import iter_entry_points
import click
from click_plugins import with_plugins
@with_plugins(iter_entry_points('core_package.cli_plugins'))
@click.group()
def cli():
"""Commandline interface for yourpackage."""
with this:
import click
from click_plugins import with_plugins
from importlib_metadata import entry_points
@with_plugins(entry_points(group='core_package.cli_plugins'))
@click.group()
def cli():
"""Commandline interface for yourpackage."""
The above code is compatible with importlib-metadata>=3.6
As reported by Adrian Bunk in Debian Bug #908684, the python-click-plugins package fails to build with python-click 6.7+git20180829-1 due to a test failure:
I: pybuild pybuild:269: cp -r /build/python-click-plugins-1.0.2/tests /build/python-click-plugins-1.0.2/.pybuild/cpython2_2.7_click-plugins/build
I: pybuild base:217: cd /build/python-click-plugins-1.0.2/.pybuild/cpython2_2.7_click-plugins/build; python2.7 -m pytest tests
============================= test session starts ==============================
platform linux2 -- Python 2.7.15+, pytest-3.6.4, py-1.6.0, pluggy-0.6.0
rootdir: /build/python-click-plugins-1.0.2, inifile:
collected 5 items
tests/test_plugins.py ...F. [100%]
=================================== FAILURES ===================================
_______________________________ test_group_chain _______________________________
runner = <click.testing.CliRunner object at 0x7f9d888d9050>
def test_group_chain(runner):
# Attach a sub-group to a CLI and get execute it without arguments to make
# sure both the sub-group and all the parent group's commands are present
@good_cli.group()
def sub_cli():
"""Sub CLI."""
pass
result = runner.invoke(good_cli)
assert result.exit_code is 0
assert sub_cli.name in result.output
for ep in iter_entry_points('_test_click_plugins.test_plugins'):
assert ep.name in result.output
# Same as above but the sub-group has plugins
@with_plugins(plugins=iter_entry_points('_test_click_plugins.test_plugins'))
@good_cli.group()
def sub_cli_plugins():
"""Sub CLI with plugins."""
pass
result = runner.invoke(good_cli, ['sub_cli_plugins'])
> assert result.exit_code is 0
E assert 2 is 0
E + where 2 = <Result SystemExit(2,)>.exit_code
tests/test_plugins.py:124: AssertionError
====================== 1 failed, 4 passed in 0.12 seconds ======================
E: pybuild pybuild:338: test: plugin distutils failed with: exit code=1: cd /build/python-click-plugins-1.0.2/.pybuild/cpython2_2.7_click-plugins/build; python2.7 -m pytest tests
The python-click package was recently updated to a git snapshot which likely changed the behaviour.
Whoa the docs have some poorly worded sections... MY BAD.
Using the @with_plugins()
decorator generates a type error in PyCharm (but not with mypy) when using CliRunner.invoke()
:
In the above code, removing the @with_plugins()
decorator also removes the type error.
This is obviously a minor issue since mypy doesn't generate an error (so CI pipeline are fine), but since CliRunner is widely used in tests, it would be nice if this type error could be suppressed.
As indicated by pypa/setuptools#510, pkg_resources
is known to be slow. click-plugins
leverages setuptools
entry points to load CLI plugin commands but this comes with a performance hit for the entire CLI application. I don't think there is anything to be done about it directly but it is worth documenting the behavior and trying fast-entry_points
.
@untitaker looks like owners are the only ones that can enable Travis and coveralls. I requested access for coveralls but I didn't see click-plugins
anywhere in Travis. When you get a chance, and assuming you're ok with both of these services, could you enable them?
v1
branchTypo fix in error message.
Is there any support for altering the usage statement to list plugin commands separately? Right now they are intermingled with the main command, but this is not desirable when a clean separation is desired between "core" and plugin commands in complicated applications.
Here is the current output (with one plugin command):
Usage: labdata [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands:
create-views
import-map-data Import WiscAr MAP spectrometer data (ArArCalc files) in...
init
serve
shell
Instead I'd want something like this:
Usage: labdata [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Commands [core]:
create-views
init
serve
shell
Commands [WiscAr]:
import-map-data Import WiscAr MAP spectrometer data (ArArCalc files) in...
Looking at the Click
documentation it looks as if they don't support reformatting help pages, so this might be an upstream issue.
Packaging improvements.
Hi I am using ubuntu 20.04 LTS.
I am going the long bumpy paths of installing gnuradio with pybombs. I did came accross this error:
[ERROR] Package has no install method: python-click-plugins
I did installed it with pip also directly from source as described and run also sudo ldconfig but the error remains... :(
Please help!!
Thank you
Is there a way to replace an existing command with a different implementation using click-plugins?
Will it just work out of the box?
BrokenCommand provides a useful trace when an entrypoint fails to import.
(.venv) project> cli run
Warning: entry point could not be loaded. Contact its author for help.
Traceback (most recent call last):
File "/home/merlin/workspace/xxx/.venv/lib/python3.6/site-packages/click_plugins/core.py", line 37, in decorator
group.add_command(entry_point.load())
File "/home/merlin/workspace/xxx/.venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2228, in load
self.require(*args, **kwargs)
File "/home/merlin/workspace/xxx/.venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2245, in require
items = working_set.resolve(reqs, env, installer)
File "/home/merlin/workspace/xxx/.venv/lib/python3.6/site-packages/pkg_resources/__init__.py", line 834, in resolve
raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (xxx 0.3.5 (/home/merlin/workspace/xxx), Requirement.parse('xxx<0.5,>=0.4'), {'yyy'})
But if that entrypoint accepts arguments the BrokenCommand swallows the traceback and produces
a misleading error.
(.venv) project> cli run -c config.yaml --log-level INFO
Usage: cli run [OPTIONS]
Try "cli run --help" for help.
Error: no such option: -c
(Sorry that this is probably a bit more of a help question than an issue, but it didn't look like there was much activity on SO for click-plugins ...)
I'm trying to register a click group as both a console script and a click plugin. Assuming my CLI code for the plugin looks like this:
import click
@click.group()
def main_group():
"""
Root plugin group
"""
@main_group.command(
'subcommand_1',
short_help='Subcommand #1'
)
def subcommand_1():
print('This is subcommand #1')
and the entry_points
section of setup.py
looks like this:
entry_points='''
[console_scripts]
foo=root_plugin.cli:main_group
[root.plugins]
plugin=root_plugin.cli:main_group
'''
When I run the main root console script, I get this:
Usage: root [OPTIONS] COMMAND [ARGS]...
Root command line interface
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
main_group Root plugin group
I was expecting that main_group
would have been called plugin
instead based on the entry point. Note that using the foo
console script works as expected. In the examples I've seen, the plugin alias always matches the click group name, e.g. here, but is it possible to give it a different alias?
There really isn't a need for the user to be doing:
from pkg_resources import iter_entry_points
from click_plugins import with_plugins
@with_plugins(iter_entry_points(entry.point))
When they could just do:
from click_plugins import with_plugins
@with_plugins('entry.point1', 'ep.2')
It seems that plugin names are not properly massaged for use as environment variable names. This conflicts with plugins that have a dot in their name:
entry_points={
"my_plugins": [
"plugin.foo=myproject.plugins.foo:foo_cmd"
]
}
the help text for a parameter "bar" shows "MYPROJECT_PLUGIN.FOO_BAR" which is an invalid envvar name in most environments.
I'm not sure if this is actually a click issue so I'm asking here first for a fix or clarification.
A reminder to future me from current me so I don't forget to set this thing up.
If any package dependency is not met the entry point fails to load. Even if this does not impact the functioning of the CLI at all
Could this be replaced by a warning?
E.g.
Traceback (most recent call last):
File "/opt/conda/envs/vds-37/lib/python3.7/site-packages/click_plugins/core.py", line 37, in decorator
group.add_command(entry_point.load())
File "/opt/conda/envs/vds-37/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2442, in load
self.require(*args, **kwargs)
File "/opt/conda/envs/vds-37/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2465, in require
items = working_set.resolve(reqs, env, installer, extras=self.extras)
File "/opt/conda/envs/vds-37/lib/python3.7/site-packages/pkg_resources/__init__.py", line 791, in resolve
raise VersionConflict(dist, req).with_context(dependent_req)
pkg_resources.ContextualVersionConflict: (docutils 0.16 (/opt/conda/envs/vds-37/lib/python3.7/site-packages), Requirement.parse('docutils<0.16,>=0.10'), {'botocore'})
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.