Merge branch 'master' into resolver/warn-after-resolution

This commit is contained in:
Pradyun Gedam 2018-03-30 13:39:22 +05:30
commit da2d7ce5b5
No known key found for this signature in database
GPG Key ID: DA17C4B29CB32E4B
15 changed files with 97 additions and 58 deletions

View File

@ -13,7 +13,7 @@
- Fix an error where the vendored requests was not correctly containing itself
to only the internal vendored prefix.
- Restore compatability with 2.6.
- Restore compatibility with 2.6.
9.0.2 (2018-03-16)

1
news/4954.feature Normal file
View File

@ -0,0 +1 @@
Add auto completion of short options.

1
news/4966.bugfix Normal file
View File

@ -0,0 +1 @@
Terminal size is now correctly inferred when using Python 3 on Windows.

View File

@ -105,9 +105,11 @@ def autocomplete():
sys.exit(1)
subcommand = commands_dict[subcommand_name]()
options += [(opt.get_opt_string(), opt.nargs)
for opt in subcommand.parser.option_list_all
if opt.help != optparse.SUPPRESS_HELP]
for opt in subcommand.parser.option_list_all:
if opt.help != optparse.SUPPRESS_HELP:
for opt_str in opt._long_opts + opt._short_opts:
options.append((opt_str, opt.nargs))
# filter out previously specified options from available options
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
@ -117,7 +119,7 @@ def autocomplete():
for option in options:
opt_label = option[0]
# append '=' to options which require args
if option[1]:
if option[1] and option[0][:2] == "--":
opt_label += '='
print(opt_label)
else:
@ -127,8 +129,9 @@ def autocomplete():
opts.append(parser.option_list)
opts = (o for it in opts for o in it)
subcommands += [i.get_opt_string() for i in opts
if i.help != optparse.SUPPRESS_HELP]
for opt in opts:
if opt.help != optparse.SUPPRESS_HELP:
subcommands += opt._long_opts + opt._short_opts
print(' '.join([x for x in subcommands if x.startswith(current)]))
sys.exit(1)

View File

@ -9,8 +9,8 @@ from distutils.util import strtobool
from pip._vendor.six import string_types
from pip._internal.compat import get_terminal_size
from pip._internal.configuration import Configuration, ConfigurationError
from pip._internal.utils.misc import get_terminal_size
logger = logging.getLogger(__name__)

View File

