Skip to content

Commit

Permalink
Merge branch 'master' into sysconfig
Browse files Browse the repository at this point in the history
  • Loading branch information
uranusjr committed Feb 27, 2021
2 parents b4ce289 + 4b5b151 commit 09513b8
Show file tree
Hide file tree
Showing 67 changed files with 877 additions and 691 deletions.
2 changes: 0 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ repos:
exclude: |
(?x)
^docs/|
^src/pip/_internal/cli|
^src/pip/_internal/commands|
^src/pip/_internal/distributions|
^src/pip/_internal/index|
^src/pip/_internal/models|
^src/pip/_internal/network|
Expand Down
6 changes: 3 additions & 3 deletions docs/html/development/ci.rst
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ Actual testing
| | +-------+---------------+-----------------+
| | | PyPy3 | | |
| MacOS +----------+-------+---------------+-----------------+
| | | CP3.6 | Azure | Azure |
| | | CP3.6 | Github | Github |
| | +-------+---------------+-----------------+
| | x64 | CP3.7 | Azure | Azure |
| | x64 | CP3.7 | Github | Github |
| | +-------+---------------+-----------------+
| | | CP3.8 | Azure | Azure |
| | | CP3.8 | Github | Github |
| | +-------+---------------+-----------------+
| | | PyPy3 | | |
+-----------+----------+-------+---------------+-----------------+
18 changes: 15 additions & 3 deletions docs/html/reference/pip_install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,12 @@ See the :ref:`pip install Examples<pip install Examples>`.
SSL Certificate Verification
----------------------------

Starting with v1.3, pip provides SSL certificate verification over https, to
prevent man-in-the-middle attacks against PyPI downloads.
Starting with v1.3, pip provides SSL certificate verification over HTTP, to
prevent man-in-the-middle attacks against PyPI downloads. This does not use
the system certificate store but instead uses a bundled CA certificate
store. The default bundled CA certificate store certificate store may be
overridden by using ``--cert`` option or by using ``PIP_CERT``,
``REQUESTS_CA_BUNDLE``, or ``CURL_CA_BUNDLE`` environment variables.


.. _`Caching`:
Expand Down Expand Up @@ -808,7 +812,15 @@ You can install local projects by specifying the project path to pip:
During regular installation, pip will copy the entire project directory to a
temporary location and install from there. The exception is that pip will
exclude .tox and .nox directories present in the top level of the project from
being copied.
being copied. This approach is the cause of several performance and correctness
issues, so it is planned that pip 21.3 will change to install directly from the
local project directory. Depending on the build backend used by the project,
this may generate secondary build artifacts in the project directory, such as
the ``.egg-info`` and ``build`` directories in the case of the setuptools
backend.

To opt in to the future behavior, specify the ``--use-feature=in-tree-build``
option in pip's command line.


.. _`editable-installs`:
Expand Down
8 changes: 5 additions & 3 deletions docs/html/user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1857,9 +1857,11 @@ We plan for the resolver changeover to proceed as follows, using
environments, pip defaults to the old resolver, and the new one is
available using the flag ``--use-feature=2020-resolver``.

* pip 21.0: pip uses new resolver, and the old resolver is no longer
available. Python 2 support is removed per our :ref:`Python 2
Support` policy.
* pip 21.0: pip uses new resolver by default, and the old resolver is
no longer supported. It will be removed after a currently undecided
amount of time, as the removal is dependent on pip's volunteer
maintainers' availability. Python 2 support is removed per our
:ref:`Python 2 Support` policy.

Since this work will not change user-visible behavior described in the
pip documentation, this change is not covered by the :ref:`Deprecation
Expand Down
Empty file.
Empty file.
1 change: 1 addition & 0 deletions news/6720.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improve SSL Certificate Verification docs and ``--cert`` help text.
Empty file.
1 change: 1 addition & 0 deletions news/8733.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Correctly uninstall script files (from setuptools' ``scripts`` argument), when installed with ``--user``.
4 changes: 4 additions & 0 deletions news/9091.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Add a feature ``--use-feature=in-tree-build`` to build local projects in-place
when installing. This is expected to become the default behavior in pip 21.3;
see `Installing from local packages <https://pip.pypa.io/en/stable/user_guide/#installing-from-local-packages>`_
for more information.
Empty file.
2 changes: 2 additions & 0 deletions news/9300.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
New resolver: Show relevant entries from user-supplied constraint files in the
error message to improve debuggability.
Empty file.
Empty file.
Empty file.
11 changes: 7 additions & 4 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,14 @@ def vendoring(session):

def pinned_requirements(path):
# type: (Path) -> Iterator[Tuple[str, str]]
for line in path.read_text().splitlines():
one, two = line.split("==", 1)
for line in path.read_text().splitlines(keepends=False):
one, sep, two = line.partition("==")
if not sep:
continue
name = one.strip()
version = two.split("#")[0].strip()
yield name, version
version = two.split("#", 1)[0].strip()
if name and version:
yield name, version

