1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Merge branch 'master' into pep518

This commit is contained in:
Thomas Kluyver 2017-05-19 11:04:32 +01:00 committed by GitHub
commit 20955812bf
135 changed files with 802 additions and 605 deletions

22
.github/CONTRIBUTING.md vendored Normal file
View file

@ -0,0 +1,22 @@
# Contributing to pip
Thank you for your interest in contributing to pip! There are many ways to
contribute, and we appreciate all of them.
As a reminder, all contributors are expected to follow our [Code of Conduct][coc].
[coc]: https://www.pypa.io/en/latest/code-of-conduct/
## Bot Commands
We have a bot monitoring the [pypa/pip](https://github.com/pypa/pip) repository
to help manage the state of issues and pull requests to keep everything running
smoothly. Each command given to the bot should be on its own line and is
generally case sensitive. Multiple commands may be listed in a single comment
(but they must each be on their own line) and the comments may also include
other, non command content.
Command | Who can run it | Description
--- | --- | ---
`/request-review` | anyone | Dismisses all of the current reviews on a pull request, making it appear back in the review queue.

10
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,10 @@
<!---
Thank you for your soon to be pull request. Before you submit this, please
double check to make sure that you've added a news file fragment. In pip we
generate our NEWS.rst from multiple news fragment files, and all pull requests
require either a news file fragment or a marker to indicate they don't require
one.
To read more about adding a news file fragment for your PR, please check out
our documentation at: https://pip.pypa.io/en/latest/development/#adding-a-news-entry
-->

View file

@ -172,6 +172,7 @@ Lincoln de Sousa <lincoln@comum.org>
Lipis <lipiridis@gmail.com>
Ludovic Gasc <gmludo@gmail.com>
Luke Macken <lmacken@redhat.com>
Luo Jiebin <luo.jiebin@foxmail.com>
Marc Abramowitz <marc@marc-abramowitz.com>
Marc Tamlyn <marc.tamlyn@gmail.com>
Marcus Smith <qwcode@gmail.com>

View file

@ -156,7 +156,7 @@ html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
html_use_smartypants = False
# html_use_smartypants = False
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}

View file

@ -21,7 +21,7 @@ Installing with get-pip.py
--------------------------
To install pip, securely download `get-pip.py
<https://bootstrap.pypa.io/get-pip.py>`_. [2]_
<https://bootstrap.pypa.io/get-pip.py>`_. [1]_
Then run the following:
@ -36,7 +36,7 @@ Then run the following:
system or another package manager. get-pip.py does not coordinate with
those tools, and may leave your system in an inconsistent state.
get-pip.py will also install :ref:`pypug:setuptools` [3]_ and :ref:`pypug:wheel`,
get-pip.py will also install :ref:`pypug:setuptools` [2]_ and :ref:`pypug:wheel`,
if they're not already. :ref:`pypug:setuptools` is required to install
:term:`source distributions <pypug:Source Distribution (or "sdist")>`. Both are
required to be able to build a :ref:`Wheel cache` (which improves installation
@ -70,13 +70,13 @@ Install from local copies of pip and setuptools::
python get-pip.py --no-index --find-links=/local/copies
Install to the user site [4]_::
Install to the user site [3]_::
python get-pip.py --user
Install behind a proxy::
python get-pip.py --proxy="[user:passwd@]proxy.server:port"
python get-pip.py --proxy="http://[user:passwd@]proxy.server:port"
Using Linux Package Managers
@ -98,7 +98,7 @@ On Linux or macOS:
pip install -U pip
On Windows [5]_:
On Windows [4]_:
::
@ -118,20 +118,17 @@ pip works on Unix/Linux, macOS, and Windows.
----
.. [1] For Python 2, see https://docs.python.org/2/installing, and for Python3,
see https://docs.python.org/3/installing.
.. [2] "Secure" in this context means using a modern browser or a
.. [1] "Secure" in this context means using a modern browser or a
tool like `curl` that verifies SSL certificates when downloading from
https URLs.
.. [3] Beginning with pip v1.5.1, ``get-pip.py`` stopped requiring setuptools to
.. [2] Beginning with pip v1.5.1, ``get-pip.py`` stopped requiring setuptools to
be installed first.
.. [4] The pip developers are considering making ``--user`` the default for all
.. [3] The pip developers are considering making ``--user`` the default for all
installs, including ``get-pip.py`` installs of pip, but at this time,
``--user`` installs for pip itself, should not be considered to be fully
tested or endorsed. For discussion, see `Issue 1668
<https://github.com/pypa/pip/issues/1668>`_.
.. [5] https://github.com/pypa/pip/issues/1299
.. [4] https://github.com/pypa/pip/issues/1299

View file

@ -325,6 +325,9 @@ the :ref:`--editable <install_--editable>` option) or not.
already installed, the VCS source will not overwrite it without an `--upgrade`
flag. VCS requirements pin the package version (specified in the `setup.py`
file) of the target commit, not necessarily the commit itself.
* The :ref:`pip freeze` subcommand will record the VCS requirement specifier
(referencing a specific commit) if and only if the install is done using the
editable option.
The "project name" component of the url suffix "egg=<project name>-<version>"
is used by pip in its dependency logic to identify the project prior
@ -509,7 +512,7 @@ building a new wheel. Note that this means when a package has both optional
C extensions and builds `py` tagged wheels when the C extension can't be built
that pip will not attempt to build a better wheel for Pythons that would have
supported it, once any generic wheel is built. To correct this, make sure that
the wheels are built with Python specific tags - e.g. pp on Pypy.
the wheels are built with Python specific tags - e.g. pp on PyPy.
When no wheels are found for an sdist, pip will attempt to build a wheel
automatically and insert it into the wheel cache.
@ -798,6 +801,7 @@ Examples
$ pip install git+https://git.repo/some_pkg.git#egg=SomePackage[PDF]
$ pip install SomePackage[PDF]==3.0
$ pip install -e .[PDF]==3.0 # editable project in current directory
$ pip install SomePackage[PDF,EPUB] # multiple extras
#. Install a particular source archive file.

View file

@ -1,5 +1,5 @@
Removed support for uninstalling projects which have been installed using
distutils. distutils installed projects do not include metadata indicating
what files belong to that install and thus it is impossible to *actually*
install them rather than just remove the metadata saying they've been installed
while leaving all of the actual files behind.
uninstall them rather than just remove the metadata saying they've been
installed while leaving all of the actual files behind.

1
news/3015.bugfix Normal file
View file

@ -0,0 +1 @@
Correctly reset the terminal if an exception occurs while a progress bar is being shown.

1
news/3236.bugfix Normal file
View file

@ -0,0 +1 @@
"Support URL-encoded characters in URL credentials."

1
news/3876.bugfix Normal file
View file

@ -0,0 +1 @@
Support installing from Git refs

1
news/4008.feature Normal file
View file

@ -0,0 +1 @@
Allowed combinations of -q and -v to act sanely. Then we don't need warnings mentioned in the issue.

1
news/4076.bugfix Normal file
View file

@ -0,0 +1 @@
Changed vendored encodings from ``utf8`` to ``utf-8``.

3
news/4208.bugfix Normal file
View file

@ -0,0 +1,3 @@
Fix a bug where `SETUPTOOLS_SHIM` got called incorrectly for relative path
requirements by converting relative paths to absolute paths prior to calling
the shim.

1
news/4219.bugfix Normal file
View file

@ -0,0 +1 @@
Return the latest version number in search results.

1
news/4316.bugfix Normal file
View file