@ -429,7 +429,7 @@ no_deps = partial(
dest='ignore_dependencies',
action='store_true',
default=False,
help="Don't install package dependencies)."
help="Don't install package dependencies.",
) # type: Any
build_dir = partial(

View File

@ -13,19 +13,7 @@ logger = logging.getLogger(__name__)
class ConfigurationCommand(Command):
"""Manage local and global configuration."""
name = 'config'
usage = """
%prog [<file-option>] list
%prog [<file-option>] [--editor <editor-path>] edit
%prog [<file-option>] get name
%prog [<file-option>] set name value
%prog [<file-option>] unset name
"""
summary = """
Manage local and global configuration.
"""Manage local and global configuration.
Subcommands:
@ -41,6 +29,18 @@ class ConfigurationCommand(Command):
default.
"""
name = 'config'
usage = """
%prog [<file-option>] list
%prog [<file-option>] [--editor <editor-path>] edit
%prog [<file-option>] get name
%prog [<file-option>] set name value
%prog [<file-option>] unset name
"""
summary = "Manage local and global configuration."
def __init__(self, *args, **kwargs):
super(ConfigurationCommand, self).__init__(*args, **kwargs)

View File

@ -12,12 +12,12 @@ from pip._vendor.packaging.version import parse as parse_version
from pip._vendor.six.moves import xmlrpc_client # type: ignore
from pip._internal.basecommand import SUCCESS, Command
from pip._internal.compat import get_terminal_size
from pip._internal.download import PipXmlrpcTransport
from pip._internal.exceptions import CommandError
from pip._internal.models import PyPI
from pip._internal.status_codes import NO_MATCHES_FOUND
from pip._internal.utils.logging import indent_log
from pip._internal.utils.misc import get_terminal_size
logger = logging.getLogger(__name__)

View File

@ -6,6 +6,7 @@ import codecs
import locale
import logging
import os
import shutil
import sys
from pip._vendor.six import text_type
@ -23,7 +24,7 @@ except ImportError:
__all__ = [
"ipaddress", "uses_pycache", "console_to_str", "native_str",
"get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile",
"get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size",
]
@ -192,3 +193,43 @@ def samefile(file1, file2):
path1 = os.path.normcase(os.path.abspath(file1))
path2 = os.path.normcase(os.path.abspath(file2))
return path1 == path2
if hasattr(shutil, 'get_terminal_size'):
def get_terminal_size():
"""
Returns a tuple (x, y) representing the width(x) and the height(y)
in characters of the terminal window.
"""
return tuple(shutil.get_terminal_size())
else:
def get_terminal_size():
"""
Returns a tuple (x, y) representing the width(x) and the height(y)
in characters of the terminal window.
"""
def ioctl_GWINSZ(fd):
try:
import fcntl
import termios
import struct
cr = struct.unpack(
'hh',
fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')
)
except:
return None
if cr == (0, 0):
return None
return cr
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80))
return int(cr[1]), int(cr[0])

View File

@ -43,7 +43,7 @@ __all__ = ['rmtree', 'display_path', 'backup_dir',
'is_svn_page', 'file_contents',
'split_leading_dir', 'has_leading_dir',
'normalize_path',
'renames', 'get_terminal_size', 'get_prog',
'renames', 'get_prog',
'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess',
'captured_stdout', 'ensure_dir',
'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS',
@ -438,36 +438,6 @@ def dist_location(dist):
return dist.location
def get_terminal_size():
"""Returns a tuple (x, y) representing the width(x) and the height(x)
in characters of the terminal window."""
def ioctl_GWINSZ(fd):
try:
import fcntl
import termios
import struct
cr = struct.unpack(
'hh',
fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')
)
except:
return None
if cr == (0, 0):
return None
return cr
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80))
return int(cr[1]), int(cr[0])
def current_umask():
"""Get the current umask which involves having to set it temporarily."""
mask = os.umask(0)

View File

@ -121,6 +121,29 @@ def test_completion_option_for_command(script):
"autocomplete function could not complete ``--``"
def test_completion_short_option(script):
"""
Test getting completion for short options after ``-`` (eg. pip -)
"""
res, env = setup_completion(script, 'pip -', '1')
assert '-h' in res.stdout.split(),\
"autocomplete function could not complete short options after ``-``"
def test_completion_short_option_for_command(script):
"""
Test getting completion for short options after ``-`` in command
(eg. pip search -)
"""
res, env = setup_completion(script, 'pip search -', '2')
assert '-h' in res.stdout.split(),\
"autocomplete function could not complete short options after ``-``"
@pytest.mark.parametrize('flag', ['--bash', '--zsh', '--fish'])
def test_completion_uses_same_executable_name(script, flag):
expect_stderr = sys.version_info[:2] == (3, 3)

View File

@ -709,7 +709,7 @@ def create_basic_wheel_for_package(script, name, version, depends, extras):
"{dist_info}/top_level.txt": """
{name}
""",
# Have an empty RECORD becuase we don't want to be checking hashes.
# Have an empty RECORD because we don't want to be checking hashes.
"{dist_info}/RECORD": ""
}

View File

@ -402,7 +402,7 @@ def test_finder_only_installs_data_require(data):
distribution are compatible with which version of Python by adding a
data-python-require to the anchor links.
See pep 503 for more informations.
See pep 503 for more information.
"""
# using a local index (that has pre & dev releases)

View File

@ -1,5 +1,5 @@
# Fixtures
This directory contains fixtures for testing pip's resolver. The fixtures are written as yml files, with a convinient format that allows for specifying a custom index for temporary use.
This directory contains fixtures for testing pip's resolver. The fixtures are written as yml files, with a convenient format that allows for specifying a custom index for temporary use.
<!-- TODO: Add a good description of the format and how it can be used. -->