vendor_txt = Path("src/pip/_vendor/vendor.txt")
for name, old_version in pinned_requirements(vendor_txt):
Expand Down
7 changes: 3 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
# The following comment should be removed at some point in the future.
# mypy: disallow-untyped-defs=False

import os
import sys

from setuptools import find_packages, setup


def read(rel_path):
# type: (str) -> str
here = os.path.abspath(os.path.dirname(__file__))
# intentionally *not* adding an encoding option to open, See:
# https://github.com/pypa/virtualenv/issues/201#issuecomment-3145690
with open(os.path.join(here, rel_path), 'r') as fp:
with open(os.path.join(here, rel_path)) as fp:
return fp.read()


def get_version(rel_path):
# type: (str) -> str
for line in read(rel_path).splitlines():
if line.startswith('__version__'):
# __version__ = "0.9"
Expand Down
58 changes: 29 additions & 29 deletions src/pip/_internal/cli/autocompletion.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@

def autocomplete():
# type: () -> None
"""Entry Point for completion of main and subcommand options.
"""
"""Entry Point for completion of main and subcommand options."""
# Don't complete if user hasn't sourced bash_completion file.
if 'PIP_AUTO_COMPLETE' not in os.environ:
if "PIP_AUTO_COMPLETE" not in os.environ:
return
cwords = os.environ['COMP_WORDS'].split()[1:]
cword = int(os.environ['COMP_CWORD'])
cwords = os.environ["COMP_WORDS"].split()[1:]
cword = int(os.environ["COMP_CWORD"])
try:
current = cwords[cword - 1]
except IndexError:
current = ''
current = ""

parser = create_main_parser()
subcommands = list(commands_dict)
Expand All @@ -39,13 +38,13 @@ def autocomplete():
# subcommand options
if subcommand_name is not None:
# special case: 'help' subcommand has no options
if subcommand_name == 'help':
if subcommand_name == "help":
sys.exit(1)
# special case: list locally installed dists for show and uninstall
should_list_installed = (
subcommand_name in ['show', 'uninstall'] and
not current.startswith('-')
)
should_list_installed = not current.startswith("-") and subcommand_name in [
"show",
"uninstall",
]
if should_list_installed:
lc = current.lower()
installed = [
Expand All @@ -67,13 +66,15 @@ def autocomplete():
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]]
prev_opts = [x.split("=")[0] for x in cwords[1 : cword - 1]]
options = [(x, v) for (x, v) in options if x not in prev_opts]
# filter options by current input
options = [(k, v) for k, v in options if k.startswith(current)]
# get completion type given cwords and available subcommand options
completion_type = get_path_completion_type(
cwords, cword, subcommand.parser.option_list_all,
cwords,
cword,
subcommand.parser.option_list_all,
)
# get completion files and directories if ``completion_type`` is
# ``<file>``, ``<dir>`` or ``<path>``
Expand All @@ -84,27 +85,25 @@ def autocomplete():
opt_label = option[0]
# append '=' to options which require args
if option[1] and option[0][:2] == "--":
opt_label += '='
opt_label += "="
print(opt_label)
else:
# show main parser options only when necessary

opts = [i.option_list for i in parser.option_groups]
opts.append(parser.option_list)
flattened_opts = chain.from_iterable(opts)
if current.startswith('-'):
if current.startswith("-"):
for opt in flattened_opts:
if opt.help != optparse.SUPPRESS_HELP:
subcommands += opt._long_opts + opt._short_opts
else:
# get completion type given cwords and all available options
completion_type = get_path_completion_type(cwords, cword,
flattened_opts)
completion_type = get_path_completion_type(cwords, cword, flattened_opts)
if completion_type:
subcommands = list(auto_complete_paths(current,
completion_type))
subcommands = list(auto_complete_paths(current, completion_type))

print(' '.join([x for x in subcommands if x.startswith(current)]))
print(" ".join([x for x in subcommands if x.startswith(current)]))
sys.exit(1)