@ -0,0 +1 @@
Generalize help text for ``compile``/``no-compile` flags.

1
news/4437.bugfix Normal file
View file

@ -0,0 +1 @@
Ensure USER_SITE is correctly initialised.

1
news/4449.removal Normal file
View file

@ -0,0 +1 @@
Deprecate SVN detection based on dependency links in ``pip freeze``.

4
news/4461.bugfix Normal file
View file

@ -0,0 +1,4 @@
This fixes an issue where when someone who tries to use git
with pip but pip can't because git is not in the path
environment variable. This clarifies the error given to
suggest to the user what might be wrong.

0
news/4477.trivial Normal file
View file

1
news/4485.trivial Normal file
View file

@ -0,0 +1 @@
Sort all imports in the codebase

1
news/4488.trivial Normal file
View file

@ -0,0 +1 @@
Misc Documentation Fixes

1
news/4496.bugfix Normal file
View file

@ -0,0 +1 @@
Allow commands to opt out of --require-venv. This allows pip help to work even when the environment variable PIP_REQUIRE_VIRTUALENV is set.

3
news/949.feature Normal file
View file

@ -0,0 +1,3 @@
Added a way to distinguish between pip installed packages and those from
the system package manager in 'pip list'. Specifically, 'pip list -v' also
shows the installer of package if it has that meta data.

1
news/979.feature Normal file
View file

@ -0,0 +1 @@
Show install locations when list command ran with "-v" option.

1
news/progress.vendor Normal file
View file

@ -0,0 +1 @@
Upgraded progress to 1.3.

1
news/webencodings.vendor Normal file
View file

@ -0,0 +1 @@
Upgraded webencodings to 0.5.1.

View file

@ -10,7 +10,7 @@ Policy
* The versions of libraries vendored in pip **MUST** be reflected in
``pip/_vendor/vendor.txt``.
* Vendored libraries **MUST** function without any build steps such as 2to3 or
* Vendored libraries **MUST** function without any build steps such as ``2to3`` or
compilation of C code, pratically this limits to single source 2.x/3.x and
pure Python.
@ -33,47 +33,43 @@ higher quality and more battle tested code, centralization of bug fixes
However, there is several issues with having dependencies in the traditional
way (via ``install_requires``) for pip. These issues are:
* Fragility. When pip depends on another library to function then if for
* **Fragility.** When pip depends on another library to function then if for
whatever reason that library either isn't installed or an incompatible
version is installed then pip ceases to function. This is of course true for
all Python applications, however for every application *except* for pip the
way you fix it is by re-running pip. Obviously when pip can't run you can't
use pip to fix pip so you're left having to manually resolve dependencies and
way you fix it is by re-running pip. Obviously, when pip can't run, you can't
use pip to fix pip, so you're left having to manually resolve dependencies and
installing them by hand.
* Making other libraries uninstallable. One of pip's current dependencies is
the requests library, for which pip requires a fairly recent version to run.
If pip dependended on requests in the traditional manner then we'd end up
needing to either maintain compatibility with every version of requests that
has ever existed (and will ever exist) or some subset of the versions of
requests available will simply become uninstallable depending on what version
of pip you're using. This is again a problem that is technically true for all
Python applications, however the nature of pip is that you're likely to have
pip installed in every single environment since it is installed by default
in Python, in pyvenv, and in virtualenv.
* **Making other libraries uninstallable.** One of pip's current dependencies is
the ``requests`` library, for which pip requires a fairly recent version to run.
If pip dependended on ``requests`` in the traditional manner, then we'd either
have to maintain compatibility with every ``requests`` version that has ever
existed (and ever will), OR allow pip to render certain versions of ``requests``
uninstallable. (The second issue, although technically true for any Python
application, is magnified by pip's ubiquity; pip is installed by default in
Python, in ``pyvenv``, and in ``virtualenv``.)
* Security. On the surface this is oxymoronic since traditionally vendoring
tends to make it harder to update a dependent library for security updates
and that holds true for pip. However given the *other* reasons that exist for
pip to avoid dependencies the alternative (and what was done historically) is
for pip to reinvent the wheel itself. This led to pip having implemented
its own HTTPS verification routines to work around the lack of ssl
validation in the Python standard library which ended up having similar bugs
to validation routine in requests/urllib3 but which had to be discovered and
fixed independently. By reusing the libraries, even though we're vendoring,
we make it easier to keep pip secure by relying on the great work of our
dependencies *and* making it easier to actually fix security issues by simply
pulling in a newer version of the dependencies.
* **Security.** This might seem puzzling at first glance, since vendoring
has a tendency to complicate updating dependencies for security updates,
and that holds true for pip. However, given the *other* reasons for avoiding
dependencies, the alternative is for pip to reinvent the wheel itself.
This is what pip did historically. It forced pip to re-implement its own
HTTPS verification routines as a workaround for the Python standard library's
lack of SSL validation, which resulted in similar bugs in the validation routine
in ``requests`` and ``urllib3``, except that they had to be discovered and
fixed independently. Even though we're vendoring, reusing libraries keeps pip
more secure by relying on the great work of our dependencies, *and* allowing for
faster, easier security fixes by simply pulling in newer versions of dependencies.
* Bootstrapping. Currently most of the popular methods of installing pip rely
on the fact that pip is self contained to install pip itself. These tools
work by bundling a copy of pip, adding it to the sys.path and then executing
that copy of pip. This is done instead of implementing a "mini" installer to
again reduce duplication, pip already knows how to install a Python package
and is going to be vastly more battle tested than any sort of mini installer
could ever possibly be.
* **Bootstrapping.** Currently most popular methods of installing pip rely
on pip's self-contained nature to install pip itself. These tools work by bundling
a copy of pip, adding it to ``sys.path``, and then executing that copy of pip.
This is done instead of implementing a "mini installer" (to reduce duplication);
pip already knows how to install a Python package, and is far more battle-tested
than any "mini installer" could ever possibly be.
Many downstream redistributors have policies against this kind of bundling and
Many downstream redistributors have policies against this kind of bundling, and
instead opt to patch the software they distribute to debundle it and make it
rely on the global versions of the software that they already have packaged
(which may have its own patches applied to it). We (the pip team) would prefer
@ -96,13 +92,13 @@ such as OS packages.
Modifications
-------------
* html5lib has been modified to import six from pip._vendor
* setuptools is completely stripped to only keep pkg_resources
* pkg_resources has been modified to import its externs from pip._vendor
* CacheControl has been modified to import its dependencies from pip._vendor
* packaging has been modified to import its dependencies from pip._vendor
* requests has been modified *not* to optionally load any C dependencies.
* Modified distro to delay importing argparse to avoid errors on 2.6
* ``html5lib`` has been modified to ``import six from pip._vendor``
* ``setuptools`` is completely stripped to only keep ``pkg_resources``
* ``pkg_resources`` has been modified to import its dependencies from ``pip._vendor``
* ``CacheControl`` has been modified to import its dependencies from ``pip._vendor``
* ``packaging`` has been modified to import its dependencies from ``pip._vendor``
* ``requests`` has been modified *not* to optionally load any C dependencies
* Modified distro to delay importing ``argparse`` to avoid errors on 2.6
Automatic Vendoring
@ -112,29 +108,29 @@ Vendoring is automated via the ``vendoring.update`` task (defined in
``tasks/vendoring/__init__.py``) from the content of
``pip/_vendor/vendor.txt`` and the different patches in
``tasks/vendoring/patches/``.
Launch it via ``invoke vendoring.update`` (you will need ``invoke>=0.13.0``).
Launch it via ``invoke vendoring.update`` (requires ``invoke>=0.13.0``).
Debundling
----------
As mentioned in the rationale we, the pip team, would prefer it if pip was not
As mentioned in the rationale, we, the pip team, would prefer it if pip was not
debundled (other than optionally ``pip/_vendor/requests/cacert.pem``) and that
pip was left intact. However, if you insist on doing so we have a
semi-supported method that we do test in our CI but which requires a bit of
extra work on your end to make it still solve the problems from above.
pip was left intact. However, if you insist on doing so, we have a
semi-supported method that we do test in our CI, but requires a bit of
extra work on your end in order to solve the problems described above.
1. Delete everything in ``pip/_vendor/`` **except** for
``pip/_vendor/__init__.py``.
2. Generate wheels for each of pip's dependencies (and any of their
dependencies) using your patched copies of these libraries. These must be
placed somewhere on the filesystem that pip can access, by default we will
assume you've placed them in ``pip/_vendor``.
placed somewhere on the filesystem that pip can access (``pip/_vendor`` is
the default assumption).
3. Modify ``pip/_vendor/__init__.py`` so that the ``DEBUNDLED`` variable is
``True``.
4. *(Optional)* If you've placed the wheels in a location other than
``pip/_vendor/`` then modify ``pip/_vendor/__init__.py`` so that the
``pip/_vendor/``, then modify ``pip/_vendor/__init__.py`` so that the
``WHEEL_DIR`` variable points to the location you've placed them.

View file

@ -21,18 +21,19 @@ from sys import stderr
from time import time
__version__ = '1.2'
__version__ = '1.3'
class Infinite(object):
file = stderr
sma_window = 10
sma_window = 10 # Simple Moving Average window
def __init__(self, *args, **kwargs):
self.index = 0
self.start_ts = time()
self.avg = 0
self._ts = self.start_ts
self._dt = deque(maxlen=self.sma_window)
self._xput = deque(maxlen=self.sma_window)
for key, val in kwargs.items():
setattr(self, key, val)
@ -41,10 +42,6 @@ class Infinite(object):
return None
return getattr(self, key, None)
@property
def avg(self):
return sum(self._dt) / len(self._dt) if self._dt else 0
@property
def elapsed(self):
return int(time() - self.start_ts)
@ -53,6 +50,11 @@ class Infinite(object):
def elapsed_td(self):
return timedelta(seconds=self.elapsed)
def update_avg(self, n, dt):
if n > 0:
self._xput.append(dt / n)
self.avg = sum(self._xput) / len(self._xput)
def update(self):
pass
@ -63,20 +65,20 @@ class Infinite(object):
pass
def next(self, n=1):
if n > 0:
now = time()
dt = (now - self._ts) / n
self._dt.append(dt)
self._ts = now
now = time()
dt = now - self._ts
self.update_avg(n, dt)
self._ts = now
self.index = self.index + n
self.update()
def iter(self, it):
for x in it:
yield x
self.next()
self.finish()
try:
for x in it:
yield x
self.next()
finally:
self.finish()
class Progress(Infinite):
@ -117,7 +119,9 @@ class Progress(Infinite):
except TypeError:
pass
for x in it:
yield x
self.next()
self.finish()
try:
for x in it:
yield x
self.next()
finally:
self.finish()

View file

@ -14,6 +14,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import unicode_literals
from . import Progress
from .helpers import WritelnMixin
@ -45,39 +46,43 @@ class ChargingBar(Bar):
suffix = '%(percent)d%%'
bar_prefix = ' '
bar_suffix = ' '
empty_fill = u''
fill = u''
empty_fill = ''
fill = ''
class FillingSquaresBar(ChargingBar):
empty_fill = u''
fill = u''
empty_fill = ''
fill = ''
class FillingCirclesBar(ChargingBar):
empty_fill = u''
fill = u''
empty_fill = ''
fill = ''
class IncrementalBar(Bar):
phases = (u' ', u'', u'', u'', u'', u'', u'', u'', u'')
phases = (' ', '', '', '', '', '', '', '', '')
def update(self):
nphases = len(self.phases)
expanded_length = int(nphases * self.width * self.progress)
filled_length = int(self.width * self.progress)
empty_length = self.width - filled_length
phase = expanded_length - (filled_length * nphases)
filled_len = self.width * self.progress
nfull = int(filled_len) # Number of full chars
phase = int((filled_len - nfull) * nphases) # Phase of last char
nempty = self.width - nfull # Number of empty chars
message = self.message % self
bar = self.phases[-1] * filled_length
bar = self.phases[-1] * nfull
current = self.phases[phase] if phase > 0 else ''
empty = self.empty_fill * max(0, empty_length - len(current))
empty = self.empty_fill * max(0, nempty - len(current))
suffix = self.suffix % self
line = ''.join([message, self.bar_prefix, bar, current, empty,
self.bar_suffix, suffix])
self.writeln(line)
class PixelBar(IncrementalBar):
phases = ('', '', '', '', '', '', '', '')
class ShadyBar(IncrementalBar):
phases = (u' ', u'', u'', u'', u'')
phases = (' ', '', '', '', '')

View file

@ -14,6 +14,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import unicode_literals
from . import Infinite, Progress
from .helpers import WriteMixin
@ -34,7 +35,7 @@ class Countdown(WriteMixin, Progress):
class Stack(WriteMixin, Progress):
phases = (u' ', u'', u'', u'', u'', u'', u'', u'', u'')
phases = (' ', '', '', '', '', '', '', '', '')
hide_cursor = True
def update(self):
@ -44,4 +45,4 @@ class Stack(WriteMixin, Progress):
class Pie(Stack):
phases = (u'', u'', u'', u'', u'')
phases = ('', '', '', '', '')

View file

@ -14,6 +14,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
from __future__ import unicode_literals
from . import Infinite
from .helpers import WriteMixin
@ -29,12 +30,15 @@ class Spinner(WriteMixin, Infinite):
class PieSpinner(Spinner):
phases = [u'', u'', u'', u'']
phases = ['', '', '', '']
class MoonSpinner(Spinner):
phases = [u'', u'', u'', u'']
phases = ['', '', '', '']
class LineSpinner(Spinner):
phases = [u'', u'', u'', u'', u'', u'']
phases = ['', '', '', '', '', '']
class PixelSpinner(Spinner):
phases = ['','', '', '', '', '', '', '']

View file

@ -7,7 +7,7 @@ colorama==0.3.7
CacheControl==0.12.2
msgpack-python==0.4.8
lockfile==0.12.2
progress==1.2
progress==1.3
ipaddress==1.0.18 # Only needed on 2.6 and 2.7
packaging==16.8
pyparsing==2.2.0
@ -15,4 +15,4 @@ pytoml==0.1.12
retrying==1.3.3
requests==2.13.0
setuptools==34.3.3
webencodings==0.5
webencodings==0.5.1

View file

@ -1,4 +1,4 @@
# coding: utf8
# coding: utf-8
"""
webencodings
@ -19,7 +19,7 @@ import codecs
from .labels import LABELS
VERSION = '0.5'
VERSION = '0.5.1'
# Some names in Encoding are not valid Python aliases. Remap these.

View file

@ -1,4 +1,4 @@
# coding: utf8
# coding: utf-8
"""
webencodings.tests

View file

@ -1,4 +1,4 @@
# coding: utf8
# coding: utf-8
"""
webencodings.x_user_defined

View file

@ -3,29 +3,29 @@ from __future__ import absolute_import
import logging
import logging.config
import optparse
import os
import sys
import optparse
import warnings
from pip import cmdoptions
from pip.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
from pip.download import PipSession
from pip.exceptions import (
BadCommand, CommandError, InstallationError, PreviousBuildDirError,
UninstallationError
)
from pip.index import PackageFinder
from pip.locations import running_under_virtualenv
from pip.download import PipSession
from pip.exceptions import (BadCommand, InstallationError, UninstallationError,
CommandError, PreviousBuildDirError)
from pip.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
from pip.req import InstallRequirement, parse_requirements
from pip.status_codes import (
SUCCESS, ERROR, UNKNOWN_ERROR, VIRTUALENV_NOT_FOUND,
PREVIOUS_BUILD_DIR_ERROR,
ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR,
VIRTUALENV_NOT_FOUND
)
from pip.utils import deprecation, get_prog, normalize_path
from pip.utils.logging import IndentingFormatter
from pip.utils.outdated import pip_version_check
__all__ = ['Command']
@ -36,6 +36,7 @@ class Command(object):
name = None
usage = None
hidden = False
ignore_require_venv = False
log_streams = ("ext://sys.stdout", "ext://sys.stderr")
def __init__(self, isolated=False):
@ -105,15 +106,15 @@ class Command(object):
def main(self, args):
options, args = self.parse_args(args)
if options.quiet:
if options.quiet == 1:
level = "WARNING"
elif options.quiet == 2:
level = "ERROR"
else:
level = "CRITICAL"
elif options.verbose:
verbosity = options.verbose - options.quiet
if verbosity >= 1:
level = "DEBUG"
elif verbosity == -1:
level = "WARNING"
elif verbosity == -2:
level = "ERROR"
elif verbosity <= -3:
level = "CRITICAL"
else:
level = "INFO"
@ -202,7 +203,7 @@ class Command(object):
if options.exists_action:
os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)
if options.require_venv:
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(
@ -210,6 +211,8 @@ class Command(object):
)
sys.exit(VIRTUALENV_NOT_FOUND)
original_root_handlers = set(logging.root.handlers)
try:
status = self.run(options, args)
# FIXME: all commands should return an exit status
@ -249,6 +252,10 @@ class Command(object):
retries=0,
timeout=min(5, options.timeout)) as session:
pip_version_check(session, options)
# Avoid leaking loggers
for handler in set(logging.root.handlers) - original_root_handlers:
# this method benefit from the Logger class internal lock
logging.root.removeHandler(handler)
return SUCCESS

View file

@ -1,12 +1,13 @@
"""Base option parser setup"""
from __future__ import absolute_import
import sys
import optparse
import sys
import textwrap
from distutils.util import strtobool
from pip._vendor.six import string_types
from pip.configuration import Configuration
from pip.utils import get_terminal_size

View file

@ -9,15 +9,15 @@ pass on state. To be consistent, all options will follow this design.
"""
from __future__ import absolute_import
from functools import partial
from optparse import OptionGroup, SUPPRESS_HELP, Option
import warnings
from functools import partial
from optparse import SUPPRESS_HELP, Option, OptionGroup
from pip.index import (
FormatControl, fmt_ctl_handle_mutual_exclude, fmt_ctl_no_binary,
FormatControl, fmt_ctl_handle_mutual_exclude, fmt_ctl_no_binary
)
from pip.models import PyPI
from pip.locations import USER_CACHE_DIR, src_prefix
from pip.models import PyPI
from pip.utils.hashes import STRONG_HASHES
from pip.utils.ui import BAR_TYPES

View file

@ -16,23 +16,6 @@ from pip.commands.install import InstallCommand
from pip.commands.uninstall import UninstallCommand
from pip.commands.wheel import WheelCommand
commands_dict = {
CompletionCommand.name: CompletionCommand,
FreezeCommand.name: FreezeCommand,
HashCommand.name: HashCommand,
HelpCommand.name: HelpCommand,
SearchCommand.name: SearchCommand,
ShowCommand.name: ShowCommand,
InstallCommand.name: InstallCommand,
UninstallCommand.name: UninstallCommand,
DownloadCommand.name: DownloadCommand,
ListCommand.name: ListCommand,
CheckCommand.name: CheckCommand,
WheelCommand.name: WheelCommand,
}
commands_order = [
InstallCommand,
DownloadCommand,
@ -48,6 +31,8 @@ commands_order = [
HelpCommand,
]
commands_dict = {c.name: c for c in commands_order}
def get_summaries(ordered=True):
"""Yields sorted (command name, command summary) tuples."""

View file

@ -4,7 +4,6 @@ from pip.basecommand import Command
from pip.operations.check import check_requirements
from pip.utils import get_installed_distributions
logger = logging.getLogger(__name__)

View file

@ -1,6 +1,7 @@
from __future__ import absolute_import
import sys
from pip.basecommand import Command
BASE_COMPLETION = """
@ -41,6 +42,7 @@ class CompletionCommand(Command):
"""A helper command to be used for command completion."""
name = 'completion'
summary = 'A helper command used for command completion.'
ignore_require_venv = True
def __init__(self, *args, **kw):
super(CompletionCommand, self).__init__(*args, **kw)

View file

@ -3,16 +3,15 @@ from __future__ import absolute_import
import logging
import os
from pip import cmdoptions
from pip.basecommand import RequirementCommand
from pip.exceptions import CommandError
from pip.index import FormatControl
from pip.req import RequirementSet
from pip.basecommand import RequirementCommand
from pip import cmdoptions
from pip.utils import ensure_dir, normalize_path
from pip.utils.build import BuildDirectory
from pip.utils.filesystem import check_path_owner
logger = logging.getLogger(__name__)

View file

@ -3,12 +3,11 @@ from __future__ import absolute_import
import sys
import pip
from pip.compat import stdlib_pkgs
from pip.basecommand import Command
from pip.compat import stdlib_pkgs
from pip.operations.freeze import freeze
from pip.wheel import WheelCache
DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'}

View file

@ -9,7 +9,6 @@ from pip.status_codes import ERROR
from pip.utils import read_chunks
from pip.utils.hashes import FAVORITE_HASH, STRONG_HASHES
logger = logging.getLogger(__name__)
@ -24,6 +23,7 @@ class HashCommand(Command):
name = 'hash'
usage = '%prog [options] <file> ...'
summary = 'Compute hashes of package archives.'
ignore_require_venv = True
def __init__(self, *args, **kw):
super(HashCommand, self).__init__(*args, **kw)

View file

@ -1,6 +1,6 @@
from __future__ import absolute_import
from pip.basecommand import Command, SUCCESS
from pip.basecommand import SUCCESS, Command
from pip.exceptions import CommandError
@ -10,6 +10,7 @@ class HelpCommand(Command):
usage = """
%prog <command>"""
summary = 'Show help for commands.'
ignore_require_venv = True
def run(self, options, args):
from pip.commands import commands_dict, get_similar_commands

View file

@ -3,25 +3,26 @@ from __future__ import absolute_import
import logging
import operator
import os
import tempfile
import shutil
import tempfile
from pip import cmdoptions
from pip.basecommand import RequirementCommand
from pip.exceptions import (
CommandError, InstallationError, PreviousBuildDirError
)
from pip.locations import distutils_scheme, virtualenv_no_global
from pip.req import RequirementSet
from pip.utils import ensure_dir, get_installed_version
from pip.utils.build import BuildDirectory
from pip.utils.filesystem import check_path_owner
from pip.wheel import WheelBuilder, WheelCache
try:
import wheel
except ImportError:
wheel = None
from pip.req import RequirementSet
from pip.basecommand import RequirementCommand
from pip.locations import virtualenv_no_global, distutils_scheme
from pip.exceptions import (
InstallationError, CommandError, PreviousBuildDirError,
)
from pip import cmdoptions
from pip.utils import ensure_dir, get_installed_version
from pip.utils.build import BuildDirectory
from pip.utils.filesystem import check_path_owner
from pip.wheel import WheelCache, WheelBuilder
logger = logging.getLogger(__name__)
@ -143,14 +144,14 @@ class InstallCommand(RequirementCommand):
action="store_true",
dest="compile",
default=True,
help="Compile py files to pyc",
help="Compile Python source files to bytecode",
)
cmd_opts.add_option(
"--no-compile",
action="store_false",
dest="compile",
help="Do not compile py files to pyc",
help="Do not compile Python source files to bytecode",
)
cmd_opts.add_option(cmdoptions.no_binary())

View file

@ -3,20 +3,22 @@ from __future__ import absolute_import
import json
import logging
import warnings
from pip._vendor import six
from pip.basecommand import Command
from pip.cmdoptions import index_group, make_option_group
from pip.exceptions import CommandError
from pip.index import PackageFinder
from pip.utils import dist_is_editable, get_installed_distributions
from pip.utils.deprecation import RemovedInPip11Warning
from pip.utils.packaging import get_installer
try:
from itertools import zip_longest
except ImportError:
from itertools import izip_longest as zip_longest
from pip._vendor import six
from pip.basecommand import Command
from pip.exceptions import CommandError
from pip.index import PackageFinder
from pip.utils import (
get_installed_distributions, dist_is_editable)
from pip.utils.deprecation import RemovedInPip11Warning
from pip.cmdoptions import make_option_group, index_group
logger = logging.getLogger(__name__)
@ -209,8 +211,15 @@ class ListCommand(Command):
dist.latest_filetype = typ
yield dist
def output_legacy(self, dist):
if dist_is_editable(dist):
def output_legacy(self, dist, options):
if options.verbose >= 1:
return '%s (%s, %s, %s)' % (
dist.project_name,
dist.version,
dist.location,
get_installer(dist),
)
elif dist_is_editable(dist):
return '%s (%s, %s)' % (
dist.project_name,
dist.version,
@ -219,9 +228,9 @@ class ListCommand(Command):
else:
return '%s (%s)' % (dist.project_name, dist.version)
def output_legacy_latest(self, dist):
def output_legacy_latest(self, dist, options):
return '%s - Latest: %s [%s]' % (
self.output_legacy(dist),
self.output_legacy(dist, options),
dist.latest_version,
dist.latest_filetype,
)
@ -236,15 +245,19 @@ class ListCommand(Command):
self.output_package_listing_columns(data, header)
elif options.list_format == 'freeze':
for dist in packages:
logger.info("%s==%s", dist.project_name, dist.version)
if options.verbose >= 1:
logger.info("%s==%s (%s)", dist.project_name,
dist.version, dist.location)
else:
logger.info("%s==%s", dist.project_name, dist.version)
elif options.list_format == 'json':
logger.info(format_for_json(packages, options))
elif options.list_format == "legacy":
for dist in packages:
if options.outdated:
logger.info(self.output_legacy_latest(dist))
logger.info(self.output_legacy_latest(dist, options))
else:
logger.info(self.output_legacy(dist))
logger.info(self.output_legacy(dist, options))
def output_package_listing_columns(self, data, header):
# insert the header first: we need to know the size of column names
@ -292,8 +305,10 @@ def format_for_columns(pkgs, options):
header = ["Package", "Version"]
data = []
if any(dist_is_editable(x) for x in pkgs):
if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs):
header.append("Location")
if options.verbose >= 1:
header.append("Installer")
for proj in pkgs:
# if we're working on the 'outdated' list, separate out the
@ -304,8 +319,10 @@ def format_for_columns(pkgs, options):
row.append(proj.latest_version)
row.append(proj.latest_filetype)
if dist_is_editable(proj):
if options.verbose >= 1 or dist_is_editable(proj):
row.append(proj.location)
if options.verbose >= 1:
row.append(get_installer(proj))
data.append(row)
@ -319,6 +336,9 @@ def format_for_json(packages, options):
'name': dist.project_name,
'version': six.text_type(dist.version),
}
if options.verbose >= 1:
info['location'] = dist.location
info['installer'] = get_installer(dist)
if options.outdated:
info['latest_version'] = six.text_type(dist.latest_version)
info['latest_filetype'] = dist.latest_filetype

View file

@ -3,20 +3,19 @@ from __future__ import absolute_import
import logging
import sys
import textwrap
from collections import OrderedDict
from pip.basecommand import Command, SUCCESS
from pip.download import PipXmlrpcTransport
from pip.models import PyPI
from pip.utils import get_terminal_size
from pip.utils.logging import indent_log
from pip.exceptions import CommandError
from pip.status_codes import NO_MATCHES_FOUND
from pip._vendor.packaging.version import parse as parse_version
from pip._vendor import pkg_resources
from pip._vendor.packaging.version import parse as parse_version
from pip._vendor.six.moves import xmlrpc_client
from pip.basecommand import SUCCESS, Command
from pip.download import PipXmlrpcTransport
from pip.exceptions import CommandError
from pip.models import PyPI
from pip.status_codes import NO_MATCHES_FOUND
from pip.utils import get_terminal_size
from pip.utils.logging import indent_log
logger = logging.getLogger(__name__)
@ -27,6 +26,7 @@ class SearchCommand(Command):
usage = """
%prog [options] <query>"""
summary = 'Search PyPI for packages.'
ignore_require_venv = True
def __init__(self, *args, **kw):
super(SearchCommand, self).__init__(*args, **kw)
@ -97,7 +97,7 @@ def print_results(hits, name_column_width=None, terminal_width=None):
return
if name_column_width is None:
name_column_width = max([
len(hit['name']) + len(hit.get('versions', ['-'])[-1])
len(hit['name']) + len(highest_version(hit.get('versions', ['-'])))
for hit in hits
]) + 4
@ -105,7 +105,7 @@ def print_results(hits, name_column_width=None, terminal_width=None):
for hit in hits:
name = hit['name']
summary = hit['summary'] or ''
version = hit.get('versions', ['-'])[-1]
latest = highest_version(hit.get('versions', ['-']))
if terminal_width is not None:
target_width = terminal_width - name_column_width - 5
if target_width > 10:
@ -114,13 +114,12 @@ def print_results(hits, name_column_width=None, terminal_width=None):
summary = ('\n' + ' ' * (name_column_width + 3)).join(summary)
line = '%-*s - %s' % (name_column_width,
'%s (%s)' % (name, version), summary)
'%s (%s)' % (name, latest), summary)
try:
logger.info(line)
if name in installed_packages:
dist = pkg_resources.get_distribution(name)
with indent_log():
latest = highest_version(hit['versions'])
if dist.version == latest:
logger.info('INSTALLED: %s (latest)', dist.version)
else:

View file

@ -1,14 +1,14 @@
from __future__ import absolute_import
from email.parser import FeedParser
import logging
import os
from email.parser import FeedParser
from pip.basecommand import Command
from pip.status_codes import SUCCESS, ERROR
from pip._vendor import pkg_resources
from pip._vendor.packaging.utils import canonicalize_name
from pip.basecommand import Command
from pip.status_codes import ERROR, SUCCESS
logger = logging.getLogger(__name__)
@ -19,6 +19,7 @@ class ShowCommand(Command):
usage = """
%prog [options] <package> ..."""
summary = 'Show information about installed packages.'
ignore_require_venv = True
def __init__(self, *args, **kw):
super(ShowCommand, self).__init__(*args, **kw)

View file

@ -1,10 +1,10 @@
from __future__ import absolute_import
import pip
from pip.wheel import WheelCache
from pip.req import InstallRequirement, RequirementSet, parse_requirements
from pip._vendor.packaging.utils import canonicalize_name
from pip.basecommand import Command
from pip.exceptions import InstallationError
from pip.req import InstallRequirement, parse_requirements
class UninstallCommand(Command):
@ -44,33 +44,25 @@ class UninstallCommand(Command):
def run(self, options, args):
with self._build_session(options) as session:
format_control = pip.index.FormatControl(set(), set())
wheel_cache = WheelCache(options.cache_dir, format_control)
requirement_set = RequirementSet(
build_dir=None,
src_dir=None,
download_dir=None,
isolated=options.isolated_mode,
session=session,
wheel_cache=wheel_cache,
)
reqs_to_uninstall = {}
for name in args:
requirement_set.add_requirement(
InstallRequirement.from_line(
name, isolated=options.isolated_mode,
wheel_cache=wheel_cache
)
req = InstallRequirement.from_line(
name, isolated=options.isolated_mode,
)
if req.name:
reqs_to_uninstall[canonicalize_name(req.name)] = req
for filename in options.requirements:
for req in parse_requirements(
filename,
options=options,
session=session,
wheel_cache=wheel_cache):
requirement_set.add_requirement(req)
if not requirement_set.has_requirements:
session=session):
if req.name:
reqs_to_uninstall[canonicalize_name(req.name)] = req
if not reqs_to_uninstall:
raise InstallationError(
'You must give at least one requirement to %(name)s (see '
'"pip help %(name)s")' % dict(name=self.name)
)
requirement_set.uninstall(auto_confirm=options.yes)
for req in reqs_to_uninstall.values():
req.uninstall(auto_confirm=options.yes)
req.uninstalled_pathset.commit()

View file

@ -4,14 +4,13 @@ from __future__ import absolute_import
import logging
import os
from pip import cmdoptions
from pip.basecommand import RequirementCommand
from pip.exceptions import CommandError, PreviousBuildDirError
from pip.req import RequirementSet
from pip.utils import import_or_raise
from pip.utils.build import BuildDirectory
from pip.wheel import WheelCache, WheelBuilder
from pip import cmdoptions
from pip.wheel import WheelBuilder, WheelCache
logger = logging.getLogger(__name__)

View file

@ -1,18 +1,18 @@
"""Configuration management setup
"""
import re
import os
import re
import sys
from pip._vendor.six.moves import configparser
from pip.locations import (
legacy_config_file, config_basename, running_under_virtualenv,
config_basename, legacy_config_file, running_under_virtualenv,
site_config_files
)
from pip.utils import appdirs
_environ_prefix_re = re.compile(r"^PIP_", re.I)

View file

@ -13,44 +13,44 @@ import shutil
import sys
import tempfile
from pip._vendor import requests, six
from pip._vendor.cachecontrol import CacheControlAdapter
from pip._vendor.cachecontrol.caches import FileCache
from pip._vendor.lockfile import LockError
from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter
from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth
from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response
from pip._vendor.requests.packages import urllib3
from pip._vendor.requests.structures import CaseInsensitiveDict
from pip._vendor.requests.utils import get_netrc_auth
from pip._vendor.six.moves import xmlrpc_client
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves.urllib import request as urllib_request
from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote
import pip
from pip.exceptions import HashMismatch, InstallationError
from pip.locations import write_delete_marker_file
from pip.models import PyPI
from pip.utils import (
ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume,
display_path, format_size, get_installed_version, rmtree, splitext,
unpack_file
)
from pip.utils.encoding import auto_decode
from pip.utils.filesystem import check_path_owner
from pip.utils.glibc import libc_ver
from pip.utils.logging import indent_log
from pip.utils.setuptools_build import SETUPTOOLS_SHIM
from pip.utils.ui import DownloadProgressProvider
from pip.vcs import vcs
try:
import ssl # noqa
HAS_TLS = True
except ImportError:
HAS_TLS = False
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves.urllib import request as urllib_request
import pip
from pip.exceptions import InstallationError, HashMismatch
from pip.models import PyPI
from pip.utils import (splitext, rmtree, format_size, display_path,
backup_dir, ask_path_exists, unpack_file,
ARCHIVE_EXTENSIONS, consume, call_subprocess,
get_installed_version)
from pip.utils.encoding import auto_decode
from pip.utils.filesystem import check_path_owner
from pip.utils.logging import indent_log
from pip.utils.setuptools_build import SETUPTOOLS_SHIM
from pip.utils.glibc import libc_ver
from pip.utils.ui import DownloadProgressProvider
from pip.locations import write_delete_marker_file
from pip.vcs import vcs
from pip._vendor import requests, six
from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter
from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth
from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response
from pip._vendor.requests.utils import get_netrc_auth
from pip._vendor.requests.structures import CaseInsensitiveDict
from pip._vendor.requests.packages import urllib3
from pip._vendor.cachecontrol import CacheControlAdapter
from pip._vendor.cachecontrol.caches import FileCache
from pip._vendor.lockfile import LockError
from pip._vendor.six.moves import xmlrpc_client
__all__ = ['get_file_content',
'is_url', 'url_to_path', 'path_to_url',
'is_archive_file', 'unpack_vcs_link',
@ -207,8 +207,9 @@ class MultiDomainBasicAuth(AuthBase):
if "@" in netloc:
userinfo = netloc.rsplit("@", 1)[0]
if ":" in userinfo:
return userinfo.split(":", 1)
return userinfo, None
user, pwd = userinfo.split(":", 1)
return (urllib_unquote(user), urllib_unquote(pwd))
return urllib_unquote(userinfo), None
return None, None

View file

@ -1,42 +1,41 @@
"""Routines related to PyPI, indexes"""
from __future__ import absolute_import
import logging
import cgi
from collections import namedtuple
import itertools
import sys
import os
import re
import logging
import mimetypes
import os
import posixpath
import re
import sys
import warnings
from collections import namedtuple
from pip._vendor import html5lib, requests, six
from pip._vendor.distlib.compat import unescape
from pip._vendor.packaging import specifiers
from pip._vendor.packaging.utils import canonicalize_name
from pip._vendor.packaging.version import parse as parse_version
from pip._vendor.requests.exceptions import SSLError
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves.urllib import request as urllib_request
from pip.compat import ipaddress
from pip.download import HAS_TLS, is_url, path_to_url, url_to_path
from pip.exceptions import (
BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename,
UnsupportedWheel
)
from pip.pep425tags import get_supported
from pip.utils import (
cached_property, splitext, normalize_path,
ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS,
ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, cached_property, normalize_path,
splitext
)
from pip.utils.deprecation import RemovedInPip11Warning
from pip.utils.logging import indent_log
from pip.utils.packaging import check_requires_python
from pip.exceptions import (
DistributionNotFound, BestVersionAlreadyInstalled, InvalidWheelFilename,
UnsupportedWheel,
)
from pip.download import HAS_TLS, is_url, path_to_url, url_to_path
from pip.wheel import Wheel, wheel_ext
from pip.pep425tags import get_supported
from pip._vendor import html5lib, requests, six
from pip._vendor.packaging.version import parse as parse_version
from pip._vendor.packaging.utils import canonicalize_name
from pip._vendor.packaging import specifiers
from pip._vendor.requests.exceptions import SSLError
from pip._vendor.distlib.compat import unescape
__all__ = ['FormatControl', 'fmt_ctl_handle_mutual_exclude', 'PackageFinder']
@ -341,9 +340,9 @@ class PackageFinder(object):
# log a warning that we are ignoring it.
logger.warning(
"The repository located at %s is not a trusted or secure host and "
"is being ignored. If this repository is available via HTTPS it "
"is recommended to use HTTPS instead, otherwise you may silence "
"this warning and allow it anyways with '--trusted-host %s'.",
"is being ignored. If this repository is available via HTTPS we "
"recommend you use HTTPS instead, otherwise you may silence "
"this warning and allow it anyway with '--trusted-host %s'.",
parsed.hostname,
parsed.hostname,
)

View file

@ -7,14 +7,12 @@ import platform
import site
import sys
import sysconfig
from distutils import sysconfig as distutils_sysconfig
from distutils.command.install import install, SCHEME_KEYS # noqa
from distutils.command.install import SCHEME_KEYS, install # noqa
from pip.compat import WINDOWS, expanduser
from pip.utils import appdirs
# Application Directories
USER_CACHE_DIR = appdirs.user_cache_dir("pip")
@ -88,7 +86,12 @@ site_packages = sysconfig.get_path("purelib")
# for more information.
if platform.python_implementation().lower() == "pypy":
site_packages = distutils_sysconfig.get_python_lib()
user_site = site.USER_SITE
try:
# Use getusersitepackages if this is present, as it ensures that the
# value is initialised properly.
user_site = site.getusersitepackages()
except AttributeError:
user_site = site.USER_SITE
user_dir = expanduser('~')
if WINDOWS:
bin_py = os.path.join(sys.prefix, 'Scripts')

View file

@ -3,15 +3,17 @@ from __future__ import absolute_import
import logging
import os
import re
import warnings
from pip.exceptions import InstallationError
from pip.req import InstallRequirement
from pip.req.req_file import COMMENT_RE
from pip.utils import get_installed_distributions, dist_is_editable
from pip._vendor import pkg_resources
from pip._vendor.packaging.utils import canonicalize_name
from pip._vendor.pkg_resources import RequirementParseError
from pip.exceptions import InstallationError
from pip.req import InstallRequirement
from pip.req.req_file import COMMENT_RE
from pip.utils import dist_is_editable, get_installed_distributions
from pip.utils.deprecation import RemovedInPip11Warning
logger = logging.getLogger(__name__)
@ -193,6 +195,11 @@ class FrozenRequirement(object):
'for this package:'
)
else:
warnings.warn(
"SVN editable detection based on dependency links "
"will be dropped in the future.",
RemovedInPip11Warning,
)
comments.append(
'# Installing as editable to satisfy requirement %s:' %
req

View file

@ -2,13 +2,12 @@
from __future__ import absolute_import
import distutils.util
import logging
import platform
import re
import sys
import sysconfig
import warnings
import platform
import logging
from collections import OrderedDict
import pip.utils.glibc

View file

@ -4,19 +4,19 @@ Requirements file parsing
from __future__ import absolute_import
import optparse
import os
import re
import shlex
import sys
import optparse
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves import filterfalse
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip.download import get_file_content
from pip.req.req_install import InstallRequirement
from pip.exceptions import (RequirementsFileParseError)
from pip import cmdoptions
from pip.download import get_file_content
from pip.exceptions import RequirementsFileParseError
from pip.req.req_install import InstallRequirement
__all__ = ['parse_requirements']

View file

@ -10,7 +10,6 @@ import tempfile
import traceback
import warnings
import zipfile
from distutils.util import change_root
from email.parser import FeedParser
@ -19,36 +18,28 @@ from pip._vendor.packaging import specifiers
from pip._vendor.packaging.markers import Marker
from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
from pip._vendor.packaging.utils import canonicalize_name
from pip._vendor.packaging.version import Version, parse as parse_version
from pip._vendor.pkg_resources import parse_requirements, RequirementParseError
from pip._vendor.packaging.version import parse as parse_version
from pip._vendor.packaging.version import Version
from pip._vendor.pkg_resources import RequirementParseError, parse_requirements
import pip.wheel
from pip.compat import native_str
from pip.download import is_url, url_to_path, path_to_url, is_archive_file
from pip.exceptions import (
InstallationError, UninstallationError,
)
from pip.locations import (
running_under_virtualenv, PIP_DELETE_MARKER_FILENAME,
)
from pip.download import is_archive_file, is_url, path_to_url, url_to_path
from pip.exceptions import InstallationError, UninstallationError
from pip.locations import PIP_DELETE_MARKER_FILENAME, running_under_virtualenv
from pip.req.req_uninstall import UninstallPathSet
from pip.utils import (
display_path, rmtree, ask_path_exists, backup_dir, is_installable_dir,
dist_in_usersite, dist_in_site_packages,
call_subprocess, read_text_file, _make_build_dir, ensure_dir,
get_installed_version,
_make_build_dir, ask_path_exists, backup_dir, call_subprocess,
display_path, dist_in_site_packages, dist_in_usersite, ensure_dir,
get_installed_version, is_installable_dir, read_text_file, rmtree
)
from pip.utils.hashes import Hashes
from pip.utils.deprecation import RemovedInPip11Warning
from pip.utils.hashes import Hashes
from pip.utils.logging import indent_log
from pip.utils.setuptools_build import SETUPTOOLS_SHIM
from pip.utils.ui import open_spinner
from pip.req.req_uninstall import UninstallPathSet
from pip.vcs import vcs
from pip.wheel import move_wheel_files, Wheel
from pip.wheel import Wheel, move_wheel_files
logger = logging.getLogger(__name__)
@ -77,7 +68,10 @@ class InstallRequirement(object):
self.req = req
self.comes_from = comes_from
self.constraint = constraint
self.source_dir = source_dir
if source_dir is not None:
self.source_dir = os.path.normpath(os.path.abspath(source_dir))
else:
self.source_dir = None
self.editable = editable
self._wheel_cache = wheel_cache
@ -388,7 +382,7 @@ class InstallRequirement(object):
shutil.move(old_location, new_location)
self._temp_build_dir = new_location
self._ideal_build_dir = None
self.source_dir = new_location
self.source_dir = os.path.normpath(os.path.abspath(new_location))
self._egg_info_path = None
@property

View file

@ -1,24 +1,26 @@
from __future__ import absolute_import
from collections import defaultdict
from itertools import chain
import logging
import os
from collections import defaultdict
from itertools import chain
from pip._vendor import pkg_resources
from pip._vendor import requests
from pip._vendor import pkg_resources, requests
from pip.compat import expanduser
from pip.download import (is_file_url, is_dir_url, is_vcs_url, url_to_path,
unpack_url)
from pip.exceptions import (InstallationError, BestVersionAlreadyInstalled,
DistributionNotFound, PreviousBuildDirError,
HashError, HashErrors, HashUnpinned,
DirectoryUrlHashUnsupported, VcsHashUnsupported,
UnsupportedPythonVersion)
from pip.download import (
is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path
)
from pip.exceptions import (
BestVersionAlreadyInstalled, DirectoryUrlHashUnsupported,
DistributionNotFound, HashError, HashErrors, HashUnpinned,
InstallationError, PreviousBuildDirError, UnsupportedPythonVersion,
VcsHashUnsupported
)
from pip.req.req_install import InstallRequirement
from pip.utils import (
display_path, dist_in_usersite, ensure_dir, normalize_path)
display_path, dist_in_usersite, ensure_dir, normalize_path
)
from pip.utils.hashes import MissingHashes
from pip.utils.logging import indent_log
from pip.utils.packaging import check_dist_requires_python
@ -338,13 +340,6 @@ class RequirementSet(object):
return self.requirements[self.requirement_aliases[name]]
raise KeyError("No project with the name %r" % project_name)
def uninstall(self, auto_confirm=False):
for req in self.requirements.values():
if req.constraint:
continue
req.uninstall(auto_confirm=auto_confirm)
req.uninstalled_pathset.commit()
def prepare_files(self, finder):
"""
Prepare process. Create temp directories, download and/or unpack files.

View file

@ -10,19 +10,15 @@ import tempfile
from pip._vendor import pkg_resources
from pip.compat import uses_pycache, WINDOWS, cache_from_source
from pip.compat import WINDOWS, cache_from_source, uses_pycache
from pip.exceptions import UninstallationError
from pip.locations import (
bin_py, bin_user,
)
from pip.locations import bin_py, bin_user
from pip.utils import (
rmtree, ask, dist_in_usersite, is_local,
egg_link_path, FakeFile,
renames, normalize_path, dist_is_local,
FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local,
normalize_path, renames, rmtree
)
from pip.utils.logging import indent_log
logger = logging.getLogger(__name__)

View file

@ -7,9 +7,10 @@ from __future__ import absolute_import
import os
import sys
from pip.compat import WINDOWS, expanduser
from pip._vendor.six import PY2, text_type
from pip.compat import WINDOWS, expanduser
def user_cache_dir(appname):
r"""

View file

@ -2,7 +2,6 @@ import codecs
import locale
import re
BOMS = [
(codecs.BOM_UTF8, 'utf8'),
(codecs.BOM_UTF16, 'utf16'),

View file

@ -1,8 +1,8 @@
from __future__ import absolute_import
import re
import ctypes
import platform
import re
import warnings

View file

@ -2,10 +2,10 @@ from __future__ import absolute_import
import hashlib
from pip.exceptions import HashMismatch, HashMissing, InstallationError
from pip.utils import read_chunks
from pip._vendor.six import iteritems, iterkeys, itervalues
from pip.exceptions import HashMismatch, HashMissing, InstallationError
from pip.utils import read_chunks
# The recommended hash algo of the moment. Change this whenever the state of
# the art changes; it won't hurt backward compatibility.

View file

@ -5,13 +5,14 @@ import logging
import logging.handlers
import os
from pip.compat import WINDOWS
from pip.utils import ensure_dir
try:
import threading
except ImportError:
import dummy_threading as threading
from pip.compat import WINDOWS
from pip.utils import ensure_dir
try:
from pip._vendor import colorama

View file

@ -15,7 +15,6 @@ from pip.locations import USER_CACHE_DIR, running_under_virtualenv
from pip.utils import ensure_dir, get_installed_version
from pip.utils.filesystem import check_path_owner
SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ"

View file

@ -1,13 +1,11 @@
from __future__ import absolute_import
from email.parser import FeedParser
import logging
import sys
from email.parser import FeedParser
from pip._vendor.packaging import specifiers
from pip._vendor.packaging import version
from pip._vendor import pkg_resources
from pip._vendor.packaging import specifiers, version
from pip import exceptions
@ -61,3 +59,11 @@ def check_dist_requires_python(dist):
"Package %s has an invalid Requires-Python entry %s - %s" % (
dist.project_name, requires_python, e))
return
def get_installer(dist):
if dist.has_metadata('INSTALLER'):
for line in dist.get_metadata_lines('INSTALLER'):
if line.strip():
return line.strip()
return ''

View file

@ -1,25 +1,23 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import absolute_import, division
import itertools
import sys
from signal import signal, SIGINT, default_int_handler
import time
import contextlib
import itertools
import logging
import sys
import time
from signal import SIGINT, default_int_handler, signal
from pip._vendor import six
from pip._vendor.progress.bar import (
Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar,
ShadyBar
)
from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin
from pip._vendor.progress.spinner import Spinner
from pip.compat import WINDOWS
from pip.utils import format_size
from pip.utils.logging import get_indentation
from pip._vendor import six
from pip._vendor.progress.bar import Bar, IncrementalBar
from pip._vendor.progress.bar import FillingCirclesBar, FillingSquaresBar
from pip._vendor.progress.bar import ChargingBar, ShadyBar
from pip._vendor.progress.helpers import (WritelnMixin,
HIDE_CURSOR, SHOW_CURSOR)
from pip._vendor.progress.spinner import Spinner
try:
from pip._vendor import colorama

View file

@ -327,7 +327,10 @@ class VersionControl(object):
# errno.ENOENT = no such file or directory
# In other words, the VCS executable isn't available
if e.errno == errno.ENOENT:
raise BadCommand('Cannot find command %r' % self.name)
raise BadCommand(
'Cannot find command %r - do you have '
'%r installed and in your '
'PATH?' % (self.name, self.name))
else:
raise # re-raise exception if a different error occurred

View file

@ -4,16 +4,16 @@ import logging
import os
import tempfile
from pip.download import path_to_url
from pip.utils import display_path, rmtree
from pip.vcs import VersionControl, vcs
# TODO: Get this into six.moves.urllib.parse
try:
from urllib import parse as urllib_parse
except ImportError:
import urlparse as urllib_parse
from pip.utils import rmtree, display_path
from pip.vcs import vcs, VersionControl
from pip.download import path_to_url
logger = logging.getLogger(__name__)

View file

@ -1,18 +1,17 @@
from __future__ import absolute_import
import logging
import tempfile
import os.path
import tempfile
from pip._vendor.packaging.version import parse as parse_version
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves.urllib import request as urllib_request
from pip.compat import samefile
from pip.exceptions import BadCommand
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip._vendor.six.moves.urllib import request as urllib_request
from pip._vendor.packaging.version import parse as parse_version
from pip.utils import display_path, rmtree
from pip.vcs import vcs, VersionControl
from pip.vcs import VersionControl, vcs
urlsplit = urllib_parse.urlsplit
urlunsplit = urllib_parse.urlunsplit
@ -92,7 +91,8 @@ class Git(VersionControl):
return [revisions[rev]]
else:
logger.warning(
"Could not find a tag or branch '%s', assuming commit.", rev,
"Could not find a tag or branch '%s', assuming commit or ref",
rev,
)
return rev_options
@ -146,9 +146,14 @@ class Git(VersionControl):
# Only do a checkout if rev_options differs from HEAD
if not self.check_version(dest, rev_options):
self.run_command(
['checkout', '-q'] + rev_options,
['fetch', '-q', url] + rev_options,
cwd=dest,
)
self.run_command(
['checkout', '-q', 'FETCH_HEAD'],
cwd=dest,
)
#: repo may contain submodules
self.update_submodules(dest)

View file

@ -4,11 +4,11 @@ import logging
import os
import tempfile
from pip.utils import display_path, rmtree
from pip.vcs import vcs, VersionControl
from pip.download import path_to_url
from pip._vendor.six.moves import configparser
from pip.download import path_to_url
from pip.utils import display_path, rmtree
from pip.vcs import VersionControl, vcs
logger = logging.getLogger(__name__)

View file

@ -7,9 +7,9 @@ import re
from pip._vendor.six.moves.urllib import parse as urllib_parse
from pip.index import Link
from pip.utils import rmtree, display_path
from pip.utils import display_path, rmtree
from pip.utils.logging import indent_log
from pip.vcs import vcs, VersionControl
from pip.vcs import VersionControl, vcs
_svn_xml_url_re = re.compile('url="([^"]+)"')
_svn_rev_re = re.compile(r'committed-rev="(\d+)"')

View file

@ -17,25 +17,28 @@ import stat
import sys
import tempfile
import warnings
from base64 import urlsafe_b64encode
from email.parser import Parser
from pip._vendor import pkg_resources
from pip._vendor.distlib.scripts import ScriptMaker
from pip._vendor.packaging.utils import canonicalize_name
from pip._vendor.six import StringIO
import pip
from pip import pep425tags
from pip.compat import expanduser
from pip.download import path_to_url, unpack_url
from pip.exceptions import (
InstallationError, InvalidWheelFilename, UnsupportedWheel)
from pip.locations import distutils_scheme, PIP_DELETE_MARKER_FILENAME
from pip import pep425tags
from pip.utils import (
call_subprocess, ensure_dir, captured_stdout, rmtree, read_chunks,
InstallationError, InvalidWheelFilename, UnsupportedWheel
)
from pip.locations import PIP_DELETE_MARKER_FILENAME, distutils_scheme
from pip.utils import (
call_subprocess, captured_stdout, ensure_dir, read_chunks, rmtree
)
from pip.utils.ui import open_spinner
from pip.utils.logging import indent_log
from pip.utils.setuptools_build import SETUPTOOLS_SHIM
from pip.utils.ui import open_spinner
from pip._vendor.distlib.scripts import ScriptMaker
from pip._vendor import pkg_resources
from pip._vendor.packaging.utils import canonicalize_name
@ -43,7 +46,6 @@ from pip._vendor import pytoml
from sysconfig import get_paths
wheel_ext = '.whl'
VERSION_COMPATIBLE = (1, 0)

View file

@ -3,13 +3,11 @@ import os
import shutil
import sys
import pytest
import six
import pip
import pytest
from pip.utils import appdirs
from tests.lib import SRC_DIR, TestData
from tests.lib.path import Path
from tests.lib.scripttest import PipTestEnvironment

View file

@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
from distutils.core import setup
import sys
from distutils.core import setup
class FakeError(Exception):
pass

View file

@ -1,4 +1,4 @@
from setuptools import setup, find_packages
from setuptools import find_packages, setup
version = '0.1dev'

View file

@ -3,6 +3,7 @@
from setuptools import setup
from setuptools.command import egg_info as orig_egg_info
class egg_info (orig_egg_info.egg_info):
def run(self):
orig_egg_info.egg_info.run(self)

View file

@ -1,3 +1,3 @@
from distutils.core import setup
setup()
from distutils.core import setup
setup()

View file

@ -1,5 +1,6 @@
import os
from setuptools import setup, find_packages
from setuptools import find_packages, setup
def path_to_url(path):

View file

@ -1,5 +1,6 @@
import os
from setuptools import setup, find_packages
from setuptools import find_packages, setup
def path_to_url(path):

View file

@ -1,5 +1,6 @@
import os
from setuptools import setup, find_packages
from setuptools import find_packages, setup
def path_to_url(path):

View file

@ -1,4 +1,5 @@
import setuptools
setuptools.setup(
name="requires_wheelbroken_upper",
version="0",

View file

@ -1,9 +1,10 @@
# A chatty setup.py for testing pip subprocess output handling
from setuptools import setup
import os
import sys
from setuptools import setup
print("HELLO FROM CHATTYMODULE %s" % (sys.argv[1],))
print(os.environ)
print(sys.argv)

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
from setuptools import find_packages, setup
setup(name='compilewheel',
version='1.0',

View file

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
from setuptools import setup
setup(
name='prjwithdatafile',
version="1.0",
packages=['prjwithdatafile'],
data_files=[
(r'packages1', ['prjwithdatafile/README.txt']),
(r'packages2', ['prjwithdatafile/README.txt'])
]
)
# -*- coding: utf-8 -*-
from setuptools import setup
setup(
name='prjwithdatafile',
version="1.0",
packages=['prjwithdatafile'],
data_files=[
(r'packages1', ['prjwithdatafile/README.txt']),
(r'packages2', ['prjwithdatafile/README.txt'])
]
)

View file

@ -1,4 +1,4 @@
from setuptools import setup, find_packages
from setuptools import find_packages, setup
setup(name='requires_simple',
version='0.1',

View file

@ -1,8 +1,9 @@
from setuptools import setup, find_packages
import codecs
import os
import re
from setuptools import find_packages, setup
here = os.path.abspath(os.path.dirname(__file__))
# Read the version number from a source file.

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
from setuptools import find_packages, setup
setup(name='simplewheel',
version='1.0',

View file

@ -1,5 +1,5 @@
#!/usr/bin/env python
from setuptools import setup, find_packages
from setuptools import find_packages, setup
setup(name='simplewheel',
version='2.0',

View file

@ -1,6 +1,5 @@
from setuptools import setup
setup(
name="singlemodule",
version='0.0.1',

View file

@ -1,7 +1,7 @@
import os
import textwrap
import pytest
import pytest
from pip.status_codes import ERROR
from tests.lib.path import Path

View file

@ -1,13 +1,12 @@
import sys
import os
import re
import sys
import textwrap
from doctest import ELLIPSIS, OutputChecker
import pytest
from doctest import OutputChecker, ELLIPSIS
from tests.lib import _create_test_package, _create_test_package_with_srcdir
distribute_re = re.compile('^distribute==[0-9.]+\n', re.MULTILINE)

View file

@ -1,10 +1,9 @@
import pytest
from pip.exceptions import CommandError
from pip.basecommand import ERROR, SUCCESS
from pip.commands.help import HelpCommand
from pip.commands import commands_dict as commands
from mock import Mock
from pip.basecommand import ERROR, SUCCESS
from pip.commands import commands_dict as commands
from pip.commands.help import HelpCommand
from pip.exceptions import CommandError
def test_run_method_should_return_success_when_finds_command_name():

View file

@ -1,19 +1,17 @@
import glob
import os
import sys
import textwrap
import glob
from os.path import join, curdir, pardir
from os.path import curdir, join, pardir
import pytest
from pip import pep425tags
from pip.utils import appdirs, rmtree
from pip.status_codes import ERROR
from tests.lib import (pyversion, pyversion_tuple,
_create_test_package, _create_svn_repo, path_to_url,
create_test_package_with_setup,
requirements_file)
from pip.utils import appdirs, rmtree
from tests.lib import (
_create_svn_repo, _create_test_package, create_test_package_with_setup,
path_to_url, pyversion, pyversion_tuple, requirements_file
)
from tests.lib.local_repos import local_checkout
from tests.lib.path import Path
@ -271,6 +269,41 @@ def test_install_from_local_directory(script, data):
assert egg_info_folder in result.files_created, str(result)
def test_install_relative_directory(script, data):
"""
Test installing a requirement using a relative path.
"""
egg_info_file = (
script.site_packages / 'FSPkg-0.1.dev0-py%s.egg-info' % pyversion
)
egg_link_file = (
script.site_packages / 'FSPkg.egg-link'
)
package_folder = script.site_packages / 'fspkg'
# Compute relative install path to FSPkg from scratch path.
full_rel_path = data.packages.join('FSPkg') - script.scratch_path
embedded_rel_path = script.scratch_path.join(full_rel_path)
# For each relative path, install as either editable or not using either
# URLs with egg links or not.
for req_path in (full_rel_path,
'file:' + full_rel_path + '#egg=FSPkg',
embedded_rel_path):
# Regular install.
result = script.pip('install', req_path,
cwd=script.scratch_path)
assert egg_info_file in result.files_created, str(result)
assert package_folder in result.files_created, str(result)
script.pip('uninstall', '-y', 'fspkg')
# Editable install.
result = script.pip('install', '-e' + req_path,
cwd=script.scratch_path)
assert egg_link_file in result.files_created, str(result)
script.pip('uninstall', '-y', 'fspkg')
def test_install_quiet(script, data):
"""
Test that install -q is actually quiet.

View file

@ -1,11 +1,10 @@
import os
import pytest
from os.path import exists
from tests.lib.local_repos import local_checkout
import pytest
from pip.locations import write_delete_marker_file
from pip.status_codes import PREVIOUS_BUILD_DIR_ERROR
from tests.lib.local_repos import local_checkout
def test_cleanup_after_install(script, data):

View file

@ -3,8 +3,9 @@ Tests for compatibility workarounds.
"""
import os
import pytest
from tests.lib import pyversion, assert_all_changes
from tests.lib import assert_all_changes, pyversion
@pytest.mark.network

View file

@ -1,6 +1,7 @@
import os
import tempfile
import textwrap
import pytest

View file

@ -1,7 +1,8 @@
import textwrap
import pytest
from os.path import join
import pytest
@pytest.mark.network
def test_simple_extras_install_from_pypi(script):

Some files were not shown because too many files have changed in this diff Show more