Imported Upstream version 6.6

This commit is contained in:
aviau 2016-04-06 12:13:57 -04:00
parent 3187e28df2
commit 5cd05ec3cc
No known key found for this signature in database
GPG key ID: DA82830E3CCC3A3A
47 changed files with 316 additions and 211 deletions

25
CHANGES
View file

@ -3,6 +3,31 @@ Click Changelog
This contains all major version changes between Click releases.
Version 6.6
-----------
(bugfix release; released on April 4th 2016)
- Fix bug in `click.Path` where it would crash when passed a `-`. See #551.
Version 6.4
-----------
(bugfix release; released on March 24th 2016)
- Fix bug in bash completion where click would discard one or more trailing
arguments. See #471.
Version 6.3
-----------
(bugfix release; released on February 22 2016)
- Fix argument checks for interpreter invoke with `-m` and `-c`
on Windows.
- Fixed a bug that cased locale detection to error out on Python 3.
Version 6.2
-----------

View file

@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: click
Version: 6.2
Version: 6.6
Summary: A simple wrapper around optparse for powerful command line utilities.
Home-page: http://github.com/mitsuhiko/click
Author: Armin Ronacher

BIN
artwork/.DS_Store vendored

Binary file not shown.

View file

@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: click
Version: 6.2
Version: 6.6
Summary: A simple wrapper around optparse for powerful command line utilities.
Home-page: http://github.com/mitsuhiko/click
Author: Armin Ronacher

View file

@ -5,7 +5,6 @@ Makefile
README
setup.cfg
setup.py
artwork/.DS_Store
artwork/logo.svg
click/__init__.py
click/_bashcomplete.py
@ -61,7 +60,6 @@ docs/_static/click.png
docs/_static/click@2x.png
docs/_templates/sidebarintro.html
docs/_templates/sidebarlogo.html
examples/.DS_Store
examples/README
examples/aliases/README
examples/aliases/aliases.ini
@ -77,55 +75,42 @@ examples/complex/complex/cli.py
examples/complex/complex/commands/__init__.py
examples/complex/complex/commands/cmd_init.py
examples/complex/complex/commands/cmd_status.py
examples/demo/demo.py
examples/imagepipe/.DS_Store
examples/imagepipe/.gitignore
examples/imagepipe/README
examples/imagepipe/example01.jpg
examples/imagepipe/example02.jpg
examples/imagepipe/imagepipe.py
examples/imagepipe/setup.py
examples/imagepipe/click_example_imagepipe.egg-info/PKG-INFO
examples/imagepipe/click_example_imagepipe.egg-info/SOURCES.txt
examples/imagepipe/click_example_imagepipe.egg-info/dependency_links.txt
examples/imagepipe/click_example_imagepipe.egg-info/entry_points.txt
examples/imagepipe/click_example_imagepipe.egg-info/requires.txt
examples/imagepipe/click_example_imagepipe.egg-info/top_level.txt
examples/inout/README
examples/inout/inout.py
examples/inout/setup.py
examples/naval/README
examples/naval/naval.py
examples/naval/setup.py
examples/naval/click_example_naval.egg-info/PKG-INFO
examples/naval/click_example_naval.egg-info/SOURCES.txt
examples/naval/click_example_naval.egg-info/dependency_links.txt
examples/naval/click_example_naval.egg-info/entry_points.txt
examples/naval/click_example_naval.egg-info/requires.txt
examples/naval/click_example_naval.egg-info/top_level.txt
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/repo.py
examples/repo/setup.py
examples/repo/click_example_repo.egg-info/PKG-INFO
examples/repo/click_example_repo.egg-info/SOURCES.txt
examples/repo/click_example_repo.egg-info/dependency_links.txt
examples/repo/click_example_repo.egg-info/entry_points.txt
examples/repo/click_example_repo.egg-info/requires.txt
examples/repo/click_example_repo.egg-info/top_level.txt
examples/termui/README
examples/termui/setup.py
examples/termui/termui.py
examples/termui/click_example_termui.egg-info/PKG-INFO
examples/termui/click_example_termui.egg-info/SOURCES.txt
examples/termui/click_example_termui.egg-info/dependency_links.txt
examples/termui/click_example_termui.egg-info/entry_points.txt
examples/termui/click_example_termui.egg-info/requires.txt
examples/termui/click_example_termui.egg-info/top_level.txt
examples/termui/build/lib/termui.py
examples/termui/dist/click_example_termui-1.0-py3.4.egg
examples/validation/README
examples/validation/setup.py
examples/validation/validation.py
tests/conftest.py
tests/test_arguments.py
tests/test_bashcomplete.py
tests/test_basic.py
tests/test_chain.py
tests/test_commands.py