Expand All @@ -117,16 +116,16 @@ def get_path_completion_type(cwords, cword, opts):
:param opts: The available options to check
:return: path completion type (``file``, ``dir``, ``path`` or None)
"""
if cword < 2 or not cwords[cword - 2].startswith('-'):
if cword < 2 or not cwords[cword - 2].startswith("-"):
return None
for opt in opts:
if opt.help == optparse.SUPPRESS_HELP:
continue
for o in str(opt).split('/'):
if cwords[cword - 2].split('=')[0] == o:
for o in str(opt).split("/"):
if cwords[cword - 2].split("=")[0] == o:
if not opt.metavar or any(
x in ('path', 'file', 'dir')
for x in opt.metavar.split('/')):
x in ("path", "file", "dir") for x in opt.metavar.split("/")
):
return opt.metavar
return None

Expand All @@ -148,15 +147,16 @@ def auto_complete_paths(current, completion_type):
return
filename = os.path.normcase(filename)
# list all files that start with ``filename``
file_list = (x for x in os.listdir(current_path)
if os.path.normcase(x).startswith(filename))
file_list = (
x for x in os.listdir(current_path) if os.path.normcase(x).startswith(filename)
)
for f in file_list:
opt = os.path.join(current_path, f)
comp_file = os.path.normcase(os.path.join(directory, f))
# complete regular files when there is not ``<dir>`` after option
# complete directories when there is ``<file>``, ``<path>`` or
# ``<dir>``after option
if completion_type != 'dir' and os.path.isfile(opt):
if completion_type != "dir" and os.path.isfile(opt):
yield comp_file
elif os.path.isdir(opt):
yield os.path.join(comp_file, '')
yield os.path.join(comp_file, "")
42 changes: 22 additions & 20 deletions src/pip/_internal/cli/base_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from pip._internal.utils.temp_dir import global_tempdir_manager, tempdir_registry
from pip._internal.utils.virtualenv import running_under_virtualenv

__all__ = ['Command']
__all__ = ["Command"]

logger = logging.getLogger(__name__)

Expand All @@ -51,7 +51,7 @@ def __init__(self, name, summary, isolated=False):
self.summary = summary
self.parser = ConfigOptionParser(
usage=self.usage,
prog=f'{get_prog()} {name}',
prog=f"{get_prog()} {name}",
formatter=UpdatingDefaultsHelpFormatter(),
add_help_option=False,
name=name,
Expand All @@ -62,7 +62,7 @@ def __init__(self, name, summary, isolated=False):
self.tempdir_registry = None # type: Optional[TempDirRegistry]

# Commands should add options to this option group
optgroup_name = f'{self.name.capitalize()} Options'
optgroup_name = f"{self.name.capitalize()} Options"
self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name)

# Add the general options
Expand All @@ -86,7 +86,7 @@ def handle_pip_version_check(self, options):
"""
# Make sure we do the pip version check if the index_group options
# are present.
assert not hasattr(options, 'no_index')
assert not hasattr(options, "no_index")

def run(self, options, args):
# type: (Values, List[Any]) -> int
Expand Down Expand Up @@ -131,17 +131,15 @@ def _main(self, args):
# This also affects isolated builds and it should.

if options.no_input:
os.environ['PIP_NO_INPUT'] = '1'
os.environ["PIP_NO_INPUT"] = "1"

if options.exists_action:
os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)
os.environ["PIP_EXISTS_ACTION"] = " ".join(options.exists_action)

if options.require_venv and not self.ignore_require_venv:
# If a venv is required check if it can really be found
if not running_under_virtualenv():
logger.critical(
'Could not find an activated virtualenv (required).'
)
logger.critical("Could not find an activated virtualenv (required).")
sys.exit(VIRTUALENV_NOT_FOUND)

if options.cache_dir:
Expand Down Expand Up @@ -171,7 +169,7 @@ def _main(self, args):
issue=8333,
)

if '2020-resolver' in options.features_enabled:
if "2020-resolver" in options.features_enabled:
logger.warning(
"--use-feature=2020-resolver no longer has any effect, "
"since it is now the default dependency resolver in pip. "
Expand All @@ -184,35 +182,39 @@ def _main(self, args):
return status
except PreviousBuildDirError as exc:
logger.critical(str(exc))
logger.debug('Exception information:', exc_info=True)
logger.debug("Exception information:", exc_info=True)

return PREVIOUS_BUILD_DIR_ERROR
except (InstallationError, UninstallationError, BadCommand,
NetworkConnectionError) as exc:
except (
InstallationError,
UninstallationError,
BadCommand,
NetworkConnectionError,
) as exc:
logger.critical(str(exc))
logger.debug('Exception information:', exc_info=True)
logger.debug("Exception information:", exc_info=True)

return ERROR
except CommandError as exc:
logger.critical('%s', exc)
logger.debug('Exception information:', exc_info=True)
logger.critical("%s", exc)
logger.debug("Exception information:", exc_info=True)

return ERROR
except BrokenStdoutLoggingError:
# Bypass our logger and write any remaining messages to stderr
# because stdout no longer works.
print('ERROR: Pipe to stdout was broken', file=sys.stderr)
print("ERROR: Pipe to stdout was broken", file=sys.stderr)
if level_number <= logging.DEBUG:
traceback.print_exc(file=sys.stderr)

return ERROR
except KeyboardInterrupt:
logger.critical('Operation cancelled by user')
logger.debug('Exception information:', exc_info=True)
logger.critical("Operation cancelled by user")
logger.debug("Exception information:", exc_info=True)

return ERROR
except BaseException:
logger.critical('Exception:', exc_info=True)
logger.critical("Exception:", exc_info=True)

return UNKNOWN_ERROR
finally:
Expand Down
Loading

0 comments on commit 09513b8

Please sign in to comment.