New upstream version 6.7
This commit is contained in:
parent
5cd05ec3cc
commit
e5fe171691
11
CHANGES
11
CHANGES
|
@ -3,6 +3,17 @@ Click Changelog
|
||||||
|
|
||||||
This contains all major version changes between Click releases.
|
This contains all major version changes between Click releases.
|
||||||
|
|
||||||
|
Version 6.7
|
||||||
|
-----------
|
||||||
|
|
||||||
|
(bugfix release; released on January 6th 2017)
|
||||||
|
|
||||||
|
- Make `click.progressbar` work with `codecs.open` files. See #637.
|
||||||
|
- Fix bug in bash completion with nested subcommands. See #639.
|
||||||
|
- Fix test runner not saving caller env correctly. See #644.
|
||||||
|
- Fix handling of SIGPIPE. See #626
|
||||||
|
- Deal with broken Windows environments such as Google App Engine's. See #711.
|
||||||
|
|
||||||
Version 6.6
|
Version 6.6
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|
2
PKG-INFO
2
PKG-INFO
|
@ -1,6 +1,6 @@
|
||||||
Metadata-Version: 1.1
|
Metadata-Version: 1.1
|
||||||
Name: click
|
Name: click
|
||||||
Version: 6.6
|
Version: 6.7
|
||||||
Summary: A simple wrapper around optparse for powerful command line utilities.
|
Summary: A simple wrapper around optparse for powerful command line utilities.
|
||||||
Home-page: http://github.com/mitsuhiko/click
|
Home-page: http://github.com/mitsuhiko/click
|
||||||
Author: Armin Ronacher
|
Author: Armin Ronacher
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Metadata-Version: 1.1
|
Metadata-Version: 1.1
|
||||||
Name: click
|
Name: click
|
||||||
Version: 6.6
|
Version: 6.7
|
||||||
Summary: A simple wrapper around optparse for powerful command line utilities.
|
Summary: A simple wrapper around optparse for powerful command line utilities.
|
||||||
Home-page: http://github.com/mitsuhiko/click
|
Home-page: http://github.com/mitsuhiko/click
|
||||||
Author: Armin Ronacher
|
Author: Armin Ronacher
|
||||||
|
|
|
@ -87,24 +87,12 @@ examples/inout/setup.py
|
||||||
examples/naval/README
|
examples/naval/README
|
||||||
examples/naval/naval.py
|
examples/naval/naval.py
|
||||||
examples/naval/setup.py
|
examples/naval/setup.py
|
||||||
examples/plugins/BrokenPlugin/printer_bold.egg-info/PKG-INFO
|
|
||||||
examples/plugins/BrokenPlugin/printer_bold.egg-info/SOURCES.txt
|
|
||||||
examples/plugins/BrokenPlugin/printer_bold.egg-info/dependency_links.txt
|
|
||||||
examples/plugins/BrokenPlugin/printer_bold.egg-info/entry_points.txt
|
|
||||||
examples/plugins/BrokenPlugin/printer_bold.egg-info/top_level.txt
|
|
||||||
examples/plugins/printer.egg-info/PKG-INFO
|
|
||||||
examples/plugins/printer.egg-info/SOURCES.txt
|
|
||||||
examples/plugins/printer.egg-info/dependency_links.txt
|
|
||||||
examples/plugins/printer.egg-info/entry_points.txt
|
|
||||||
examples/plugins/printer.egg-info/top_level.txt
|
|
||||||
examples/repo/README
|
examples/repo/README
|
||||||
examples/repo/repo.py
|
examples/repo/repo.py
|
||||||
examples/repo/setup.py
|
examples/repo/setup.py
|
||||||
examples/termui/README
|
examples/termui/README
|
||||||
examples/termui/setup.py
|
examples/termui/setup.py
|
||||||
examples/termui/termui.py
|
examples/termui/termui.py
|
||||||
examples/termui/build/lib/termui.py
|
|
||||||
examples/termui/dist/click_example_termui-1.0-py3.4.egg
|
|
||||||
examples/validation/README
|
examples/validation/README
|
||||||
examples/validation/setup.py
|
examples/validation/setup.py
|
||||||
examples/validation/validation.py
|
examples/validation/validation.py
|
||||||
|
|
|
@ -95,4 +95,4 @@ __all__ = [
|
||||||
disable_unicode_literals_warning = False
|
disable_unicode_literals_warning = False
|
||||||
|
|
||||||
|
|
||||||
__version__ = '6.6'
|
__version__ = '6.7'
|
||||||
|
|
|
@ -30,8 +30,8 @@ def get_completion_script(prog_name, complete_var):
|
||||||
|
|
||||||
def resolve_ctx(cli, prog_name, args):
|
def resolve_ctx(cli, prog_name, args):
|
||||||
ctx = cli.make_context(prog_name, args, resilient_parsing=True)
|
ctx = cli.make_context(prog_name, args, resilient_parsing=True)
|
||||||
while ctx.args + ctx.protected_args and isinstance(ctx.command, MultiCommand):
|
while ctx.protected_args + ctx.args and isinstance(ctx.command, MultiCommand):
|
||||||
a = ctx.args + ctx.protected_args
|
a = ctx.protected_args + ctx.args
|
||||||
cmd = ctx.command.get_command(ctx, a[0])
|
cmd = ctx.command.get_command(ctx, a[0])
|
||||||
if cmd is None:
|
if cmd is None:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -160,8 +160,16 @@ if PY2:
|
||||||
#
|
#
|
||||||
# This code also lives in _winconsole for the fallback to the console
|
# This code also lives in _winconsole for the fallback to the console
|
||||||
# emulation stream.
|
# emulation stream.
|
||||||
if WIN:
|
#
|
||||||
|
# There are also Windows environments where the `msvcrt` module is not
|
||||||
|
# available (which is why we use try-catch instead of the WIN variable
|
||||||
|
# here), such as the Google App Engine development server on Windows. In
|
||||||
|
# those cases there is just nothing we can do.
|
||||||
|
try:
|
||||||
import msvcrt
|
import msvcrt
|
||||||
|
except ImportError:
|
||||||
|
set_binary_mode = lambda x: x
|
||||||
|
else:
|
||||||
def set_binary_mode(f):
|
def set_binary_mode(f):
|
||||||
try:
|
try:
|
||||||
fileno = f.fileno()
|
fileno = f.fileno()
|
||||||
|
@ -170,8 +178,6 @@ if PY2:
|
||||||
else:
|
else:
|
||||||
msvcrt.setmode(fileno, os.O_BINARY)
|
msvcrt.setmode(fileno, os.O_BINARY)
|
||||||
return f
|
return f
|
||||||
else:
|
|
||||||
set_binary_mode = lambda x: x
|
|
||||||
|
|
||||||
def isidentifier(x):
|
def isidentifier(x):
|
||||||
return _identifier_re.search(x) is not None
|
return _identifier_re.search(x) is not None
|
||||||
|
|
|
@ -31,7 +31,7 @@ def _length_hint(obj):
|
||||||
"""Returns the length hint of an object."""
|
"""Returns the length hint of an object."""
|
||||||
try:
|
try:
|
||||||
return len(obj)
|
return len(obj)
|
||||||
except TypeError:
|
except (AttributeError, TypeError):
|
||||||
try:
|
try:
|
||||||
get_hint = type(obj).__length_hint__
|
get_hint = type(obj).__length_hint__
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
|
|
@ -114,6 +114,5 @@ def _verify_python3_env():
|
||||||
|
|
||||||
raise RuntimeError('Click will abort further execution because Python 3 '
|
raise RuntimeError('Click will abort further execution because Python 3 '
|
||||||
'was configured to use ASCII as encoding for the '
|
'was configured to use ASCII as encoding for the '
|
||||||
'environment. Either run this under Python 2 or '
|
'environment. Consult http://click.pocoo.org/python3/'
|
||||||
'consult http://click.pocoo.org/python3/ for '
|
'for mitigation steps.' + extra)
|
||||||
'mitigation steps.' + extra)
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import errno
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
@ -705,6 +706,11 @@ class BaseCommand(object):
|
||||||
raise
|
raise
|
||||||
e.show()
|
e.show()
|
||||||
sys.exit(e.exit_code)
|
sys.exit(e.exit_code)
|
||||||
|
except IOError as e:
|
||||||
|
if e.errno == errno.EPIPE:
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
except Abort:
|
except Abort:
|
||||||
if not standalone_mode:
|
if not standalone_mode:
|
||||||
raise
|
raise
|
||||||
|
|
|
@ -213,7 +213,7 @@ class CliRunner(object):
|
||||||
old_env = {}
|
old_env = {}
|
||||||
try:
|
try:
|
||||||
for key, value in iteritems(env):
|
for key, value in iteritems(env):
|
||||||
old_env[key] = os.environ.get(value)
|
old_env[key] = os.environ.get(key)
|
||||||
if value is None:
|
if value is None:
|
||||||
try:
|
try:
|
||||||
del os.environ[key]
|
del os.environ[key]
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
Metadata-Version: 1.0
|
|
||||||
Name: printer-bold
|
|
||||||
Version: 0.1dev0
|
|
||||||
Summary: UNKNOWN
|
|
||||||
Home-page: UNKNOWN
|
|
||||||
Author: UNKNOWN
|
|
||||||
Author-email: UNKNOWN
|
|
||||||
License: UNKNOWN
|
|
||||||
Description: UNKNOWN
|
|
||||||
Platform: UNKNOWN
|
|
|
@ -1,8 +0,0 @@
|
||||||
README.rst
|
|
||||||
printer_bold/__init__.py
|
|
||||||
printer_bold/core.py
|
|
||||||
printer_bold.egg-info/PKG-INFO
|
|
||||||
printer_bold.egg-info/SOURCES.txt
|
|
||||||
printer_bold.egg-info/dependency_links.txt
|
|
||||||
printer_bold.egg-info/entry_points.txt
|
|
||||||
printer_bold.egg-info/top_level.txt
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
[printer.plugins]
|
|
||||||
bold=printer_bold.core:bolddddddddddd
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
printer_bold
|
|
|
@ -1,10 +0,0 @@
|
||||||
Metadata-Version: 1.0
|
|
||||||
Name: printer
|
|
||||||
Version: 0.1dev0
|
|
||||||
Summary: UNKNOWN
|
|
||||||
Home-page: UNKNOWN
|
|
||||||
Author: UNKNOWN
|
|
||||||
Author-email: UNKNOWN
|
|
||||||
License: UNKNOWN
|
|
||||||
Description: UNKNOWN
|
|
||||||
Platform: UNKNOWN
|
|
|
@ -1,8 +0,0 @@
|
||||||
README.rst
|
|
||||||
printer/__init__.py
|
|
||||||
printer/cli.py
|
|
||||||
printer.egg-info/PKG-INFO
|
|
||||||
printer.egg-info/SOURCES.txt
|
|
||||||
printer.egg-info/dependency_links.txt
|
|
||||||
printer.egg-info/entry_points.txt
|
|
||||||
printer.egg-info/top_level.txt
|
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
[console_scripts]
|
|
||||||
printer=printer.cli:cli
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
printer
|
|
|
@ -1,145 +0,0 @@
|
||||||
# coding: utf-8
|
|
||||||
import click
|
|
||||||
import time
|
|
||||||
import random
|
|
||||||
|
|
||||||
try:
|
|
||||||
range_type = xrange
|
|
||||||
except NameError:
|
|
||||||
range_type = range
|
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
|
||||||
def cli():
|
|
||||||
"""This script showcases different terminal UI helpers in Click."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
def colordemo():
|
|
||||||
"""Demonstrates ANSI color support."""
|
|
||||||
for color in 'red', 'green', 'blue':
|
|
||||||
click.echo(click.style('I am colored %s' % color, fg=color))
|
|
||||||
click.echo(click.style('I am background colored %s' % color, bg=color))
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
def pager():
|
|
||||||
"""Demonstrates using the pager."""
|
|
||||||
lines = []
|
|
||||||
for x in range_type(200):
|
|
||||||
lines.append('%s. Hello World!' % click.style(str(x), fg='green'))
|
|
||||||
click.echo_via_pager('\n'.join(lines))
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
@click.option('--count', default=8000, type=click.IntRange(1, 100000),
|
|
||||||
help='The number of items to process.')
|
|
||||||
def progress(count):
|
|
||||||
"""Demonstrates the progress bar."""
|
|
||||||
items = range_type(count)
|
|
||||||
|
|
||||||
def process_slowly(item):
|
|
||||||
time.sleep(0.002 * random.random())
|
|
||||||
|
|
||||||
def filter(items):
|
|
||||||
for item in items:
|
|
||||||
if random.random() > 0.3:
|
|
||||||
yield item
|
|
||||||
|
|
||||||
with click.progressbar(items, label='Processing accounts',
|
|
||||||
fill_char=click.style('#', fg='green')) as bar:
|
|
||||||
for item in bar:
|
|
||||||
process_slowly(item)
|
|
||||||
|
|
||||||
def show_item(item):
|
|
||||||
if item is not None:
|
|
||||||
return 'Item #%d' % item
|
|
||||||
|
|
||||||
with click.progressbar(filter(items), label='Committing transaction',
|
|
||||||
fill_char=click.style('#', fg='yellow'),
|
|
||||||
item_show_func=show_item) as bar:
|
|
||||||
for item in bar:
|
|
||||||
process_slowly(item)
|
|
||||||
|
|
||||||
with click.progressbar(length=count, label='Counting',
|
|
||||||
bar_template='%(label)s %(bar)s | %(info)s',
|
|
||||||
fill_char=click.style(u'█', fg='cyan'),
|
|
||||||
empty_char=' ') as bar:
|
|
||||||
for item in bar:
|
|
||||||
process_slowly(item)
|
|
||||||
|
|
||||||
with click.progressbar(length=count, width=0, show_percent=False,
|
|
||||||
show_eta=False,
|
|
||||||
fill_char=click.style('#', fg='magenta')) as bar:
|
|
||||||
for item in bar:
|
|
||||||
process_slowly(item)
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
@click.argument('url')
|
|
||||||
def open(url):
|
|
||||||
"""Opens a file or URL In the default application."""
|
|
||||||
click.launch(url)
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
@click.argument('url')
|
|
||||||
def locate(url):
|
|
||||||
"""Opens a file or URL In the default application."""
|
|
||||||
click.launch(url, locate=True)
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
def edit():
|
|
||||||
"""Opens an editor with some text in it."""
|
|
||||||
MARKER = '# Everything below is ignored\n'
|
|
||||||
message = click.edit('\n\n' + MARKER)
|
|
||||||
if message is not None:
|
|
||||||
msg = message.split(MARKER, 1)[0].rstrip('\n')
|
|
||||||
if not msg:
|
|
||||||
click.echo('Empty message!')
|
|
||||||
else:
|
|
||||||
click.echo('Message:\n' + msg)
|
|
||||||
else:
|
|
||||||
click.echo('You did not enter anything!')
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
def clear():
|
|
||||||
"""Clears the entire screen."""
|
|
||||||
click.clear()
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
def pause():
|
|
||||||
"""Waits for the user to press a button."""
|
|
||||||
click.pause()
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command()
|
|
||||||
def menu():
|
|
||||||
"""Shows a simple menu."""
|
|
||||||
menu = 'main'
|
|
||||||
while 1:
|
|
||||||
if menu == 'main':
|
|
||||||
click.echo('Main menu:')
|
|
||||||
click.echo(' d: debug menu')
|
|
||||||
click.echo(' q: quit')
|
|
||||||
char = click.getchar()
|
|
||||||
if char == 'd':
|
|
||||||
menu = 'debug'
|
|
||||||
elif char == 'q':
|
|
||||||
menu = 'quit'
|
|
||||||
else:
|
|
||||||
click.echo('Invalid input')
|
|
||||||
elif menu == 'debug':
|
|
||||||
click.echo('Debug menu')
|
|
||||||
click.echo(' b: back')
|
|
||||||
char = click.getchar()
|
|
||||||
if char == 'b':
|
|
||||||
menu = 'main'
|
|
||||||
else:
|
|
||||||
click.echo('Invalid input')
|
|
||||||
elif menu == 'quit':
|
|
||||||
return
|
|
Binary file not shown.
|
@ -3,7 +3,18 @@
|
||||||
import click
|
import click
|
||||||
from click._bashcomplete import get_choices
|
from click._bashcomplete import get_choices
|
||||||
|
|
||||||
def test_basic():
|
|
||||||
|
def test_single_command():
|
||||||
|
@click.command()
|
||||||
|
@click.option('--local-opt')
|
||||||
|
def cli(local_opt):
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert list(get_choices(cli, 'lol', [], '-')) == ['--local-opt']
|
||||||
|
assert list(get_choices(cli, 'lol', [], '')) == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_small_chain():
|
||||||
@click.group()
|
@click.group()
|
||||||
@click.option('--global-opt')
|
@click.option('--global-opt')
|
||||||
def cli(global_opt):
|
def cli(global_opt):
|
||||||
|
@ -18,3 +29,34 @@ def test_basic():
|
||||||
assert list(get_choices(cli, 'lol', [], '-')) == ['--global-opt']
|
assert list(get_choices(cli, 'lol', [], '-')) == ['--global-opt']
|
||||||
assert list(get_choices(cli, 'lol', ['sub'], '')) == []
|
assert list(get_choices(cli, 'lol', ['sub'], '')) == []
|
||||||
assert list(get_choices(cli, 'lol', ['sub'], '-')) == ['--local-opt']
|
assert list(get_choices(cli, 'lol', ['sub'], '-')) == ['--local-opt']
|
||||||
|
|
||||||
|
|
||||||
|
def test_long_chain():
|
||||||
|
@click.group('cli')
|
||||||
|
@click.option('--cli-opt')
|
||||||
|
def cli(cli_opt):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@cli.group('asub')
|
||||||
|
@click.option('--asub-opt')
|
||||||
|
def asub(asub_opt):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@asub.group('bsub')
|
||||||
|
@click.option('--bsub-opt')
|
||||||
|
def bsub(bsub_opt):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@bsub.command('csub')
|
||||||
|
@click.option('--csub-opt')
|
||||||
|
def csub(csub_opt):
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert list(get_choices(cli, 'lol', [], '-')) == ['--cli-opt']
|
||||||
|
assert list(get_choices(cli, 'lol', [], '')) == ['asub']
|
||||||
|
assert list(get_choices(cli, 'lol', ['asub'], '-')) == ['--asub-opt']
|
||||||
|
assert list(get_choices(cli, 'lol', ['asub'], '')) == ['bsub']
|
||||||
|
assert list(get_choices(cli, 'lol', ['asub', 'bsub'], '-')) == ['--bsub-opt']
|
||||||
|
assert list(get_choices(cli, 'lol', ['asub', 'bsub'], '')) == ['csub']
|
||||||
|
assert list(get_choices(cli, 'lol', ['asub', 'bsub', 'csub'], '-')) == ['--csub-opt']
|
||||||
|
assert list(get_choices(cli, 'lol', ['asub', 'bsub', 'csub'], '')) == []
|
||||||
|
|
|
@ -32,7 +32,7 @@ click.echo(json.dumps(rv))
|
||||||
ALLOWED_IMPORTS = set([
|
ALLOWED_IMPORTS = set([
|
||||||
'weakref', 'os', 'struct', 'collections', 'sys', 'contextlib',
|
'weakref', 'os', 'struct', 'collections', 'sys', 'contextlib',
|
||||||
'functools', 'stat', 're', 'codecs', 'inspect', 'itertools', 'io',
|
'functools', 'stat', 're', 'codecs', 'inspect', 'itertools', 'io',
|
||||||
'threading', 'colorama'
|
'threading', 'colorama', 'errno'
|
||||||
])
|
])
|
||||||
|
|
||||||
if WIN:
|
if WIN:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -183,3 +184,21 @@ def test_exit_code_and_output_from_sys_exit():
|
||||||
result = runner.invoke(cli_no_error)
|
result = runner.invoke(cli_no_error)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert result.output == 'hello world\n'
|
assert result.output == 'hello world\n'
|
||||||
|
|
||||||
|
|
||||||
|
def test_env():
|
||||||
|
@click.command()
|
||||||
|
def cli_env():
|
||||||
|
click.echo('ENV=%s' % os.environ['TEST_CLICK_ENV'])
|
||||||
|
|
||||||
|
runner = CliRunner()
|
||||||
|
|
||||||
|
env_orig = dict(os.environ)
|
||||||
|
env = dict(env_orig)
|
||||||
|
assert 'TEST_CLICK_ENV' not in env
|
||||||
|
env['TEST_CLICK_ENV'] = 'some_value'
|
||||||
|
result = runner.invoke(cli_env, env=env)
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert result.output == 'ENV=some_value\n'
|
||||||
|
|
||||||
|
assert os.environ == env_orig
|
||||||
|
|
Loading…
Reference in a new issue