View file

@ -95,4 +95,4 @@ __all__ = [
disable_unicode_literals_warning = False
__version__ = '6.2'
__version__ = '6.6'

View file

@ -30,27 +30,19 @@ def get_completion_script(prog_name, complete_var):
def resolve_ctx(cli, prog_name, args):
ctx = cli.make_context(prog_name, args, resilient_parsing=True)
while ctx.args and isinstance(ctx.command, MultiCommand):
cmd = ctx.command.get_command(ctx, ctx.args[0])
while ctx.args + ctx.protected_args and isinstance(ctx.command, MultiCommand):
a = ctx.args + ctx.protected_args
cmd = ctx.command.get_command(ctx, a[0])
if cmd is None:
return None
ctx = cmd.make_context(ctx.args[0], ctx.args[1:], parent=ctx,
resilient_parsing=True)
ctx = cmd.make_context(a[0], a[1:], parent=ctx, resilient_parsing=True)
return ctx
def do_complete(cli, prog_name):
cwords = split_arg_string(os.environ['COMP_WORDS'])
cword = int(os.environ['COMP_CWORD'])
args = cwords[1:cword]
try:
incomplete = cwords[cword]
except IndexError:
incomplete = ''
def get_choices(cli, prog_name, args, incomplete):
ctx = resolve_ctx(cli, prog_name, args)
if ctx is None:
return True
return
choices = []
if incomplete and not incomplete[:1].isalnum():
@ -64,7 +56,20 @@ def do_complete(cli, prog_name):
for item in choices:
if item.startswith(incomplete):
echo(item)
yield item
def do_complete(cli, prog_name):
cwords = split_arg_string(os.environ['COMP_WORDS'])
cword = int(os.environ['COMP_CWORD'])
args = cwords[1:cword]
try:
incomplete = cwords[cword]
except IndexError:
incomplete = ''
for item in get_choices(cli, prog_name, args, incomplete):
echo(item)
return True

View file

@ -64,6 +64,11 @@ def _verify_python3_env():
stderr=subprocess.PIPE).communicate()[0]
good_locales = set()
has_c_utf8 = False
# Make sure we're operating on text here.
if isinstance(rv, bytes):
rv = rv.decode('ascii', 'replace')
for line in rv.splitlines():
locale = line.strip()
if locale.lower().endswith(('.utf-8', '.utf8')):

View file

@ -16,16 +16,19 @@ import time
import ctypes
import msvcrt
from click._compat import _NonClosingTextIOWrapper, text_type, PY2
from ctypes import byref, POINTER, pythonapi, c_int, c_char, c_char_p, \
from ctypes import byref, POINTER, c_int, c_char, c_char_p, \
c_void_p, py_object, c_ssize_t, c_ulong, windll, WINFUNCTYPE
try:
from ctypes import pythonapi
PyObject_GetBuffer = pythonapi.PyObject_GetBuffer
PyBuffer_Release = pythonapi.PyBuffer_Release
except ImportError:
pythonapi = None
from ctypes.wintypes import LPWSTR, LPCWSTR
c_ssize_p = POINTER(c_ssize_t)
PyObject_GetBuffer = pythonapi.PyObject_GetBuffer
PyBuffer_Release = pythonapi.PyBuffer_Release
kernel32 = windll.kernel32
GetStdHandle = kernel32.GetStdHandle
ReadConsoleW = kernel32.ReadConsoleW
@ -77,15 +80,20 @@ class Py_buffer(ctypes.Structure):
_fields_.insert(-1, ('smalltable', c_ssize_t * 2))
def get_buffer(obj, writable=False):
buf = Py_buffer()
flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE
PyObject_GetBuffer(py_object(obj), byref(buf), flags)
try:
buffer_type = c_char * buf.len
return buffer_type.from_address(buf.buf)
finally:
PyBuffer_Release(byref(buf))
# On PyPy we cannot get buffers so our ability to operate here is
# serverly limited.
if pythonapi is None:
get_buffer = None
else:
def get_buffer(obj, writable=False):
buf = Py_buffer()
flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE
PyObject_GetBuffer(py_object(obj), byref(buf), flags)
try:
buffer_type = c_char * buf.len
return buffer_type.from_address(buf.buf)
finally:
PyBuffer_Release(byref(buf))
class _WindowsConsoleRawIOBase(io.RawIOBase):
@ -232,7 +240,7 @@ if PY2:
if not arg.startswith('-') or arg == '-':
break
argv = argv[1:]
if arg in ('-c', '-m'):
if arg.startswith(('-c', '-m')):
break
return argv[1:]
@ -246,7 +254,8 @@ _stream_factories = {
def _get_windows_console_stream(f, encoding, errors):
if encoding in ('utf-16-le', None) \
if get_buffer is not None and \
encoding in ('utf-16-le', None) \
and errors in ('strict', None) and \
hasattr(f, 'isatty') and f.isatty():
func = _stream_factories.get(f.fileno())

View file

@ -418,26 +418,26 @@ class Path(ParamType):
filename_to_ui(value)
), param, ctx)
if not self.file_okay and stat.S_ISREG(st.st_mode):
self.fail('%s "%s" is a file.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
if not self.dir_okay and stat.S_ISDIR(st.st_mode):
self.fail('%s "%s" is a directory.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
if self.writable and not os.access(value, os.W_OK):
self.fail('%s "%s" is not writable.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
if self.readable and not os.access(value, os.R_OK):
self.fail('%s "%s" is not readable.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
if not self.file_okay and stat.S_ISREG(st.st_mode):
self.fail('%s "%s" is a file.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
if not self.dir_okay and stat.S_ISDIR(st.st_mode):
self.fail('%s "%s" is a directory.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
if self.writable and not os.access(value, os.W_OK):
self.fail('%s "%s" is not writable.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
if self.readable and not os.access(value, os.R_OK):
self.fail('%s "%s" is not readable.' % (
self.path_type,
filename_to_ui(value)
), param, ctx)
return self.coerce_path_result(rv)

BIN
examples/.DS_Store vendored

Binary file not shown.

View file

@ -1,47 +0,0 @@
import click
class VcsContext(object):
def __init__(self):
self.debug = False
class FancyContext(object):
def __init__(self):
pass
pass_vcs = click.make_pass_decorator(VcsContext, ensure=True)
pass_fancy = click.make_pass_decorator(FancyContext, ensure=True)
@click.group()
@pass_vcs
def cli(obj):
"""Write stuff here."""
print obj
@click.group()
@pass_vcs
def commit(obj):
"""This commits some stuff."""
print obj
@click.command()
@pass_fancy
def fancy_thing(obj):
ctx = click.get_current_context()
print obj
print 'find vcs context', ctx.find_object(VcsContext)
cli.add_command(commit)
commit.add_command(fancy_thing)
if __name__ == '__main__':
cli()

Binary file not shown.

View file

@ -1,10 +0,0 @@
Metadata-Version: 1.0
Name: click-example-imagepipe
Version: 1.0
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN

View file

@ -1,8 +0,0 @@
README
imagepipe.py
click_example_imagepipe.egg-info/PKG-INFO
click_example_imagepipe.egg-info/SOURCES.txt
click_example_imagepipe.egg-info/dependency_links.txt
click_example_imagepipe.egg-info/entry_points.txt
click_example_imagepipe.egg-info/requires.txt
click_example_imagepipe.egg-info/top_level.txt

View file

@ -1,4 +0,0 @@
[console_scripts]
imagepipe=imagepipe:cli

View file

@ -1,8 +0,0 @@
README
naval.py
click_example_naval.egg-info/PKG-INFO
click_example_naval.egg-info/SOURCES.txt
click_example_naval.egg-info/dependency_links.txt
click_example_naval.egg-info/entry_points.txt
click_example_naval.egg-info/requires.txt
click_example_naval.egg-info/top_level.txt

View file

@ -1,4 +0,0 @@
[console_scripts]
naval=naval:cli

View file

@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: click-example-repo
Version: 0.1
Name: printer-bold
Version: 0.1dev0
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN

View file

@ -0,0 +1,8 @@
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

View file

@ -0,0 +1,4 @@
[printer.plugins]
bold=printer_bold.core:bolddddddddddd

View file

@ -0,0 +1 @@
printer_bold

View file

@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: click-example-naval
Version: 2.0
Name: printer
Version: 0.1dev0
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN

View file

@ -0,0 +1,8 @@
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

View file

@ -0,0 +1,4 @@
[console_scripts]
printer=printer.cli:cli

View file

@ -0,0 +1 @@
printer

View file

@ -1,8 +0,0 @@
README
repo.py
click_example_repo.egg-info/PKG-INFO
click_example_repo.egg-info/SOURCES.txt
click_example_repo.egg-info/dependency_links.txt
click_example_repo.egg-info/entry_points.txt
click_example_repo.egg-info/requires.txt
click_example_repo.egg-info/top_level.txt

View file

@ -1,4 +0,0 @@
[console_scripts]
repo=repo:cli

View file

@ -0,0 +1,145 @@
# 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

View file

@ -1,10 +0,0 @@
Metadata-Version: 1.0
Name: click-example-termui
Version: 1.0
Summary: UNKNOWN
Home-page: UNKNOWN
Author: UNKNOWN
Author-email: UNKNOWN
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN

View file

@ -1,8 +0,0 @@
README
termui.py
click_example_termui.egg-info/PKG-INFO
click_example_termui.egg-info/SOURCES.txt
click_example_termui.egg-info/dependency_links.txt
click_example_termui.egg-info/entry_points.txt
click_example_termui.egg-info/requires.txt
click_example_termui.egg-info/top_level.txt

View file

@ -1,4 +0,0 @@
[console_scripts]
termui=termui:cli

View file

@ -1,2 +0,0 @@
click
colorama

Binary file not shown.

View file

@ -106,6 +106,17 @@ def test_file_args(runner):
assert result.exit_code == 0
def test_path_args(runner):
@click.command()
@click.argument('input', type=click.Path(dir_okay=False, allow_dash=True))
def foo(input):
click.echo(input)
result = runner.invoke(foo, ['-'])
assert result.output == '-\n'
assert result.exit_code == 0
def test_file_atomics(runner):
@click.command()
@click.argument('output', type=click.File('wb', atomic=True))

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
import click
from click._bashcomplete import get_choices
def test_basic():
@click.group()
@click.option('--global-opt')
def cli(global_opt):
pass
@cli.command()
@click.option('--local-opt')
def sub(local_opt):
pass
assert list(get_choices(cli, 'lol', [], '')) == ['sub']
assert list(get_choices(cli, 'lol', [], '-')) == ['--global-opt']
assert list(get_choices(cli, 'lol', ['sub'], '')) == []
assert list(get_choices(cli, 'lol', ['sub'], '-')) == ['--local-opt']