mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Merge branch 'master' into req-types-finished
This commit is contained in:
commit
0c0bfe256d
20
AUTHORS.txt
20
AUTHORS.txt
|
@ -1,8 +1,11 @@
|
|||
AceGentile <ventogrigio83@gmail.com>
|
||||
Adam Chainz <adam@adamj.eu>
|
||||
Adam Tse <atse@users.noreply.github.com>
|
||||
Adam Wentz <awentz@theonion.com>
|
||||
Adrien Morison <adrien.morison@gmail.com>
|
||||
Alan Yee <alyee@ucsd.edu>
|
||||
Albert-Guan <albert.guan94@gmail.com>
|
||||
albertg <albert.guan94@gmail.com>
|
||||
Aleks Bunin <github@compuix.com>
|
||||
Alethea Flowers <magicalgirl@google.com>
|
||||
Alex Gaynor <alex.gaynor@gmail.com>
|
||||
|
@ -14,6 +17,7 @@ Alexandre Conrad <alexandre.conrad@gmail.com>
|
|||
Alexey Popravka <a.popravka@smartweb.com.ua>
|
||||
Alexey Popravka <alexey.popravka@horsedevel.com>
|
||||
Alli <alzeih@users.noreply.github.com>
|
||||
Ami Fischman <ami@fischman.org>
|
||||
Anatoly Techtonik <techtonik@gmail.com>
|
||||
Andrei Geacar <andrei.geacar@gmail.com>
|
||||
Andrew Gaul <andrew@gaul.org>
|
||||
|
@ -49,6 +53,7 @@ Ben Darnell <ben@bendarnell.com>
|
|||
Ben Hoyt <benhoyt@gmail.com>
|
||||
Ben Rosser <rosser.bjr@gmail.com>
|
||||
Bence Nagy <bence@underyx.me>
|
||||
Benjamin Peterson <benjamin@python.org>
|
||||
Benjamin VanEvery <ben@simondata.com>
|
||||
Benoit Pierre <benoit.pierre@gmail.com>
|
||||
Berker Peksag <berker.peksag@gmail.com>
|
||||
|
@ -59,6 +64,8 @@ Brad Erickson <eosrei@gmail.com>
|
|||
Bradley Ayers <bradley.ayers@gmail.com>
|
||||
Brandon L. Reiss <brandon@damyata.co>
|
||||
Brett Randall <javabrett@gmail.com>
|
||||
Brian Cristante <33549821+brcrista@users.noreply.github.com>
|
||||
Brian Cristante <brcrista@microsoft.com>
|
||||
Brian Rosner <brosner@gmail.com>
|
||||
BrownTruck <BrownTruck@users.noreply.github.com>
|
||||
Bruno Oliveira <nicoddemus@gmail.com>
|
||||
|
@ -75,6 +82,7 @@ Carol Willing <carolcode@willingconsulting.com>
|
|||
Carter Thayer <carterwthayer@gmail.com>
|
||||
Cass <cass.petrus@gmail.com>
|
||||
Chandrasekhar Atina <chandu.atina@gmail.com>
|
||||
Chih-Hsuan Yen <yen@chyen.cc>
|
||||
Chris Brinker <chris.brinker@gmail.com>
|
||||
Chris Jerdonek <chris.jerdonek@gmail.com>
|
||||
Chris McDonough <chrism@plope.com>
|
||||
|
@ -133,9 +141,11 @@ Ed Morley <501702+edmorley@users.noreply.github.com>
|
|||
Ed Morley <emorley@mozilla.com>
|
||||
elainechan <elaine.chan@outlook.com>
|
||||
Eli Schwartz <eschwartz93@gmail.com>
|
||||
Eli Schwartz <eschwartz@archlinux.org>
|
||||
Emil Styrke <emil.styrke@gmail.com>
|
||||
Endoh Takanao <djmchl@gmail.com>
|
||||
enoch <lanxenet@gmail.com>
|
||||
Erdinc Mutlu <erdinc_mutlu@yahoo.com>
|
||||
Eric Gillingham <Gillingham@bikezen.net>
|
||||
Eric Hanchrow <eric.hanchrow@gmail.com>
|
||||
Eric Hopper <hopper@omnifarious.org>
|
||||
|
@ -149,6 +159,7 @@ Felix Yan <felixonmars@archlinux.org>
|
|||
fiber-space <fiber-space@users.noreply.github.com>
|
||||
Filip Kokosiński <filip.kokosinski@gmail.com>
|
||||
Florian Briand <ownerfrance+github@hotmail.com>
|
||||
Florian Rathgeber <florian.rathgeber@gmail.com>
|
||||
Francesco <f.guerrieri@gmail.com>
|
||||
Francesco Montesano <franz.bergesund@gmail.com>
|
||||
Gabriel Curio <g.curio@gmail.com>
|
||||
|
@ -253,6 +264,8 @@ Marc Tamlyn <marc.tamlyn@gmail.com>
|
|||
Marcus Smith <qwcode@gmail.com>
|
||||
Mariatta <Mariatta@users.noreply.github.com>
|
||||
Mark Kohler <mark.kohler@proteinsimple.com>
|
||||
Mark Williams <markrwilliams@gmail.com>
|
||||
Mark Williams <mrw@enotuniq.org>
|
||||
Markus Hametner <fin+github@xbhd.org>
|
||||
Masklinn <bitbucket.org@masklinn.net>
|
||||
Matej Stuchlik <mstuchli@redhat.com>
|
||||
|
@ -271,6 +284,7 @@ Matthias Bussonnier <bussonniermatthias@gmail.com>
|
|||
mattip <matti.picus@gmail.com>
|
||||
Maxim Kurnikov <maxim.kurnikov@gmail.com>
|
||||
Maxime Rouyrre <rouyrre+git@gmail.com>
|
||||
mbaluna <44498973+mbaluna@users.noreply.github.com>
|
||||
memoselyk <memoselyk@gmail.com>
|
||||
Michael <michael-k@users.noreply.github.com>
|
||||
Michael Aquilina <michaelaquilina@gmail.com>
|
||||
|
@ -284,6 +298,7 @@ Mihir Singh <git.service@mihirsingh.com>
|
|||
Min RK <benjaminrk@gmail.com>
|
||||
MinRK <benjaminrk@gmail.com>
|
||||
Miro Hrončok <miro@hroncok.cz>
|
||||
Monica Baluna <mbaluna@bloomberg.net>
|
||||
montefra <franz.bergesund@gmail.com>
|
||||
Monty Taylor <mordred@inaugust.com>
|
||||
Nate Coraor <nate@bx.psu.edu>
|
||||
|
@ -318,6 +333,7 @@ Paulus Schoutsen <paulus@paulusschoutsen.nl>
|
|||
Pavithra Eswaramoorthy <33131404+QueenCoffee@users.noreply.github.com>
|
||||
Pawel Jasinski <pawel.jasinski@gmail.com>
|
||||
Pekka Klärck <peke@iki.fi>
|
||||
Peter Lisák <peter.lisak@showmax.com>
|
||||
Peter Waller <peter.waller@gmail.com>
|
||||
petr-tik <petr-tik@users.noreply.github.com>
|
||||
Phaneendra Chiruvella <hi@pcx.io>
|
||||
|
@ -329,6 +345,7 @@ Philippe Ombredanne <pombredanne@gmail.com>
|
|||
Pi Delport <pjdelport@gmail.com>
|
||||
Pierre-Yves Rofes <github@rofes.fr>
|
||||
pip <pypa-dev@googlegroups.com>
|
||||
Prabhjyotsing Surjit Singh Sodhi <psinghsodhi@bloomberg.net>
|
||||
Pradyun Gedam <pradyunsg@gmail.com>
|
||||
Pratik Mallya <mallya@us.ibm.com>
|
||||
Preston Holmes <preston@ptone.com>
|
||||
|
@ -379,6 +396,7 @@ Stephan Erb <github@stephanerb.eu>
|
|||
stepshal <nessento@openmailbox.org>
|
||||
Steve (Gadget) Barnes <gadgetsteve@hotmail.com>
|
||||
Steve Barnes <gadgetsteve@hotmail.com>
|
||||
Steve Dower <steve.dower@microsoft.com>
|
||||
Steve Kowalik <steven@wedontsleep.org>
|
||||
Steven Myint <git@stevenmyint.com>
|
||||
stonebig <stonebig34@gmail.com>
|
||||
|
@ -418,11 +436,13 @@ W. Trevor King <wking@drexel.edu>
|
|||
Wil Tan <wil@dready.org>
|
||||
Wilfred Hughes <me@wilfred.me.uk>
|
||||
William ML Leslie <william.leslie.ttg@gmail.com>
|
||||
William T Olson <trevor@heytrevor.com>
|
||||
wim glenn <wim.glenn@gmail.com>
|
||||
Wolfgang Maier <wolfgang.maier@biologie.uni-freiburg.de>
|
||||
Xavier Fernandez <xav.fernandez@gmail.com>
|
||||
Xavier Fernandez <xavier.fernandez@polyconseil.fr>
|
||||
xoviat <xoviat@users.noreply.github.com>
|
||||
xtreak <tir.karthi@gmail.com>
|
||||
YAMAMOTO Takashi <yamamoto@midokura.com>
|
||||
Yen Chi Hsuan <yan12125@gmail.com>
|
||||
Yoval P <yoval@gmx.com>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2008-2018 The pip developers (see AUTHORS.txt file)
|
||||
Copyright (c) 2008-2019 The pip developers (see AUTHORS.txt file)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
83
NEWS.rst
83
NEWS.rst
|
@ -7,6 +7,89 @@
|
|||
|
||||
.. towncrier release notes start
|
||||
|
||||
19.0.1 (2019-01-23)
|
||||
===================
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Fix a crash when using --no-cache-dir with PEP 517 distributions (`#6158 <https://github.com/pypa/pip/issues/6158>`_, `#6171 <https://github.com/pypa/pip/issues/6171>`_)
|
||||
|
||||
|
||||
19.0 (2019-01-22)
|
||||
=================
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Deprecate support for Python 3.4 (`#6106 <https://github.com/pypa/pip/issues/6106>`_)
|
||||
- Start printing a warning for Python 2.7 to warn of impending Python 2.7 End-of-life and
|
||||
prompt users to start migrating to Python 3. (`#6148 <https://github.com/pypa/pip/issues/6148>`_)
|
||||
- Remove the deprecated ``--process-dependency-links`` option. (`#6060 <https://github.com/pypa/pip/issues/6060>`_)
|
||||
- Remove the deprecated SVN editable detection based on dependency links
|
||||
during freeze. (`#5866 <https://github.com/pypa/pip/issues/5866>`_)
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Implement PEP 517 (allow projects to specify a build backend via pyproject.toml). (`#5743 <https://github.com/pypa/pip/issues/5743>`_)
|
||||
- Implement manylinux2010 platform tag support. manylinux2010 is the successor
|
||||
to manylinux1. It allows carefully compiled binary wheels to be installed
|
||||
on compatible Linux platforms. (`#5008 <https://github.com/pypa/pip/issues/5008>`_)
|
||||
- Improve build isolation: handle ``.pth`` files, so namespace packages are correctly supported under Python 3.2 and earlier. (`#5656 <https://github.com/pypa/pip/issues/5656>`_)
|
||||
- Include the package name in a freeze warning if the package is not installed. (`#5943 <https://github.com/pypa/pip/issues/5943>`_)
|
||||
- Warn when dropping an ``--[extra-]index-url`` value that points to an existing local directory. (`#5827 <https://github.com/pypa/pip/issues/5827>`_)
|
||||
- Prefix pip's ``--log`` file lines with their timestamp. (`#6141 <https://github.com/pypa/pip/issues/6141>`_)
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Avoid creating excessively long temporary paths when uninstalling packages. (`#3055 <https://github.com/pypa/pip/issues/3055>`_)
|
||||
- Redact the password from the URL in various log messages. (`#4746 <https://github.com/pypa/pip/issues/4746>`_, `#6124 <https://github.com/pypa/pip/issues/6124>`_)
|
||||
- Avoid creating excessively long temporary paths when uninstalling packages. (`#3055 <https://github.com/pypa/pip/issues/3055>`_)
|
||||
- Avoid printing a stack trace when given an invalid requirement. (`#5147 <https://github.com/pypa/pip/issues/5147>`_)
|
||||
- Present 401 warning if username/password do not work for URL (`#4833 <https://github.com/pypa/pip/issues/4833>`_)
|
||||
- Handle ``requests.exceptions.RetryError`` raised in ``PackageFinder`` that was causing pip to fail silently when some indexes were unreachable. (`#5270 <https://github.com/pypa/pip/issues/5270>`_, `#5483 <https://github.com/pypa/pip/issues/5483>`_)
|
||||
- Handle a broken stdout pipe more gracefully (e.g. when running ``pip list | head``). (`#4170 <https://github.com/pypa/pip/issues/4170>`_)
|
||||
- Fix crash from setting ``PIP_NO_CACHE_DIR=yes``. (`#5385 <https://github.com/pypa/pip/issues/5385>`_)
|
||||
- Fix crash from unparseable requirements when checking installed packages. (`#5839 <https://github.com/pypa/pip/issues/5839>`_)
|
||||
- Fix content type detection if a directory named like an archive is used as a package source. (`#5838 <https://github.com/pypa/pip/issues/5838>`_)
|
||||
- Fix listing of outdated packages that are not dependencies of installed packages in ``pip list --outdated --not-required`` (`#5737 <https://github.com/pypa/pip/issues/5737>`_)
|
||||
- Fix sorting ``TypeError`` in ``move_wheel_files()`` when installing some packages. (`#5868 <https://github.com/pypa/pip/issues/5868>`_)
|
||||
- Fix support for invoking pip using ``python src/pip ...``. (`#5841 <https://github.com/pypa/pip/issues/5841>`_)
|
||||
- Greatly reduce memory usage when installing wheels containing large files. (`#5848 <https://github.com/pypa/pip/issues/5848>`_)
|
||||
- Editable non-VCS installs now freeze as editable. (`#5031 <https://github.com/pypa/pip/issues/5031>`_)
|
||||
- Editable Git installs without a remote now freeze as editable. (`#4759 <https://github.com/pypa/pip/issues/4759>`_)
|
||||
- Canonicalize sdist file names so they can be matched to a canonicalized package name passed to ``pip install``. (`#5870 <https://github.com/pypa/pip/issues/5870>`_)
|
||||
- Properly decode special characters in SVN URL credentials. (`#5968 <https://github.com/pypa/pip/issues/5968>`_)
|
||||
- Make ``PIP_NO_CACHE_DIR`` disable the cache also for truthy values like ``"true"``, ``"yes"``, ``"1"``, etc. (`#5735 <https://github.com/pypa/pip/issues/5735>`_)
|
||||
|
||||
Vendored Libraries
|
||||
------------------
|
||||
|
||||
- Include license text of vendored 3rd party libraries. (`#5213 <https://github.com/pypa/pip/issues/5213>`_)
|
||||
- Update certifi to 2018.11.29
|
||||
- Update colorama to 0.4.1
|
||||
- Update distlib to 0.2.8
|
||||
- Update idna to 2.8
|
||||
- Update packaging to 19.0
|
||||
- Update pep517 to 0.5.0
|
||||
- Update pkg_resources to 40.6.3 (via setuptools)
|
||||
- Update pyparsing to 2.3.1
|
||||
- Update pytoml to 0.1.20
|
||||
- Update requests to 2.21.0
|
||||
- Update six to 1.12.0
|
||||
- Update urllib3 to 1.24.1
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Include the Vendoring Policy in the documentation. (`#5958 <https://github.com/pypa/pip/issues/5958>`_)
|
||||
- Add instructions for running pip from source to Development documentation. (`#5949 <https://github.com/pypa/pip/issues/5949>`_)
|
||||
- Remove references to removed ``#egg=<name>-<version>`` functionality (`#5888 <https://github.com/pypa/pip/issues/5888>`_)
|
||||
- Fix omission of command name in HTML usage documentation (`#5984 <https://github.com/pypa/pip/issues/5984>`_)
|
||||
|
||||
|
||||
18.1 (2018-10-05)
|
||||
=================
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Include the package name in a freeze warning if the package is not installed.
|
|
@ -1 +0,0 @@
|
|||
Avoids creating excessively long temporary paths when uninstalling packages.
|
|
@ -1 +0,0 @@
|
|||
Redact the password from the URL in various log messages.
|
|
@ -1 +0,0 @@
|
|||
give 401 warning if username/password do not work for URL
|
|
@ -1,3 +0,0 @@
|
|||
Implement manylinux2010 platform tag support. manylinux2010 is the successor
|
||||
to manylinux1. It allows carefully compiled binary wheels to be installed
|
||||
on compatible Linux platforms.
|
|
@ -1 +0,0 @@
|
|||
Editable, non-VCS installs now freeze as editable.
|
|
@ -1 +0,0 @@
|
|||
Invalid requirement no longer causes stack trace to be printed.
|
|
@ -1 +0,0 @@
|
|||
Pip now includes license text of 3rd party libraries.
|
|
@ -1,2 +0,0 @@
|
|||
Handle `requests.exceptions.RetryError` raised in `PackageFinder` that was
|
||||
causing pip to fail silently when some indexes were unreachable.
|
|
@ -1 +0,0 @@
|
|||
Setting ``PIP_NO_CACHE_DIR=yes`` no longer causes pip to crash.
|
|
@ -1,2 +0,0 @@
|
|||
Handle `requests.exceptions.RetryError` raised in `PackageFinder` that was
|
||||
causing pip to fail silently when some indexes were unreachable.
|
|
@ -1 +0,0 @@
|
|||
- Improve PEP 518 build isolation: handle .pth files, so namespace packages are correctly supported under Python 3.2 and earlier.
|
|
@ -1,2 +0,0 @@
|
|||
Make ``PIP_NO_CACHE_DIR`` disable the cache also for truthy values like
|
||||
``"true"``, ``"yes"``, ``"1"``, etc.
|
|
@ -1 +0,0 @@
|
|||
Implement PEP 517 (allow projects to specify a build backend via pyproject.toml).
|
|
@ -1 +0,0 @@
|
|||
A warning message is emitted when dropping an ``--[extra-]index-url`` value that points to an existing local directory.
|
|
@ -1 +0,0 @@
|
|||
Fix content type detection if a directory named like an archive is used as a package source.
|
|
@ -1 +0,0 @@
|
|||
Fix crashes from unparseable requirements when checking installed packages.
|
|
@ -1 +0,0 @@
|
|||
Fix support for invoking pip using `python src/pip ...`.
|
|
@ -1 +0,0 @@
|
|||
Greatly reduce memory usage when installing wheels containing large files.
|
|
@ -1,2 +0,0 @@
|
|||
Remove the deprecated SVN editable detection based on dependency links
|
||||
during freeze.
|
|
@ -1 +0,0 @@
|
|||
Fix sorting `TypeError` in `move_wheel_files()` when installing some packages.
|
|
@ -1 +0,0 @@
|
|||
Canonicalize sdist file names so they can be matched to a canonicalized package name passed to ``pip install``.
|
|
@ -1 +0,0 @@
|
|||
Remove references to removed #egg=<name>-<version> functionality
|
|
@ -1 +0,0 @@
|
|||
Adds instructions for running pip from source to Development documentation.
|
|
@ -1 +0,0 @@
|
|||
Include the Vendoring Policy in the documentation.
|
|
@ -1,2 +0,0 @@
|
|||
|
||||
Adds hyperlinks to User IRC and Dev IRC in README.
|
|
@ -1 +0,0 @@
|
|||
Percent-decode special characters in SVN URL credentials.
|
|
@ -1 +0,0 @@
|
|||
Add command information in usage document for pip cmd
|
1
news/6165.bugfix
Normal file
1
news/6165.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Allow ``RECORD`` lines with more than three elements, and display a warning.
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1 +1 @@
|
|||
__version__ = "19.0.dev0"
|
||||
__version__ = "19.1.dev0"
|
||||
|
|
|
@ -189,8 +189,6 @@ class BuildEnvironment(object):
|
|||
args.extend(['--trusted-host', host])
|
||||
if finder.allow_all_prereleases:
|
||||
args.append('--pre')
|
||||
if finder.process_dependency_links:
|
||||
args.append('--process-dependency-links')
|
||||
args.append('--')
|
||||
args.extend(requirements)
|
||||
with open_spinner(message) as spinner:
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
"""Base Command class, and related routines"""
|
||||
from __future__ import absolute_import
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
import logging
|
||||
import logging.config
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.parser import (
|
||||
|
@ -26,8 +27,11 @@ from pip._internal.req.constructors import (
|
|||
install_req_from_editable, install_req_from_line,
|
||||
)
|
||||
from pip._internal.req.req_file import parse_requirements
|
||||
from pip._internal.utils.logging import setup_logging
|
||||
from pip._internal.utils.misc import get_prog, normalize_path
|
||||
from pip._internal.utils.deprecation import deprecated
|
||||
from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging
|
||||
from pip._internal.utils.misc import (
|
||||
get_prog, normalize_path, redact_password_from_url,
|
||||
)
|
||||
from pip._internal.utils.outdated import pip_version_check
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
|
@ -126,12 +130,30 @@ class Command(object):
|
|||
# Set verbosity so that it can be used elsewhere.
|
||||
self.verbosity = options.verbose - options.quiet
|
||||
|
||||
setup_logging(
|
||||
level_number = setup_logging(
|
||||
verbosity=self.verbosity,
|
||||
no_color=options.no_color,
|
||||
user_log_file=options.log,
|
||||
)
|
||||
|
||||
if sys.version_info[:2] == (3, 4):
|
||||
deprecated(
|
||||
"Python 3.4 support has been deprecated. pip 19.1 will be the "
|
||||
"last one supporting it. Please upgrade your Python as Python "
|
||||
"3.4 won't be maintained after March 2019 (cf PEP 429).",
|
||||
replacement=None,
|
||||
gone_in='19.2',
|
||||
)
|
||||
elif sys.version_info[:2] == (2, 7):
|
||||
deprecated(
|
||||
"Python 2.7 will reach the end of its life on January 1st, "
|
||||
"2020. Please upgrade your Python as Python 2.7 won't be "
|
||||
"maintained after that date. A future version of pip will "
|
||||
"drop support for Python 2.7.",
|
||||
replacement=None,
|
||||
gone_in=None,
|
||||
)
|
||||
|
||||
# TODO: Try to get these passing down from the command?
|
||||
# without resorting to os.environ to hold these.
|
||||
# This also affects isolated builds and it should.
|
||||
|
@ -170,6 +192,14 @@ class Command(object):
|
|||
logger.critical('ERROR: %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)
|
||||
if level_number <= logging.DEBUG:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
|
||||
return ERROR
|
||||
except KeyboardInterrupt:
|
||||
logger.critical('Operation cancelled by user')
|
||||
|
@ -287,7 +317,10 @@ class RequirementCommand(Command):
|
|||
"""
|
||||
index_urls = [options.index_url] + options.extra_index_urls
|
||||
if options.no_index:
|
||||
logger.debug('Ignoring indexes: %s', ','.join(index_urls))
|
||||
logger.debug(
|
||||
'Ignoring indexes: %s',
|
||||
','.join(redact_password_from_url(url) for url in index_urls),
|
||||
)
|
||||
index_urls = []
|
||||
|
||||
return PackageFinder(
|
||||
|
@ -296,7 +329,6 @@ class RequirementCommand(Command):
|
|||
index_urls=index_urls,
|
||||
trusted_hosts=options.trusted_hosts,
|
||||
allow_all_prereleases=options.pre,
|
||||
process_dependency_links=options.process_dependency_links,
|
||||
session=session,
|
||||
platform=platform,
|
||||
versions=python_versions,
|
||||
|
|
|
@ -9,6 +9,7 @@ pass on state. To be consistent, all options will follow this design.
|
|||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import textwrap
|
||||
import warnings
|
||||
from distutils.util import strtobool
|
||||
from functools import partial
|
||||
|
@ -28,6 +29,20 @@ if MYPY_CHECK_RUNNING:
|
|||
from pip._internal.cli.parser import ConfigOptionParser # noqa: F401
|
||||
|
||||
|
||||
def raise_option_error(parser, option, msg):
|
||||
"""
|
||||
Raise an option parsing error using parser.error().
|
||||
|
||||
Args:
|
||||
parser: an OptionParser instance.
|
||||
option: an Option instance.
|
||||
msg: the error text.
|
||||
"""
|
||||
msg = '{} error: {}'.format(option, msg)
|
||||
msg = textwrap.fill(' '.join(msg.split()))
|
||||
parser.error(msg)
|
||||
|
||||
|
||||
def make_option_group(group, parser):
|
||||
# type: (Dict[str, Any], ConfigOptionParser) -> OptionGroup
|
||||
"""
|
||||
|
@ -347,17 +362,6 @@ def trusted_host():
|
|||
)
|
||||
|
||||
|
||||
# Remove after 1.5
|
||||
process_dependency_links = partial(
|
||||
Option,
|
||||
"--process-dependency-links",
|
||||
dest="process_dependency_links",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Enable the processing of dependency links.",
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
def constraints():
|
||||
# type: () -> Option
|
||||
return Option(
|
||||
|
@ -551,7 +555,10 @@ def no_cache_dir_callback(option, opt, value, parser):
|
|||
# environment variable, like PIP_NO_CACHE_DIR=true.
|
||||
if value is not None:
|
||||
# Then parse the string value to get argument error-checking.
|
||||
strtobool(value)
|
||||
try:
|
||||
strtobool(value)
|
||||
except ValueError as exc:
|
||||
raise_option_error(parser, option=option, msg=str(exc))
|
||||
|
||||
# Originally, setting PIP_NO_CACHE_DIR to a value that strtobool()
|
||||
# converted to 0 (like "false" or "no") caused cache_dir to be disabled
|
||||
|
@ -612,6 +619,30 @@ no_build_isolation = partial(
|
|||
'if this option is used.'
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
def no_use_pep517_callback(option, opt, value, parser):
|
||||
"""
|
||||
Process a value provided for the --no-use-pep517 option.
|
||||
|
||||
This is an optparse.Option callback for the no_use_pep517 option.
|
||||
"""
|
||||
# Since --no-use-pep517 doesn't accept arguments, the value argument
|
||||
# will be None if --no-use-pep517 is passed via the command-line.
|
||||
# However, the value can be non-None if the option is triggered e.g.
|
||||
# by an environment variable, for example "PIP_NO_USE_PEP517=true".
|
||||
if value is not None:
|
||||
msg = """A value was passed for --no-use-pep517,
|
||||
probably using either the PIP_NO_USE_PEP517 environment variable
|
||||
or the "no-use-pep517" config file option. Use an appropriate value
|
||||
of the PIP_USE_PEP517 environment variable or the "use-pep517"
|
||||
config file option instead.
|
||||
"""
|
||||
raise_option_error(parser, option=option, msg=msg)
|
||||
|
||||
# Otherwise, --no-use-pep517 was passed via the command-line.
|
||||
parser.values.use_pep517 = False
|
||||
|
||||
|
||||
use_pep517 = partial(
|
||||
Option,
|
||||
'--use-pep517',
|
||||
|
@ -626,7 +657,8 @@ no_use_pep517 = partial(
|
|||
Option,
|
||||
'--no-use-pep517',
|
||||
dest='use_pep517',
|
||||
action='store_false',
|
||||
action='callback',
|
||||
callback=no_use_pep517_callback,
|
||||
default=None,
|
||||
help=SUPPRESS_HELP
|
||||
) # type: Any
|
||||
|
@ -773,6 +805,5 @@ index_group = {
|
|||
extra_index_url,
|
||||
no_index,
|
||||
find_links,
|
||||
process_dependency_links,
|
||||
]
|
||||
} # type: Dict[str, Any]
|
||||
|
|
|
@ -118,7 +118,6 @@ class ListCommand(Command):
|
|||
index_urls=index_urls,
|
||||
allow_all_prereleases=options.pre,
|
||||
trusted_hosts=options.trusted_hosts,
|
||||
process_dependency_links=options.process_dependency_links,
|
||||
session=session,
|
||||
)
|
||||
|
||||
|
@ -134,14 +133,18 @@ class ListCommand(Command):
|
|||
include_editables=options.include_editable,
|
||||
)
|
||||
|
||||
# get_not_required must be called firstly in order to find and
|
||||
# filter out all dependencies correctly. Otherwise a package
|
||||
# can't be identified as requirement because some parent packages
|
||||
# could be filtered out before.
|
||||
if options.not_required:
|
||||
packages = self.get_not_required(packages, options)
|
||||
|
||||
if options.outdated:
|
||||
packages = self.get_outdated(packages, options)
|
||||
elif options.uptodate:
|
||||
packages = self.get_uptodate(packages, options)
|
||||
|
||||
if options.not_required:
|
||||
packages = self.get_not_required(packages, options)
|
||||
|
||||
self.output_package_listing(packages, options)
|
||||
|
||||
def get_outdated(self, packages, options):
|
||||
|
@ -168,16 +171,8 @@ class ListCommand(Command):
|
|||
logger.debug('Ignoring indexes: %s', ','.join(index_urls))
|
||||
index_urls = []
|
||||
|
||||
dependency_links = []
|
||||
for dist in packages:
|
||||
if dist.has_metadata('dependency_links.txt'):
|
||||
dependency_links.extend(
|
||||
dist.get_metadata_lines('dependency_links.txt'),
|
||||
)
|
||||
|
||||
with self._build_session(options) as session:
|
||||
finder = self._build_package_finder(options, index_urls, session)
|
||||
finder.add_dependency_links(dependency_links)
|
||||
|
||||
for dist in packages:
|
||||
typ = 'unknown'
|
||||
|
|
|
@ -31,7 +31,6 @@ from pip._internal.models.index import PyPI
|
|||
from pip._internal.models.link import Link
|
||||
from pip._internal.pep425tags import get_supported
|
||||
from pip._internal.utils.compat import ipaddress
|
||||
from pip._internal.utils.deprecation import deprecated
|
||||
from pip._internal.utils.logging import indent_log
|
||||
from pip._internal.utils.misc import (
|
||||
ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, WHEEL_EXTENSION, normalize_path,
|
||||
|
@ -268,7 +267,6 @@ class PackageFinder(object):
|
|||
index_urls, # type: List[str]
|
||||
allow_all_prereleases=False, # type: bool
|
||||
trusted_hosts=None, # type: Optional[Iterable[str]]
|
||||
process_dependency_links=False, # type: bool
|
||||
session=None, # type: Optional[PipSession]
|
||||
format_control=None, # type: Optional[FormatControl]
|
||||
platform=None, # type: Optional[str]
|
||||
|
@ -315,7 +313,6 @@ class PackageFinder(object):
|
|||
self.find_links.append(link)
|
||||
|
||||
self.index_urls = index_urls
|
||||
self.dependency_links = [] # type: List[str]
|
||||
|
||||
# These are boring links that have already been logged somehow:
|
||||
self.logged_links = set() # type: Set[Link]
|
||||
|
@ -331,9 +328,6 @@ class PackageFinder(object):
|
|||
# Do we want to allow _all_ pre-releases?
|
||||
self.allow_all_prereleases = allow_all_prereleases
|
||||
|
||||
# Do we process dependency links?
|
||||
self.process_dependency_links = process_dependency_links
|
||||
|
||||
# The Session we'll use to make requests
|
||||
self.session = session
|
||||
|
||||
|
@ -375,22 +369,6 @@ class PackageFinder(object):
|
|||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
def add_dependency_links(self, links):
|
||||
# type: (Iterable[str]) -> None
|
||||
# FIXME: this shouldn't be global list this, it should only
|
||||
# apply to requirements of the package that specifies the
|
||||
# dependency_links value
|
||||
# FIXME: also, we should track comes_from (i.e., use Link)
|
||||
if self.process_dependency_links:
|
||||
deprecated(
|
||||
"Dependency Links processing has been deprecated and will be "
|
||||
"removed in a future release.",
|
||||
replacement="PEP 508 URL dependencies",
|
||||
gone_in="19.0",
|
||||
issue=4187,
|
||||
)
|
||||
self.dependency_links.extend(links)
|
||||
|
||||
@staticmethod
|
||||
def _sort_locations(locations, expand_dir=False):
|
||||
# type: (Sequence[str], bool) -> Tuple[List[str], List[str]]
|
||||
|
@ -587,7 +565,7 @@ class PackageFinder(object):
|
|||
# type: (str) -> List[Optional[InstallationCandidate]]
|
||||
"""Find all available InstallationCandidate for project_name
|
||||
|
||||
This checks index_urls, find_links and dependency_links.
|
||||
This checks index_urls and find_links.
|
||||
All versions found are returned as an InstallationCandidate list.
|
||||
|
||||
See _link_package_versions for details on which files are accepted
|
||||
|
@ -597,21 +575,18 @@ class PackageFinder(object):
|
|||
fl_file_loc, fl_url_loc = self._sort_locations(
|
||||
self.find_links, expand_dir=True,
|
||||
)
|
||||
dep_file_loc, dep_url_loc = self._sort_locations(self.dependency_links)
|
||||
|
||||
file_locations = (Link(url) for url in itertools.chain(
|
||||
index_file_loc, fl_file_loc, dep_file_loc,
|
||||
index_file_loc, fl_file_loc,
|
||||
))
|
||||
|
||||
# We trust every url that the user has given us whether it was given
|
||||
# via --index-url or --find-links
|
||||
# We explicitly do not trust links that came from dependency_links
|
||||
# via --index-url or --find-links.
|
||||
# We want to filter out any thing which does not have a secure origin.
|
||||
url_locations = [
|
||||
link for link in itertools.chain(
|
||||
(Link(url) for url in index_url_loc),
|
||||
(Link(url) for url in fl_url_loc),
|
||||
(Link(url) for url in dep_url_loc),
|
||||
)
|
||||
if self._validate_secure_origin(logger, link)
|
||||
]
|
||||
|
@ -639,17 +614,6 @@ class PackageFinder(object):
|
|||
self._package_versions(page.iter_links(), search)
|
||||
)
|
||||
|
||||
dependency_versions = self._package_versions(
|
||||
(Link(url) for url in self.dependency_links), search
|
||||
)
|
||||
if dependency_versions:
|
||||
logger.debug(
|
||||
'dependency_links found: %s',
|
||||
', '.join([
|
||||
version.location.url for version in dependency_versions
|
||||
])
|
||||
)
|
||||
|
||||
file_versions = self._package_versions(file_locations, search)
|
||||
if file_versions:
|
||||
file_versions.sort(reverse=True)
|
||||
|
@ -662,10 +626,7 @@ class PackageFinder(object):
|
|||
)
|
||||
|
||||
# This is an intentional priority ordering
|
||||
return (
|
||||
file_versions + find_links_versions + page_versions +
|
||||
dependency_versions
|
||||
)
|
||||
return file_versions + find_links_versions + page_versions
|
||||
|
||||
def find_requirement(self, req, upgrade):
|
||||
# type: (InstallRequirement, bool) -> Optional[Link]
|
||||
|
|
|
@ -120,9 +120,6 @@ def check_install_conflicts(to_install):
|
|||
)
|
||||
|
||||
|
||||
# NOTE from @pradyunsg
|
||||
# This required a minor update in dependency link handling logic over at
|
||||
# operations.prepare.IsSDist.dist() to get it working
|
||||
def _simulate_installation_of(to_install, package_set):
|
||||
# type: (List[InstallRequirement], PackageSet) -> Set[str]
|
||||
"""Computes the version of packages after installing to_install.
|
||||
|
@ -133,7 +130,7 @@ def _simulate_installation_of(to_install, package_set):
|
|||
|
||||
# Modify it as installing requirement_set would (assuming no errors)
|
||||
for inst_req in to_install:
|
||||
dist = make_abstract_dist(inst_req).dist(finder=None)
|
||||
dist = make_abstract_dist(inst_req).dist()
|
||||
name = canonicalize_name(dist.key)
|
||||
package_set[name] = PackageDetails(dist.version, dist.requires())
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ def get_requirement_info(dist):
|
|||
|
||||
location = os.path.normcase(os.path.abspath(dist.location))
|
||||
|
||||
from pip._internal.vcs import vcs
|
||||
from pip._internal.vcs import vcs, RemoteNotFoundError
|
||||
vc_type = vcs.get_backend_type(location)
|
||||
|
||||
if not vc_type:
|
||||
|
@ -182,12 +182,21 @@ def get_requirement_info(dist):
|
|||
location,
|
||||
)
|
||||
comments = [
|
||||
'# Editable, no version control detected ({})'.format(req)
|
||||
'# Editable install with no version control ({})'.format(req)
|
||||
]
|
||||
return (location, True, comments)
|
||||
|
||||
try:
|
||||
req = vc_type().get_src_requirement(location, dist.project_name)
|
||||
req = vc_type.get_src_requirement(location, dist.project_name)
|
||||
except RemoteNotFoundError:
|
||||
req = dist.as_requirement()
|
||||
comments = [
|
||||
'# Editable {} install with no remote ({})'.format(
|
||||
vc_type.__name__, req,
|
||||
)
|
||||
]
|
||||
return (location, True, comments)
|
||||
|
||||
except BadCommand:
|
||||
logger.warning(
|
||||
'cannot determine version of editable source in %s '
|
||||
|
|
|
@ -71,21 +71,21 @@ class DistAbstraction(object):
|
|||
# type: (InstallRequirement) -> None
|
||||
self.req = req # type: InstallRequirement
|
||||
|
||||
def dist(self, finder):
|
||||
# type: (PackageFinder) -> Any
|
||||
def dist(self):
|
||||
# type: () -> Any
|
||||
"""Return a setuptools Dist object."""
|
||||
raise NotImplementedError(self.dist)
|
||||
raise NotImplementedError
|
||||
|
||||
def prep_for_dist(self, finder, build_isolation):
|
||||
# type: (PackageFinder, bool) -> Any
|
||||
"""Ensure that we can get a Dist for this requirement."""
|
||||
raise NotImplementedError(self.dist)
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class IsWheel(DistAbstraction):
|
||||
|
||||
def dist(self, finder):
|
||||
# type: (PackageFinder) -> pkg_resources.Distribution
|
||||
def dist(self):
|
||||
# type: () -> pkg_resources.Distribution
|
||||
return list(pkg_resources.find_distributions(
|
||||
self.req.source_dir))[0]
|
||||
|
||||
|
@ -97,15 +97,8 @@ class IsWheel(DistAbstraction):
|
|||
|
||||
class IsSDist(DistAbstraction):
|
||||
|
||||
def dist(self, finder):
|
||||
# type: (PackageFinder) -> pkg_resources.Distribution
|
||||
dist = self.req.get_dist()
|
||||
# FIXME: shouldn't be globally added.
|
||||
if finder and dist.has_metadata('dependency_links.txt'):
|
||||
finder.add_dependency_links(
|
||||
dist.get_metadata_lines('dependency_links.txt')
|
||||
)
|
||||
return dist
|
||||
def dist(self):
|
||||
return self.req.get_dist()
|
||||
|
||||
def prep_for_dist(self, finder, build_isolation):
|
||||
# type: (PackageFinder, bool) -> None
|
||||
|
@ -168,8 +161,8 @@ class IsSDist(DistAbstraction):
|
|||
|
||||
class Installed(DistAbstraction):
|
||||
|
||||
def dist(self, finder):
|
||||
# type: (PackageFinder) -> pkg_resources.Distribution
|
||||
def dist(self):
|
||||
# type: () -> pkg_resources.Distribution
|
||||
return self.req.satisfied_by
|
||||
|
||||
def prep_for_dist(self, finder, build_isolation):
|
||||
|
|
|
@ -57,17 +57,20 @@ def load_pyproject_toml(
|
|||
build_system = None
|
||||
|
||||
# The following cases must use PEP 517
|
||||
# We check for use_pep517 equalling False because that
|
||||
# means the user explicitly requested --no-use-pep517
|
||||
# We check for use_pep517 being non-None and falsey because that means
|
||||
# the user explicitly requested --no-use-pep517. The value 0 as
|
||||
# opposed to False can occur when the value is provided via an
|
||||
# environment variable or config file option (due to the quirk of
|
||||
# strtobool() returning an integer in pip's configuration code).
|
||||
if has_pyproject and not has_setup:
|
||||
if use_pep517 is False:
|
||||
if use_pep517 is not None and not use_pep517:
|
||||
raise InstallationError(
|
||||
"Disabling PEP 517 processing is invalid: "
|
||||
"project does not have a setup.py"
|
||||
)
|
||||
use_pep517 = True
|
||||
elif build_system and "build-backend" in build_system:
|
||||
if use_pep517 is False:
|
||||
if use_pep517 is not None and not use_pep517:
|
||||
raise InstallationError(
|
||||
"Disabling PEP 517 processing is invalid: "
|
||||
"project specifies a build backend of {} "
|
||||
|
|
|
@ -55,7 +55,6 @@ SUPPORTED_OPTIONS = [
|
|||
cmdoptions.no_binary,
|
||||
cmdoptions.only_binary,
|
||||
cmdoptions.pre,
|
||||
cmdoptions.process_dependency_links,
|
||||
cmdoptions.trusted_host,
|
||||
cmdoptions.require_hashes,
|
||||
] # type: List[Callable[..., optparse.Option]]
|
||||
|
@ -251,8 +250,6 @@ def process_line(
|
|||
finder.find_links.append(value)
|
||||
if opts.pre:
|
||||
finder.allow_all_prereleases = True
|
||||
if opts.process_dependency_links:
|
||||
finder.process_dependency_links = True
|
||||
if opts.trusted_hosts:
|
||||
finder.secure_origins.extend(
|
||||
("*", host, "*") for host in opts.trusted_hosts)
|
||||
|
|
|
@ -294,7 +294,7 @@ class Resolver(object):
|
|||
abstract_dist = self._get_abstract_dist_for(req_to_install)
|
||||
|
||||
# Parse and return dependencies
|
||||
dist = abstract_dist.dist(self.finder)
|
||||
dist = abstract_dist.dist()
|
||||
try:
|
||||
check_dist_requires_python(dist)
|
||||
except UnsupportedPythonVersion as err:
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
import contextlib
|
||||
import errno
|
||||
import logging
|
||||
import logging.handlers
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.utils.compat import WINDOWS
|
||||
from pip._internal.utils.misc import ensure_dir
|
||||
|
@ -26,6 +30,48 @@ _log_state = threading.local()
|
|||
_log_state.indentation = 0
|
||||
|
||||
|
||||
class BrokenStdoutLoggingError(Exception):
|
||||
"""
|
||||
Raised if BrokenPipeError occurs for the stdout stream while logging.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
# BrokenPipeError does not exist in Python 2 and, in addition, manifests
|
||||
# differently in Windows and non-Windows.
|
||||
if WINDOWS:
|
||||
# In Windows, a broken pipe can show up as EINVAL rather than EPIPE:
|
||||
# https://bugs.python.org/issue19612
|
||||
# https://bugs.python.org/issue30418
|
||||
if PY2:
|
||||
def _is_broken_pipe_error(exc_class, exc):
|
||||
"""See the docstring for non-Windows Python 3 below."""
|
||||
return (exc_class is IOError and
|
||||
exc.errno in (errno.EINVAL, errno.EPIPE))
|
||||
else:
|
||||
# In Windows, a broken pipe IOError became OSError in Python 3.
|
||||
def _is_broken_pipe_error(exc_class, exc):
|
||||
"""See the docstring for non-Windows Python 3 below."""
|
||||
return ((exc_class is BrokenPipeError) or # noqa: F821
|
||||
(exc_class is OSError and
|
||||
exc.errno in (errno.EINVAL, errno.EPIPE)))
|
||||
elif PY2:
|
||||
def _is_broken_pipe_error(exc_class, exc):
|
||||
"""See the docstring for non-Windows Python 3 below."""
|
||||
return (exc_class is IOError and exc.errno == errno.EPIPE)
|
||||
else:
|
||||
# Then we are in the non-Windows Python 3 case.
|
||||
def _is_broken_pipe_error(exc_class, exc):
|
||||
"""
|
||||
Return whether an exception is a broken pipe error.
|
||||
|
||||
Args:
|
||||
exc_class: an exception class.
|
||||
exc: an exception instance.
|
||||
"""
|
||||
return (exc_class is BrokenPipeError) # noqa: F821
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def indent_log(num=2):
|
||||
"""
|
||||
|
@ -44,15 +90,28 @@ def get_indentation():
|
|||
|
||||
|
||||
class IndentingFormatter(logging.Formatter):
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
A logging.Formatter obeying containing indent_log contexts.
|
||||
|
||||
:param add_timestamp: A bool indicating output lines should be prefixed
|
||||
with their record's timestamp.
|
||||
"""
|
||||
self.add_timestamp = kwargs.pop("add_timestamp", False)
|
||||
super(IndentingFormatter, self).__init__(*args, **kwargs)
|
||||
|
||||
def format(self, record):
|
||||
"""
|
||||
Calls the standard formatter, but will indent all of the log messages
|
||||
by our current indentation level.
|
||||
"""
|
||||
formatted = logging.Formatter.format(self, record)
|
||||
formatted = super(IndentingFormatter, self).format(record)
|
||||
prefix = ''
|
||||
if self.add_timestamp:
|
||||
prefix = self.formatTime(record, "%Y-%m-%dT%H:%M:%S ")
|
||||
prefix += " " * get_indentation()
|
||||
formatted = "".join([
|
||||
(" " * get_indentation()) + line
|
||||
prefix + line
|
||||
for line in formatted.splitlines(True)
|
||||
])
|
||||
return formatted
|
||||
|
@ -83,6 +142,16 @@ class ColorizedStreamHandler(logging.StreamHandler):
|
|||
if WINDOWS and colorama:
|
||||
self.stream = colorama.AnsiToWin32(self.stream)
|
||||
|
||||
def _using_stdout(self):
|
||||
"""
|
||||
Return whether the handler is using sys.stdout.
|
||||
"""
|
||||
if WINDOWS and colorama:
|
||||
# Then self.stream is an AnsiToWin32 object.
|
||||
return self.stream.wrapped is sys.stdout
|
||||
|
||||
return self.stream is sys.stdout
|
||||
|
||||
def should_color(self):
|
||||
# Don't colorize things if we do not have colorama or if told not to
|
||||
if not colorama or self._no_color:
|
||||
|
@ -115,6 +184,19 @@ class ColorizedStreamHandler(logging.StreamHandler):
|
|||
|
||||
return msg
|
||||
|
||||
# The logging module says handleError() can be customized.
|
||||
def handleError(self, record):
|
||||
exc_class, exc = sys.exc_info()[:2]
|
||||
# If a broken pipe occurred while calling write() or flush() on the
|
||||
# stdout stream in logging's Handler.emit(), then raise our special
|
||||
# exception so we can handle it in main() instead of logging the
|
||||
# broken pipe error and continuing.
|
||||
if (exc_class and self._using_stdout() and
|
||||
_is_broken_pipe_error(exc_class, exc)):
|
||||
raise BrokenStdoutLoggingError()
|
||||
|
||||
return super(ColorizedStreamHandler, self).handleError(record)
|
||||
|
||||
|
||||
class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler):
|
||||
|
||||
|
@ -134,6 +216,8 @@ class MaxLevelFilter(logging.Filter):
|
|||
|
||||
def setup_logging(verbosity, no_color, user_log_file):
|
||||
"""Configures and sets up all of the logging
|
||||
|
||||
Returns the requested logging level, as its integer value.
|
||||
"""
|
||||
|
||||
# Determine the level to be logging at.
|
||||
|
@ -148,6 +232,8 @@ def setup_logging(verbosity, no_color, user_log_file):
|
|||
else:
|
||||
level = "INFO"
|
||||
|
||||
level_number = getattr(logging, level)
|
||||
|
||||
# The "root" logger should match the "console" level *unless* we also need
|
||||
# to log to a user log file.
|
||||
include_user_log = user_log_file is not None
|
||||
|
@ -186,6 +272,11 @@ def setup_logging(verbosity, no_color, user_log_file):
|
|||
"()": IndentingFormatter,
|
||||
"format": "%(message)s",
|
||||
},
|
||||
"indent_with_timestamp": {
|
||||
"()": IndentingFormatter,
|
||||
"format": "%(message)s",
|
||||
"add_timestamp": True,
|
||||
},
|
||||
},
|
||||
"handlers": {
|
||||
"console": {
|
||||
|
@ -208,7 +299,7 @@ def setup_logging(verbosity, no_color, user_log_file):
|
|||
"class": handler_classes["file"],
|
||||
"filename": additional_log_file,
|
||||
"delay": True,
|
||||
"formatter": "indent",
|
||||
"formatter": "indent_with_timestamp",
|
||||
},
|
||||
},
|
||||
"root": {
|
||||
|
@ -223,3 +314,5 @@ def setup_logging(verbosity, no_color, user_log_file):
|
|||
}
|
||||
},
|
||||
})
|
||||
|
||||
return level_number
|
||||
|
|
|
@ -653,6 +653,7 @@ def call_subprocess(
|
|||
show_stdout=True, # type: bool
|
||||
cwd=None, # type: Optional[str]
|
||||
on_returncode='raise', # type: str
|
||||
extra_ok_returncodes=None, # type: Optional[Iterable[int]]
|
||||
command_desc=None, # type: Optional[str]
|
||||
extra_environ=None, # type: Optional[Mapping[str, Any]]
|
||||
unset_environ=None, # type: Optional[Iterable[str]]
|
||||
|
@ -661,9 +662,13 @@ def call_subprocess(
|
|||
# type: (...) -> Optional[Text]
|
||||
"""
|
||||
Args:
|
||||
extra_ok_returncodes: an iterable of integer return codes that are
|
||||
acceptable, in addition to 0. Defaults to None, which means [].
|
||||
unset_environ: an iterable of environment variable names to unset
|
||||
prior to calling subprocess.Popen().
|
||||
"""
|
||||
if extra_ok_returncodes is None:
|
||||
extra_ok_returncodes = []
|
||||
if unset_environ is None:
|
||||
unset_environ = []
|
||||
# This function's handling of subprocess output is confusing and I
|
||||
|
@ -740,7 +745,7 @@ def call_subprocess(
|
|||
spinner.finish("error")
|
||||
else:
|
||||
spinner.finish("done")
|
||||
if proc.returncode:
|
||||
if proc.returncode and proc.returncode not in extra_ok_returncodes:
|
||||
if on_returncode == 'raise':
|
||||
if (logger.getEffectiveLevel() > std_logging.DEBUG and
|
||||
not show_stdout):
|
||||
|
@ -859,6 +864,13 @@ def captured_stdout():
|
|||
return captured_output('stdout')
|
||||
|
||||
|
||||
def captured_stderr():
|
||||
"""
|
||||
See captured_stdout().
|
||||
"""
|
||||
return captured_output('stderr')
|
||||
|
||||
|
||||
class cached_property(object):
|
||||
"""A property that is only computed once per instance and then replaces
|
||||
itself with an ordinary attribute. Deleting the attribute resets the
|
||||
|
|
|
@ -127,7 +127,6 @@ def pip_version_check(session, options):
|
|||
index_urls=[options.index_url] + options.extra_index_urls,
|
||||
allow_all_prereleases=False, # Explicitly set to False
|
||||
trusted_hosts=options.trusted_hosts,
|
||||
process_dependency_links=options.process_dependency_links,
|
||||
session=session,
|
||||
)
|
||||
all_candidates = finder.find_all_candidates("pip")
|
||||
|
|
|
@ -17,7 +17,7 @@ from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
|||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import ( # noqa: F401
|
||||
Dict, Optional, Tuple, List, Type, Any, Mapping, Text
|
||||
Any, Dict, Iterable, List, Mapping, Optional, Text, Tuple, Type
|
||||
)
|
||||
from pip._internal.utils.ui import SpinnerInterface # noqa: F401
|
||||
|
||||
|
@ -29,6 +29,10 @@ __all__ = ['vcs']
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RemoteNotFoundError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class RevOptions(object):
|
||||
|
||||
"""
|
||||
|
@ -206,7 +210,8 @@ class VersionControl(object):
|
|||
"""
|
||||
return RevOptions(self, rev, extra_args=extra_args)
|
||||
|
||||
def _is_local_repository(self, repo):
|
||||
@classmethod
|
||||
def _is_local_repository(cls, repo):
|
||||
# type: (str) -> bool
|
||||
"""
|
||||
posix absolute paths start with os.path.sep,
|
||||
|
@ -440,7 +445,8 @@ class VersionControl(object):
|
|||
rmtree(location)
|
||||
self.obtain(location)
|
||||
|
||||
def get_src_requirement(self, location, project_name):
|
||||
@classmethod
|
||||
def get_src_requirement(cls, location, project_name):
|
||||
"""
|
||||
Return a string representing the requirement needed to
|
||||
redownload the files currently present in location, something
|
||||
|
@ -449,24 +455,31 @@ class VersionControl(object):
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_remote_url(self, location):
|
||||
@classmethod
|
||||
def get_remote_url(cls, location):
|
||||
"""
|
||||
Return the url used at location
|
||||
|
||||
Raises RemoteNotFoundError if the repository does not have a remote
|
||||
url configured.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_revision(self, location):
|
||||
@classmethod
|
||||
def get_revision(cls, location):
|
||||
"""
|
||||
Return the current commit id of the files at the given location.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def run_command(
|
||||
self,
|
||||
cls,
|
||||
cmd, # type: List[str]
|
||||
show_stdout=True, # type: bool
|
||||
cwd=None, # type: Optional[str]
|
||||
on_returncode='raise', # type: str
|
||||
extra_ok_returncodes=None, # type: Optional[Iterable[int]]
|
||||
command_desc=None, # type: Optional[str]
|
||||
extra_environ=None, # type: Optional[Mapping[str, Any]]
|
||||
spinner=None # type: Optional[SpinnerInterface]
|
||||
|
@ -477,12 +490,14 @@ class VersionControl(object):
|
|||
This is simply a wrapper around call_subprocess that adds the VCS
|
||||
command name, and checks that the VCS is available
|
||||
"""
|
||||
cmd = [self.name] + cmd
|
||||
cmd = [cls.name] + cmd
|
||||
try:
|
||||
return call_subprocess(cmd, show_stdout, cwd,
|
||||
on_returncode,
|
||||
command_desc, extra_environ,
|
||||
unset_environ=self.unset_environ,
|
||||
on_returncode=on_returncode,
|
||||
extra_ok_returncodes=extra_ok_returncodes,
|
||||
command_desc=command_desc,
|
||||
extra_environ=extra_environ,
|
||||
unset_environ=cls.unset_environ,
|
||||
spinner=spinner)
|
||||
except OSError as e:
|
||||
# errno.ENOENT = no such file or directory
|
||||
|
@ -491,7 +506,7 @@ class VersionControl(object):
|
|||
raise BadCommand(
|
||||
'Cannot find command %r - do you have '
|
||||
'%r installed and in your '
|
||||
'PATH?' % (self.name, self.name))
|
||||
'PATH?' % (cls.name, cls.name))
|
||||
else:
|
||||
raise # re-raise exception if a different error occurred
|
||||
|
||||
|
|
|
@ -75,32 +75,35 @@ class Bazaar(VersionControl):
|
|||
url = 'bzr+' + url
|
||||
return url, rev, user_pass
|
||||
|
||||
def get_remote_url(self, location):
|
||||
urls = self.run_command(['info'], show_stdout=False, cwd=location)
|
||||
@classmethod
|
||||
def get_remote_url(cls, location):
|
||||
urls = cls.run_command(['info'], show_stdout=False, cwd=location)
|
||||
for line in urls.splitlines():
|
||||
line = line.strip()
|
||||
for x in ('checkout of branch: ',
|
||||
'parent branch: '):
|
||||
if line.startswith(x):
|
||||
repo = line.split(x)[1]
|
||||
if self._is_local_repository(repo):
|
||||
if cls._is_local_repository(repo):
|
||||
return path_to_url(repo)
|
||||
return repo
|
||||
return None
|
||||
|
||||
def get_revision(self, location):
|
||||
revision = self.run_command(
|
||||
@classmethod
|
||||
def get_revision(cls, location):
|
||||
revision = cls.run_command(
|
||||
['revno'], show_stdout=False, cwd=location,
|
||||
)
|
||||
return revision.splitlines()[-1]
|
||||
|
||||
def get_src_requirement(self, location, project_name):
|
||||
repo = self.get_remote_url(location)
|
||||
@classmethod
|
||||
def get_src_requirement(cls, location, project_name):
|
||||
repo = cls.get_remote_url(location)
|
||||
if not repo:
|
||||
return None
|
||||
if not repo.lower().startswith('bzr:'):
|
||||
repo = 'bzr+' + repo
|
||||
current_rev = self.get_revision(location)
|
||||
current_rev = cls.get_revision(location)
|
||||
return make_vcs_requirement_url(repo, current_rev, project_name)
|
||||
|
||||
def is_commit_id_equal(self, dest, name):
|
||||
|
|
|
@ -14,7 +14,7 @@ from pip._internal.utils.misc import (
|
|||
display_path, make_vcs_requirement_url, redact_password_from_url,
|
||||
)
|
||||
from pip._internal.utils.temp_dir import TempDirectory
|
||||
from pip._internal.vcs import VersionControl, vcs
|
||||
from pip._internal.vcs import RemoteNotFoundError, VersionControl, vcs
|
||||
|
||||
urlsplit = urllib_parse.urlsplit
|
||||
urlunsplit = urllib_parse.urlunsplit
|
||||
|
@ -79,19 +79,25 @@ class Git(VersionControl):
|
|||
version = '.'.join(version.split('.')[:3])
|
||||
return parse_version(version)
|
||||
|
||||
def get_branch(self, location):
|
||||
def get_current_branch(self, location):
|
||||
"""
|
||||
Return the current branch, or None if HEAD isn't at a branch
|
||||
(e.g. detached HEAD).
|
||||
"""
|
||||
args = ['rev-parse', '--abbrev-ref', 'HEAD']
|
||||
output = self.run_command(args, show_stdout=False, cwd=location)
|
||||
branch = output.strip()
|
||||
# git-symbolic-ref exits with empty stdout if "HEAD" is a detached
|
||||
# HEAD rather than a symbolic ref. In addition, the -q causes the
|
||||
# command to exit with status code 1 instead of 128 in this case
|
||||
# and to suppress the message to stderr.
|
||||
args = ['symbolic-ref', '-q', 'HEAD']
|
||||
output = self.run_command(
|
||||
args, extra_ok_returncodes=(1, ), show_stdout=False, cwd=location,
|
||||
)
|
||||
ref = output.strip()
|
||||
|
||||
if branch == 'HEAD':
|
||||
return None
|
||||
if ref.startswith('refs/heads/'):
|
||||
return ref[len('refs/heads/'):]
|
||||
|
||||
return branch
|
||||
return None
|
||||
|
||||
def export(self, location):
|
||||
"""Export the Git repository at the url to the destination location"""
|
||||
|
@ -210,7 +216,7 @@ class Git(VersionControl):
|
|||
if not self.is_commit_id_equal(dest, rev_options.rev):
|
||||
cmd_args = ['checkout', '-q'] + rev_options.to_args()
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
elif self.get_branch(dest) != branch_name:
|
||||
elif self.get_current_branch(dest) != branch_name:
|
||||
# Then a specific branch was requested, and that branch
|
||||
# is not yet checked out.
|
||||
track_branch = 'origin/{}'.format(branch_name)
|
||||
|
@ -243,14 +249,26 @@ class Git(VersionControl):
|
|||
#: update submodules
|
||||
self.update_submodules(dest)
|
||||
|
||||
def get_remote_url(self, location):
|
||||
"""Return URL of the first remote encountered."""
|
||||
remotes = self.run_command(
|
||||
@classmethod
|
||||
def get_remote_url(cls, location):
|
||||
"""
|
||||
Return URL of the first remote encountered.
|
||||
|
||||
Raises RemoteNotFoundError if the repository does not have a remote
|
||||
url configured.
|
||||
"""
|
||||
# We need to pass 1 for extra_ok_returncodes since the command
|
||||
# exits with return code 1 if there are no matching lines.
|
||||
stdout = cls.run_command(
|
||||
['config', '--get-regexp', r'remote\..*\.url'],
|
||||
show_stdout=False, cwd=location,
|
||||
extra_ok_returncodes=(1, ), show_stdout=False, cwd=location,
|
||||
)
|
||||
remotes = remotes.splitlines()
|
||||
found_remote = remotes[0]
|
||||
remotes = stdout.splitlines()
|
||||
try:
|
||||
found_remote = remotes[0]
|
||||
except IndexError:
|
||||
raise RemoteNotFoundError
|
||||
|
||||
for remote in remotes:
|
||||
if remote.startswith('remote.origin.url '):
|
||||
found_remote = remote
|
||||
|
@ -258,19 +276,21 @@ class Git(VersionControl):
|
|||
url = found_remote.split(' ')[1]
|
||||
return url.strip()
|
||||
|
||||
def get_revision(self, location, rev=None):
|
||||
@classmethod
|
||||
def get_revision(cls, location, rev=None):
|
||||
if rev is None:
|
||||
rev = 'HEAD'
|
||||
current_rev = self.run_command(
|
||||
current_rev = cls.run_command(
|
||||
['rev-parse', rev], show_stdout=False, cwd=location,
|
||||
)
|
||||
return current_rev.strip()
|
||||
|
||||
def _get_subdirectory(self, location):
|
||||
@classmethod
|
||||
def _get_subdirectory(cls, location):
|
||||
"""Return the relative path of setup.py to the git repo root."""
|
||||
# find the repo root
|
||||
git_dir = self.run_command(['rev-parse', '--git-dir'],
|
||||
show_stdout=False, cwd=location).strip()
|
||||
git_dir = cls.run_command(['rev-parse', '--git-dir'],
|
||||
show_stdout=False, cwd=location).strip()
|
||||
if not os.path.isabs(git_dir):
|
||||
git_dir = os.path.join(location, git_dir)
|
||||
root_dir = os.path.join(git_dir, '..')
|
||||
|
@ -293,12 +313,13 @@ class Git(VersionControl):
|
|||
return None
|
||||
return os.path.relpath(location, root_dir)
|
||||
|
||||
def get_src_requirement(self, location, project_name):
|
||||
repo = self.get_remote_url(location)
|
||||
@classmethod
|
||||
def get_src_requirement(cls, location, project_name):
|
||||
repo = cls.get_remote_url(location)
|
||||
if not repo.lower().startswith('git:'):
|
||||
repo = 'git+' + repo
|
||||
current_rev = self.get_revision(location)
|
||||
subdir = self._get_subdirectory(location)
|
||||
current_rev = cls.get_revision(location)
|
||||
subdir = cls._get_subdirectory(location)
|
||||
req = make_vcs_requirement_url(repo, current_rev, project_name,
|
||||
subdir=subdir)
|
||||
|
||||
|
@ -334,10 +355,10 @@ class Git(VersionControl):
|
|||
if super(Git, cls).controls_location(location):
|
||||
return True
|
||||
try:
|
||||
r = cls().run_command(['rev-parse'],
|
||||
cwd=location,
|
||||
show_stdout=False,
|
||||
on_returncode='ignore')
|
||||
r = cls.run_command(['rev-parse'],
|
||||
cwd=location,
|
||||
show_stdout=False,
|
||||
on_returncode='ignore')
|
||||
return not r
|
||||
except BadCommand:
|
||||
logger.debug("could not determine if %s is under git control "
|
||||
|
|
|
@ -64,31 +64,35 @@ class Mercurial(VersionControl):
|
|||
cmd_args = ['update', '-q'] + rev_options.to_args()
|
||||
self.run_command(cmd_args, cwd=dest)
|
||||
|
||||
def get_remote_url(self, location):
|
||||
url = self.run_command(
|
||||
@classmethod
|
||||
def get_remote_url(cls, location):
|
||||
url = cls.run_command(
|
||||
['showconfig', 'paths.default'],
|
||||
show_stdout=False, cwd=location).strip()
|
||||
if self._is_local_repository(url):
|
||||
if cls._is_local_repository(url):
|
||||
url = path_to_url(url)
|
||||
return url.strip()
|
||||
|
||||
def get_revision(self, location):
|
||||
current_revision = self.run_command(
|
||||
@classmethod
|
||||
def get_revision(cls, location):
|
||||
current_revision = cls.run_command(
|
||||
['parents', '--template={rev}'],
|
||||
show_stdout=False, cwd=location).strip()
|
||||
return current_revision
|
||||
|
||||
def get_revision_hash(self, location):
|
||||
current_rev_hash = self.run_command(
|
||||
@classmethod
|
||||
def get_revision_hash(cls, location):
|
||||
current_rev_hash = cls.run_command(
|
||||
['parents', '--template={node}'],
|
||||
show_stdout=False, cwd=location).strip()
|
||||
return current_rev_hash
|
||||
|
||||
def get_src_requirement(self, location, project_name):
|
||||
repo = self.get_remote_url(location)
|
||||
@classmethod
|
||||
def get_src_requirement(cls, location, project_name):
|
||||
repo = cls.get_remote_url(location)
|
||||
if not repo.lower().startswith('hg:'):
|
||||
repo = 'hg+' + repo
|
||||
current_rev_hash = self.get_revision_hash(location)
|
||||
current_rev_hash = cls.get_revision_hash(location)
|
||||
return make_vcs_requirement_url(repo, current_rev_hash, project_name)
|
||||
|
||||
def is_commit_id_equal(self, dest, name):
|
||||
|
|
|
@ -4,7 +4,6 @@ import logging
|
|||
import os
|
||||
import re
|
||||
|
||||
from pip._internal.models.link import Link
|
||||
from pip._internal.utils.logging import indent_log
|
||||
from pip._internal.utils.misc import (
|
||||
display_path, make_vcs_requirement_url, rmtree, split_auth_from_netloc,
|
||||
|
@ -61,21 +60,8 @@ class Subversion(VersionControl):
|
|||
cmd_args = ['update'] + rev_options.to_args() + [dest]
|
||||
self.run_command(cmd_args)
|
||||
|
||||
def get_location(self, dist, dependency_links):
|
||||
for url in dependency_links:
|
||||
egg_fragment = Link(url).egg_fragment
|
||||
if not egg_fragment:
|
||||
continue
|
||||
if '-' in egg_fragment:
|
||||
# FIXME: will this work when a package has - in the name?
|
||||
key = '-'.join(egg_fragment.split('-')[:-1]).lower()
|
||||
else:
|
||||
key = egg_fragment
|
||||
if key == dist.key:
|
||||
return url.split('#', 1)[0]
|
||||
return None
|
||||
|
||||
def get_revision(self, location):
|
||||
@classmethod
|
||||
def get_revision(cls, location):
|
||||
"""
|
||||
Return the maximum revision for all files under a given location
|
||||
"""
|
||||
|
@ -83,16 +69,16 @@ class Subversion(VersionControl):
|
|||
revision = 0
|
||||
|
||||
for base, dirs, files in os.walk(location):
|
||||
if self.dirname not in dirs:
|
||||
if cls.dirname not in dirs:
|
||||
dirs[:] = []
|
||||
continue # no sense walking uncontrolled subdirs
|
||||
dirs.remove(self.dirname)
|
||||
entries_fn = os.path.join(base, self.dirname, 'entries')
|
||||
dirs.remove(cls.dirname)
|
||||
entries_fn = os.path.join(base, cls.dirname, 'entries')
|
||||
if not os.path.exists(entries_fn):
|
||||
# FIXME: should we warn?
|
||||
continue
|
||||
|
||||
dirurl, localrev = self._get_svn_url_rev(base)
|
||||
dirurl, localrev = cls._get_svn_url_rev(base)
|
||||
|
||||
if base == location:
|
||||
base = dirurl + '/' # save the root url
|
||||
|
@ -131,7 +117,8 @@ class Subversion(VersionControl):
|
|||
|
||||
return extra_args
|
||||
|
||||
def get_remote_url(self, location):
|
||||
@classmethod
|
||||
def get_remote_url(cls, location):
|
||||
# In cases where the source is in a subdirectory, not alongside
|
||||
# setup.py we have to look up in the location until we find a real
|
||||
# setup.py
|
||||
|
@ -149,12 +136,13 @@ class Subversion(VersionControl):
|
|||
)
|
||||
return None
|
||||
|
||||
return self._get_svn_url_rev(location)[0]
|
||||
return cls._get_svn_url_rev(location)[0]
|
||||
|
||||
def _get_svn_url_rev(self, location):
|
||||
@classmethod
|
||||
def _get_svn_url_rev(cls, location):
|
||||
from pip._internal.exceptions import InstallationError
|
||||
|
||||
entries_path = os.path.join(location, self.dirname, 'entries')
|
||||
entries_path = os.path.join(location, cls.dirname, 'entries')
|
||||
if os.path.exists(entries_path):
|
||||
with open(entries_path) as f:
|
||||
data = f.read()
|
||||
|
@ -177,7 +165,7 @@ class Subversion(VersionControl):
|
|||
else:
|
||||
try:
|
||||
# subversion >= 1.7
|
||||
xml = self.run_command(
|
||||
xml = cls.run_command(
|
||||
['info', '--xml', location],
|
||||
show_stdout=False,
|
||||
)
|
||||
|
@ -195,12 +183,13 @@ class Subversion(VersionControl):
|
|||
|
||||
return url, rev
|
||||
|
||||
def get_src_requirement(self, location, project_name):
|
||||
repo = self.get_remote_url(location)
|
||||
@classmethod
|
||||
def get_src_requirement(cls, location, project_name):
|
||||
repo = cls.get_remote_url(location)
|
||||
if repo is None:
|
||||
return None
|
||||
repo = 'svn+' + repo
|
||||
rev = self.get_revision(location)
|
||||
rev = cls.get_revision(location)
|
||||
return make_vcs_requirement_url(repo, rev, project_name)
|
||||
|
||||
def is_commit_id_equal(self, dest, name):
|
||||
|
|
|
@ -55,7 +55,7 @@ if MYPY_CHECK_RUNNING:
|
|||
from pip._internal.cache import WheelCache # noqa: F401
|
||||
from pip._internal.pep425tags import Pep425Tag # noqa: F401
|
||||
|
||||
InstalledCSVRow = Tuple[str, Union[str, Text], str]
|
||||
InstalledCSVRow = Tuple[str, ...]
|
||||
|
||||
|
||||
VERSION_COMPATIBLE = (1, 0)
|
||||
|
@ -64,6 +64,10 @@ VERSION_COMPATIBLE = (1, 0)
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def normpath(src, p):
|
||||
return os.path.relpath(src, p).replace(os.path.sep, '/')
|
||||
|
||||
|
||||
def rehash(path, blocksize=1 << 20):
|
||||
# type: (str, int) -> Tuple[str, str]
|
||||
"""Return (hash, length) for path using hashlib.sha256()"""
|
||||
|
@ -255,6 +259,35 @@ def sorted_outrows(outrows):
|
|||
return sorted(outrows, key=lambda row: tuple(str(x) for x in row))
|
||||
|
||||
|
||||
def get_csv_rows_for_installed(
|
||||
old_csv_rows, # type: Iterable[List[str]]
|
||||
installed, # type: Dict[str, str]
|
||||
changed, # type: set
|
||||
generated, # type: List[str]
|
||||
lib_dir, # type: str
|
||||
):
|
||||
# type: (...) -> List[InstalledCSVRow]
|
||||
installed_rows = [] # type: List[InstalledCSVRow]
|
||||
for row in old_csv_rows:
|
||||
if len(row) > 3:
|
||||
logger.warning(
|
||||
'RECORD line has more than three elements: {}'.format(row)
|
||||
)
|
||||
fpath = row[0]
|
||||
fpath = installed.pop(fpath, fpath)
|
||||
if fpath in changed:
|
||||
digest, length = rehash(fpath)
|
||||
row[1] = digest
|
||||
row[2] = length
|
||||
installed_rows.append(tuple(row))
|
||||
for f in generated:
|
||||
digest, length = rehash(f)
|
||||
installed_rows.append((normpath(f, lib_dir), digest, str(length)))
|
||||
for f in installed:
|
||||
installed_rows.append((installed[f], '', ''))
|
||||
return installed_rows
|
||||
|
||||
|
||||
def move_wheel_files(
|
||||
name, # type: str
|
||||
req, # type: Requirement
|
||||
|
@ -305,9 +338,6 @@ def move_wheel_files(
|
|||
compileall.compile_dir(source, force=True, quiet=True)
|
||||
logger.debug(stdout.getvalue())
|
||||
|
||||
def normpath(src, p):
|
||||
return os.path.relpath(src, p).replace(os.path.sep, '/')
|
||||
|
||||
def record_installed(srcfile, destfile, modified=False):
|
||||
"""Map archive RECORD paths to installation RECORD paths."""
|
||||
oldpath = normpath(srcfile, wheeldir)
|
||||
|
@ -559,28 +589,16 @@ if __name__ == '__main__':
|
|||
shutil.move(temp_installer, installer)
|
||||
generated.append(installer)
|
||||
|
||||
def get_csv_rows_for_installed(old_csv_rows):
|
||||
# type: (Iterable[List[str]]) -> List[InstalledCSVRow]
|
||||
installed_rows = [] # type: List[InstalledCSVRow]
|
||||
for fpath, digest, length in old_csv_rows:
|
||||
fpath = installed.pop(fpath, fpath)
|
||||
if fpath in changed:
|
||||
digest, length = rehash(fpath)
|
||||
installed_rows.append((fpath, digest, str(length)))
|
||||
for f in generated:
|
||||
digest, length = rehash(f)
|
||||
installed_rows.append((normpath(f, lib_dir), digest, str(length)))
|
||||
for f in installed:
|
||||
installed_rows.append((installed[f], '', ''))
|
||||
return installed_rows
|
||||
|
||||
# Record details of all files installed
|
||||
record = os.path.join(info_dir[0], 'RECORD')
|
||||
temp_record = os.path.join(info_dir[0], 'RECORD.pip')
|
||||
with open_for_csv(record, 'r') as record_in:
|
||||
with open_for_csv(temp_record, 'w+') as record_out:
|
||||
reader = csv.reader(record_in)
|
||||
outrows = get_csv_rows_for_installed(reader)
|
||||
outrows = get_csv_rows_for_installed(
|
||||
reader, installed=installed, changed=changed,
|
||||
generated=generated, lib_dir=lib_dir,
|
||||
)
|
||||
writer = csv.writer(record_out)
|
||||
# Sort to simplify testing.
|
||||
for row in sorted_outrows(outrows):
|
||||
|
@ -840,12 +858,6 @@ class WheelBuilder(object):
|
|||
newly built wheel, in preparation for installation.
|
||||
:return: True if all the wheels built correctly.
|
||||
"""
|
||||
# TODO: This check fails if --no-cache-dir is set. And yet we
|
||||
# might be able to build into the ephemeral cache, surely?
|
||||
building_is_possible = self._wheel_dir or (
|
||||
autobuilding and self.wheel_cache.cache_dir
|
||||
)
|
||||
assert building_is_possible
|
||||
|
||||
buildset = []
|
||||
format_control = self.finder.format_control
|
||||
|
@ -884,6 +896,13 @@ class WheelBuilder(object):
|
|||
if not buildset:
|
||||
return []
|
||||
|
||||
# Is any wheel build not using the ephemeral cache?
|
||||
if any(not ephem_cache for _, ephem_cache in buildset):
|
||||
have_directory_for_build = self._wheel_dir or (
|
||||
autobuilding and self.wheel_cache.cache_dir
|
||||
)
|
||||
assert have_directory_for_build
|
||||
|
||||
# TODO by @pradyunsg
|
||||
# Should break up this method into 2 separate methods.
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ Vendoring Policy
|
|||
``pip/_vendor/README.rst`` and their corresponding patches **MUST** be
|
||||
included ``tasks/vendoring/patches``.
|
||||
|
||||
* Vendored libraries should have corresponding ``vendored()`` entries in
|
||||
``pip/_vendor/__init__.py``.
|
||||
|
||||
Rationale
|
||||
---------
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
from .core import where, old_where
|
||||
from .core import where
|
||||
|
||||
__version__ = "2018.08.24"
|
||||
__version__ = "2018.11.29"
|
||||
|
|
|
@ -326,36 +326,6 @@ OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
|
|||
QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
|
||||
# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
|
||||
# Label: "Visa eCommerce Root"
|
||||
# Serial: 25952180776285836048024890241505565794
|
||||
# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02
|
||||
# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62
|
||||
# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
|
||||
MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
|
||||
cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
|
||||
bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
|
||||
CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
|
||||
dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
|
||||
cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
|
||||
2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
|
||||
lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
|
||||
ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
|
||||
299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
|
||||
vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
|
||||
dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
|
||||
AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
|
||||
AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
|
||||
zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
|
||||
LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
|
||||
7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
|
||||
++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
|
||||
398znM/jra6O1I7mT1GvFpLgXPYHDw==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
|
||||
# Subject: CN=AAA Certificate Services O=Comodo CA Limited
|
||||
# Label: "Comodo AAA Services root"
|
||||
|
@ -4298,3 +4268,245 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
|
|||
57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
|
||||
Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R1 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R1"
|
||||
# Serial: 146587175971765017618439757810265552097
|
||||
# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85
|
||||
# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8
|
||||
# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R2 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R2 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R2"
|
||||
# Serial: 146587176055767053814479386953112547951
|
||||
# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b
|
||||
# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d
|
||||
# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH
|
||||
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
|
||||
QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
|
||||
MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
|
||||
cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv
|
||||
CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg
|
||||
GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu
|
||||
XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd
|
||||
re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu
|
||||
PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1
|
||||
mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K
|
||||
8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj
|
||||
x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR
|
||||
nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0
|
||||
kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok
|
||||
twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
|
||||
HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp
|
||||
8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT
|
||||
vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT
|
||||
z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA
|
||||
pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb
|
||||
pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB
|
||||
R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R
|
||||
RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk
|
||||
0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC
|
||||
5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF
|
||||
izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn
|
||||
yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R3 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R3 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R3"
|
||||
# Serial: 146587176140553309517047991083707763997
|
||||
# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25
|
||||
# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5
|
||||
# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw
|
||||
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
|
||||
MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
|
||||
MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
|
||||
Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout
|
||||
736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A
|
||||
DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk
|
||||
fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA
|
||||
njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
|
||||
# Subject: CN=GTS Root R4 O=Google Trust Services LLC
|
||||
# Label: "GTS Root R4"
|
||||
# Serial: 146587176229350439916519468929765261721
|
||||
# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26
|
||||
# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb
|
||||
# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw
|
||||
CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
|
||||
MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
|
||||
MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
|
||||
Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA
|
||||
IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu
|
||||
hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l
|
||||
xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0
|
||||
CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx
|
||||
sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=UCA Global G2 Root O=UniTrust
|
||||
# Subject: CN=UCA Global G2 Root O=UniTrust
|
||||
# Label: "UCA Global G2 Root"
|
||||
# Serial: 124779693093741543919145257850076631279
|
||||
# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8
|
||||
# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a
|
||||
# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
UB+K+wb1whnw0A==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=UCA Extended Validation Root O=UniTrust
|
||||
# Subject: CN=UCA Extended Validation Root O=UniTrust
|
||||
# Label: "UCA Extended Validation Root"
|
||||
# Serial: 106100277556486529736699587978573607008
|
||||
# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2
|
||||
# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a
|
||||
# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH
|
||||
MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF
|
||||
eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx
|
||||
MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV
|
||||
BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB
|
||||
AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog
|
||||
D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS
|
||||
sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop
|
||||
O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk
|
||||
sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi
|
||||
c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj
|
||||
VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz
|
||||
KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/
|
||||
TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G
|
||||
sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs
|
||||
1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD
|
||||
fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T
|
||||
AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN
|
||||
l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR
|
||||
ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ
|
||||
VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5
|
||||
c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp
|
||||
4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s
|
||||
t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj
|
||||
2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO
|
||||
vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C
|
||||
xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx
|
||||
cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM
|
||||
fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
|
||||
# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
|
||||
# Label: "Certigna Root CA"
|
||||
# Serial: 269714418870597844693661054334862075617
|
||||
# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77
|
||||
# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43
|
||||
# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
|
||||
WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
|
||||
MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
|
||||
MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD
|
||||
VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX
|
||||
BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO
|
||||
ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M
|
||||
CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu
|
||||
I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm
|
||||
TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh
|
||||
C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf
|
||||
ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz
|
||||
IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT
|
||||
Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k
|
||||
JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5
|
||||
hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB
|
||||
GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
|
||||
FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
|
||||
1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov
|
||||
L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo
|
||||
dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr
|
||||
aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq
|
||||
hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L
|
||||
6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG
|
||||
HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6
|
||||
0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB
|
||||
lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi
|
||||
o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1
|
||||
gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v
|
||||
faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
|
||||
Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
|
||||
jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
|
||||
3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -8,14 +8,6 @@ certifi.py
|
|||
This module returns the installation location of cacert.pem.
|
||||
"""
|
||||
import os
|
||||
import warnings
|
||||
|
||||
|
||||
class DeprecatedBundleWarning(DeprecationWarning):
|
||||
"""
|
||||
The weak security bundle is being deprecated. Please bother your service
|
||||
provider to get them to stop using cross-signed roots.
|
||||
"""
|
||||
|
||||
|
||||
def where():
|
||||
|
@ -24,14 +16,5 @@ def where():
|
|||
return os.path.join(f, 'cacert.pem')
|
||||
|
||||
|
||||
def old_where():
|
||||
warnings.warn(
|
||||
"The weak security bundle has been removed. certifi.old_where() is now an alias "
|
||||
"of certifi.where(). Please update your code to use certifi.where() instead. "
|
||||
"certifi.old_where() will be removed in 2018.",
|
||||
DeprecatedBundleWarning
|
||||
)
|
||||
return where()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(where())
|
||||
|
|
|
@ -25,4 +25,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
|
|
@ -3,5 +3,4 @@ from .initialise import init, deinit, reinit, colorama_text
|
|||
from .ansi import Fore, Back, Style, Cursor
|
||||
from .ansitowin32 import AnsiToWin32
|
||||
|
||||
__version__ = '0.3.9'
|
||||
|
||||
__version__ = '0.4.1'
|
||||
|
|
|
@ -13,14 +13,6 @@ if windll is not None:
|
|||
winterm = WinTerm()
|
||||
|
||||
|
||||
def is_stream_closed(stream):
|
||||
return not hasattr(stream, 'closed') or stream.closed
|
||||
|
||||
|
||||
def is_a_tty(stream):
|
||||
return hasattr(stream, 'isatty') and stream.isatty()
|
||||
|
||||
|
||||
class StreamWrapper(object):
|
||||
'''
|
||||
Wraps a stream (such as stdout), acting as a transparent proxy for all
|
||||
|
@ -36,9 +28,38 @@ class StreamWrapper(object):
|
|||
def __getattr__(self, name):
|
||||
return getattr(self.__wrapped, name)
|
||||
|
||||
def __enter__(self, *args, **kwargs):
|
||||
# special method lookup bypasses __getattr__/__getattribute__, see
|
||||
# https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit
|
||||
# thus, contextlib magic methods are not proxied via __getattr__
|
||||
return self.__wrapped.__enter__(*args, **kwargs)
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
return self.__wrapped.__exit__(*args, **kwargs)
|
||||
|
||||
def write(self, text):
|
||||
self.__convertor.write(text)
|
||||
|
||||
def isatty(self):
|
||||
stream = self.__wrapped
|
||||
if 'PYCHARM_HOSTED' in os.environ:
|
||||
if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__):
|
||||
return True
|
||||
try:
|
||||
stream_isatty = stream.isatty
|
||||
except AttributeError:
|
||||
return False
|
||||
else:
|
||||
return stream_isatty()
|
||||
|
||||
@property
|
||||
def closed(self):
|
||||
stream = self.__wrapped
|
||||
try:
|
||||
return stream.closed
|
||||
except AttributeError:
|
||||
return True
|
||||
|
||||
|
||||
class AnsiToWin32(object):
|
||||
'''
|
||||
|
@ -68,12 +89,12 @@ class AnsiToWin32(object):
|
|||
|
||||
# should we strip ANSI sequences from our output?
|
||||
if strip is None:
|
||||
strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped))
|
||||
strip = conversion_supported or (not self.stream.closed and not self.stream.isatty())
|
||||
self.strip = strip
|
||||
|
||||
# should we should convert ANSI sequences into win32 calls?
|
||||
if convert is None:
|
||||
convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped)
|
||||
convert = conversion_supported and not self.stream.closed and self.stream.isatty()
|
||||
self.convert = convert
|
||||
|
||||
# dict of ansi codes to win32 functions and parameters
|
||||
|
@ -149,7 +170,7 @@ class AnsiToWin32(object):
|
|||
def reset_all(self):
|
||||
if self.convert:
|
||||
self.call_win32('m', (0,))
|
||||
elif not self.strip and not is_stream_closed(self.wrapped):
|
||||
elif not self.strip and not self.stream.closed:
|
||||
self.wrapped.write(Style.RESET_ALL)
|
||||
|
||||
|
||||
|
|
|
@ -78,5 +78,3 @@ def wrap_stream(stream, convert, strip, autoreset, wrap):
|
|||
if wrapper.should_wrap():
|
||||
stream = wrapper.stream
|
||||
return stream
|
||||
|
||||
|
||||
|
|
|
@ -89,11 +89,6 @@ else:
|
|||
]
|
||||
_SetConsoleTitleW.restype = wintypes.BOOL
|
||||
|
||||
handles = {
|
||||
STDOUT: _GetStdHandle(STDOUT),
|
||||
STDERR: _GetStdHandle(STDERR),
|
||||
}
|
||||
|
||||
def _winapi_test(handle):
|
||||
csbi = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
success = _GetConsoleScreenBufferInfo(
|
||||
|
@ -101,17 +96,18 @@ else:
|
|||
return bool(success)
|
||||
|
||||
def winapi_test():
|
||||
return any(_winapi_test(h) for h in handles.values())
|
||||
return any(_winapi_test(h) for h in
|
||||
(_GetStdHandle(STDOUT), _GetStdHandle(STDERR)))
|
||||
|
||||
def GetConsoleScreenBufferInfo(stream_id=STDOUT):
|
||||
handle = handles[stream_id]
|
||||
handle = _GetStdHandle(stream_id)
|
||||
csbi = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
success = _GetConsoleScreenBufferInfo(
|
||||
handle, byref(csbi))
|
||||
return csbi
|
||||
|
||||
def SetConsoleTextAttribute(stream_id, attrs):
|
||||
handle = handles[stream_id]
|
||||
handle = _GetStdHandle(stream_id)
|
||||
return _SetConsoleTextAttribute(handle, attrs)
|
||||
|
||||
def SetConsoleCursorPosition(stream_id, position, adjust=True):
|
||||
|
@ -129,11 +125,11 @@ else:
|
|||
adjusted_position.Y += sr.Top
|
||||
adjusted_position.X += sr.Left
|
||||
# Resume normal processing
|
||||
handle = handles[stream_id]
|
||||
handle = _GetStdHandle(stream_id)
|
||||
return _SetConsoleCursorPosition(handle, adjusted_position)
|
||||
|
||||
def FillConsoleOutputCharacter(stream_id, char, length, start):
|
||||
handle = handles[stream_id]
|
||||
handle = _GetStdHandle(stream_id)
|
||||
char = c_char(char.encode())
|
||||
length = wintypes.DWORD(length)
|
||||
num_written = wintypes.DWORD(0)
|
||||
|
@ -144,7 +140,7 @@ else:
|
|||
|
||||
def FillConsoleOutputAttribute(stream_id, attr, length, start):
|
||||
''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )'''
|
||||
handle = handles[stream_id]
|
||||
handle = _GetStdHandle(stream_id)
|
||||
attribute = wintypes.WORD(attr)
|
||||
length = wintypes.DWORD(length)
|
||||
num_written = wintypes.DWORD(0)
|
||||
|
|
|
@ -44,6 +44,7 @@ class WinTerm(object):
|
|||
def reset_all(self, on_stderr=None):
|
||||
self.set_attrs(self._default)
|
||||
self.set_console(attrs=self._default)
|
||||
self._light = 0
|
||||
|
||||
def fore(self, fore=None, light=False, on_stderr=False):
|
||||
if fore is None:
|
||||
|
@ -122,12 +123,15 @@ class WinTerm(object):
|
|||
if mode == 0:
|
||||
from_coord = csbi.dwCursorPosition
|
||||
cells_to_erase = cells_in_screen - cells_before_cursor
|
||||
if mode == 1:
|
||||
elif mode == 1:
|
||||
from_coord = win32.COORD(0, 0)
|
||||
cells_to_erase = cells_before_cursor
|
||||
elif mode == 2:
|
||||
from_coord = win32.COORD(0, 0)
|
||||
cells_to_erase = cells_in_screen
|
||||
else:
|
||||
# invalid mode
|
||||
return
|
||||
# fill the entire screen with blanks
|
||||
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
|
||||
# now set the buffer's attributes accordingly
|
||||
|
@ -147,12 +151,15 @@ class WinTerm(object):
|
|||
if mode == 0:
|
||||
from_coord = csbi.dwCursorPosition
|
||||
cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X
|
||||
if mode == 1:
|
||||
elif mode == 1:
|
||||
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
|
||||
cells_to_erase = csbi.dwCursorPosition.X
|
||||
elif mode == 2:
|
||||
from_coord = win32.COORD(0, csbi.dwCursorPosition.Y)
|
||||
cells_to_erase = csbi.dwSize.X
|
||||
else:
|
||||
# invalid mode
|
||||
return
|
||||
# fill the entire screen with blanks
|
||||
win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord)
|
||||
# now set the buffer's attributes accordingly
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
import logging
|
||||
|
||||
__version__ = '0.2.7'
|
||||
__version__ = '0.2.8'
|
||||
|
||||
class DistlibException(Exception):
|
||||
pass
|
||||
|
|
|
@ -20,7 +20,8 @@ import zipimport
|
|||
from . import DistlibException, resources
|
||||
from .compat import StringIO
|
||||
from .version import get_scheme, UnsupportedVersionError
|
||||
from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME
|
||||
from .metadata import (Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME,
|
||||
LEGACY_METADATA_FILENAME)
|
||||
from .util import (parse_requirement, cached_property, parse_name_and_version,
|
||||
read_exports, write_exports, CSVReader, CSVWriter)
|
||||
|
||||
|
@ -132,7 +133,9 @@ class DistributionPath(object):
|
|||
if not r or r.path in seen:
|
||||
continue
|
||||
if self._include_dist and entry.endswith(DISTINFO_EXT):
|
||||
possible_filenames = [METADATA_FILENAME, WHEEL_METADATA_FILENAME]
|
||||
possible_filenames = [METADATA_FILENAME,
|
||||
WHEEL_METADATA_FILENAME,
|
||||
LEGACY_METADATA_FILENAME]
|
||||
for metadata_filename in possible_filenames:
|
||||
metadata_path = posixpath.join(entry, metadata_filename)
|
||||
pydist = finder.find(metadata_path)
|
||||
|
|
|
@ -255,7 +255,9 @@ class Locator(object):
|
|||
if path.endswith('.whl'):
|
||||
try:
|
||||
wheel = Wheel(path)
|
||||
if is_compatible(wheel, self.wheel_tags):
|
||||
if not is_compatible(wheel, self.wheel_tags):
|
||||
logger.debug('Wheel not compatible: %s', path)
|
||||
else:
|
||||
if project_name is None:
|
||||
include = True
|
||||
else:
|
||||
|
@ -613,6 +615,7 @@ class SimpleScrapingLocator(Locator):
|
|||
# as it is for coordinating our internal threads - the ones created
|
||||
# in _prepare_threads.
|
||||
self._gplock = threading.RLock()
|
||||
self.platform_check = False # See issue #112
|
||||
|
||||
def _prepare_threads(self):
|
||||
"""
|
||||
|
@ -658,8 +661,8 @@ class SimpleScrapingLocator(Locator):
|
|||
del self.result
|
||||
return result
|
||||
|
||||
platform_dependent = re.compile(r'\b(linux-(i\d86|x86_64|arm\w+)|'
|
||||
r'win(32|-amd64)|macosx-?\d+)\b', re.I)
|
||||
platform_dependent = re.compile(r'\b(linux_(i\d86|x86_64|arm\w+)|'
|
||||
r'win(32|_amd64)|macosx_?\d+)\b', re.I)
|
||||
|
||||
def _is_platform_dependent(self, url):
|
||||
"""
|
||||
|
@ -677,7 +680,7 @@ class SimpleScrapingLocator(Locator):
|
|||
Note that the return value isn't actually used other than as a boolean
|
||||
value.
|
||||
"""
|
||||
if self._is_platform_dependent(url):
|
||||
if self.platform_check and self._is_platform_dependent(url):
|
||||
info = None
|
||||
else:
|
||||
info = self.convert_url_to_download_info(url, self.project_name)
|
||||
|
|
|
@ -91,7 +91,9 @@ _426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform',
|
|||
_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By',
|
||||
'Setup-Requires-Dist', 'Extension')
|
||||
|
||||
_566_FIELDS = _426_FIELDS + ('Description-Content-Type',)
|
||||
# See issue #106: Sometimes 'Requires' occurs wrongly in the metadata. Include
|
||||
# it in the tuple literal below to allow it (for now)
|
||||
_566_FIELDS = _426_FIELDS + ('Description-Content-Type', 'Requires')
|
||||
|
||||
_566_MARKERS = ('Description-Content-Type',)
|
||||
|
||||
|
@ -377,8 +379,8 @@ class LegacyMetadata(object):
|
|||
value = msg[field]
|
||||
if value is not None and value != 'UNKNOWN':
|
||||
self.set(field, value)
|
||||
logger.debug('Attempting to set metadata for %s', self)
|
||||
self.set_metadata_version()
|
||||
# logger.debug('Attempting to set metadata for %s', self)
|
||||
# self.set_metadata_version()
|
||||
|
||||
def write(self, filepath, skip_unknown=False):
|
||||
"""Write the metadata fields to filepath."""
|
||||
|
@ -648,6 +650,7 @@ class LegacyMetadata(object):
|
|||
|
||||
METADATA_FILENAME = 'pydist.json'
|
||||
WHEEL_METADATA_FILENAME = 'metadata.json'
|
||||
LEGACY_METADATA_FILENAME = 'METADATA'
|
||||
|
||||
|
||||
class Metadata(object):
|
||||
|
|
|
@ -236,8 +236,10 @@ class ScriptMaker(object):
|
|||
def _write_script(self, names, shebang, script_bytes, filenames, ext):
|
||||
use_launcher = self.add_launchers and self._is_nt
|
||||
linesep = os.linesep.encode('utf-8')
|
||||
if not shebang.endswith(linesep):
|
||||
shebang += linesep
|
||||
if not use_launcher:
|
||||
script_bytes = shebang + linesep + script_bytes
|
||||
script_bytes = shebang + script_bytes
|
||||
else: # pragma: no cover
|
||||
if ext == 'py':
|
||||
launcher = self._get_launcher('t')
|
||||
|
@ -247,7 +249,7 @@ class ScriptMaker(object):
|
|||
with ZipFile(stream, 'w') as zf:
|
||||
zf.writestr('__main__.py', script_bytes)
|
||||
zip_data = stream.getvalue()
|
||||
script_bytes = launcher + shebang + linesep + zip_data
|
||||
script_bytes = launcher + shebang + zip_data
|
||||
for name in names:
|
||||
outname = os.path.join(self.target_dir, name)
|
||||
if use_launcher: # pragma: no cover
|
||||
|
|
|
@ -545,16 +545,14 @@ class FileOperator(object):
|
|||
def write_binary_file(self, path, data):
|
||||
self.ensure_dir(os.path.dirname(path))
|
||||
if not self.dry_run:
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
with open(path, 'wb') as f:
|
||||
f.write(data)
|
||||
self.record_as_written(path)
|
||||
|
||||
def write_text_file(self, path, data, encoding):
|
||||
self.ensure_dir(os.path.dirname(path))
|
||||
if not self.dry_run:
|
||||
with open(path, 'wb') as f:
|
||||
f.write(data.encode(encoding))
|
||||
self.record_as_written(path)
|
||||
self.write_binary_file(path, data.encode(encoding))
|
||||
|
||||
def set_mode(self, bits, mask, files):
|
||||
if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'):
|
||||
|
@ -582,7 +580,7 @@ class FileOperator(object):
|
|||
if self.record:
|
||||
self.dirs_created.add(path)
|
||||
|
||||
def byte_compile(self, path, optimize=False, force=False, prefix=None):
|
||||
def byte_compile(self, path, optimize=False, force=False, prefix=None, hashed_invalidation=False):
|
||||
dpath = cache_from_source(path, not optimize)
|
||||
logger.info('Byte-compiling %s to %s', path, dpath)
|
||||
if not self.dry_run:
|
||||
|
@ -592,7 +590,10 @@ class FileOperator(object):
|
|||
else:
|
||||
assert path.startswith(prefix)
|
||||
diagpath = path[len(prefix):]
|
||||
py_compile.compile(path, dpath, diagpath, True) # raise error
|
||||
compile_kwargs = {}
|
||||
if hashed_invalidation and hasattr(py_compile, 'PycInvalidationMode'):
|
||||
compile_kwargs['invalidation_mode'] = py_compile.PycInvalidationMode.CHECKED_HASH
|
||||
py_compile.compile(path, dpath, diagpath, True, **compile_kwargs) # raise error
|
||||
self.record_as_written(dpath)
|
||||
return dpath
|
||||
|
||||
|
|
|
@ -442,7 +442,9 @@ class Wheel(object):
|
|||
This can be used to issue any warnings to raise any exceptions.
|
||||
If kwarg ``lib_only`` is True, only the purelib/platlib files are
|
||||
installed, and the headers, scripts, data and dist-info metadata are
|
||||
not written.
|
||||
not written. If kwarg ``bytecode_hashed_invalidation`` is True, written
|
||||
bytecode will try to use file-hash based invalidation (PEP-552) on
|
||||
supported interpreter versions (CPython 2.7+).
|
||||
|
||||
The return value is a :class:`InstalledDistribution` instance unless
|
||||
``options.lib_only`` is True, in which case the return value is ``None``.
|
||||
|
@ -451,6 +453,7 @@ class Wheel(object):
|
|||
dry_run = maker.dry_run
|
||||
warner = kwargs.get('warner')
|
||||
lib_only = kwargs.get('lib_only', False)
|
||||
bc_hashed_invalidation = kwargs.get('bytecode_hashed_invalidation', False)
|
||||
|
||||
pathname = os.path.join(self.dirname, self.filename)
|
||||
name_ver = '%s-%s' % (self.name, self.version)
|
||||
|
@ -557,7 +560,8 @@ class Wheel(object):
|
|||
'%s' % outfile)
|
||||
if bc and outfile.endswith('.py'):
|
||||
try:
|
||||
pyc = fileop.byte_compile(outfile)
|
||||
pyc = fileop.byte_compile(outfile,
|
||||
hashed_invalidation=bc_hashed_invalidation)
|
||||
outfiles.append(pyc)
|
||||
except Exception:
|
||||
# Don't give up if byte-compilation fails,
|
||||
|
|
2
src/pip/_vendor/idna/LICENSE.rst
Normal file → Executable file
2
src/pip/_vendor/idna/LICENSE.rst
Normal file → Executable file
|
@ -1,7 +1,7 @@
|
|||
License
|
||||
-------
|
||||
|
||||
Copyright (c) 2013-2017, Kim Davies. All rights reserved.
|
||||
Copyright (c) 2013-2018, Kim Davies. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
|
|
@ -267,10 +267,7 @@ def alabel(label):
|
|||
|
||||
try:
|
||||
label = label.encode('ascii')
|
||||
try:
|
||||
ulabel(label)
|
||||
except IDNAError:
|
||||
raise IDNAError('The label {0} is not a valid A-label'.format(label))
|
||||
ulabel(label)
|
||||
if not valid_label_length(label):
|
||||
raise IDNAError('Label too long')
|
||||
return label
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# This file is automatically generated by tools/idna-data
|
||||
|
||||
__version__ = "10.0.0"
|
||||
__version__ = "11.0.0"
|
||||
scripts = {
|
||||
'Greek': (
|
||||
0x37000000374,
|
||||
|
@ -49,7 +49,7 @@ scripts = {
|
|||
0x30210000302a,
|
||||
0x30380000303c,
|
||||
0x340000004db6,
|
||||
0x4e0000009feb,
|
||||
0x4e0000009ff0,
|
||||
0xf9000000fa6e,
|
||||
0xfa700000fada,
|
||||
0x200000002a6d7,
|
||||
|
@ -62,7 +62,7 @@ scripts = {
|
|||
'Hebrew': (
|
||||
0x591000005c8,
|
||||
0x5d0000005eb,
|
||||
0x5f0000005f5,
|
||||
0x5ef000005f5,
|
||||
0xfb1d0000fb37,
|
||||
0xfb380000fb3d,
|
||||
0xfb3e0000fb3f,
|
||||
|
@ -248,6 +248,7 @@ joining_types = {
|
|||
0x6fb: 68,
|
||||
0x6fc: 68,
|
||||
0x6ff: 68,
|
||||
0x70f: 84,
|
||||
0x710: 82,
|
||||
0x712: 68,
|
||||
0x713: 68,
|
||||
|
@ -522,6 +523,7 @@ joining_types = {
|
|||
0x1875: 68,
|
||||
0x1876: 68,
|
||||
0x1877: 68,
|
||||
0x1878: 68,
|
||||
0x1880: 85,
|
||||
0x1881: 85,
|
||||
0x1882: 85,
|
||||
|
@ -690,6 +692,70 @@ joining_types = {
|
|||
0x10bad: 68,
|
||||
0x10bae: 68,
|
||||
0x10baf: 85,
|
||||
0x10d00: 76,
|
||||
0x10d01: 68,
|
||||
0x10d02: 68,
|
||||
0x10d03: 68,
|
||||
0x10d04: 68,
|
||||
0x10d05: 68,
|
||||
0x10d06: 68,
|
||||
0x10d07: 68,
|
||||
0x10d08: 68,
|
||||
0x10d09: 68,
|
||||
0x10d0a: 68,
|
||||
0x10d0b: 68,
|
||||
0x10d0c: 68,
|
||||
0x10d0d: 68,
|
||||
0x10d0e: 68,
|
||||
0x10d0f: 68,
|
||||
0x10d10: 68,
|
||||
0x10d11: 68,
|
||||
0x10d12: 68,
|
||||
0x10d13: 68,
|
||||
0x10d14: 68,
|
||||
0x10d15: 68,
|
||||
0x10d16: 68,
|
||||
0x10d17: 68,
|
||||
0x10d18: 68,
|
||||
0x10d19: 68,
|
||||
0x10d1a: 68,
|
||||
0x10d1b: 68,
|
||||
0x10d1c: 68,
|
||||
0x10d1d: 68,
|
||||
0x10d1e: 68,
|
||||
0x10d1f: 68,
|
||||
0x10d20: 68,
|
||||
0x10d21: 68,
|
||||
0x10d22: 82,
|
||||
0x10d23: 68,
|
||||
0x10f30: 68,
|
||||
0x10f31: 68,
|
||||
0x10f32: 68,
|
||||
0x10f33: 82,
|
||||
0x10f34: 68,
|
||||
0x10f35: 68,
|
||||
0x10f36: 68,
|
||||
0x10f37: 68,
|
||||
0x10f38: 68,
|
||||
0x10f39: 68,
|
||||
0x10f3a: 68,
|
||||
0x10f3b: 68,
|
||||
0x10f3c: 68,
|
||||
0x10f3d: 68,
|
||||
0x10f3e: 68,
|
||||
0x10f3f: 68,
|
||||
0x10f40: 68,
|
||||
0x10f41: 68,
|
||||
0x10f42: 68,
|
||||
0x10f43: 68,
|
||||
0x10f44: 68,
|
||||
0x10f45: 85,
|
||||
0x10f51: 68,
|
||||
0x10f52: 68,
|
||||
0x10f53: 68,
|
||||
0x10f54: 82,
|
||||
0x110bd: 85,
|
||||
0x110cd: 85,
|
||||
0x1e900: 68,
|
||||
0x1e901: 68,
|
||||
0x1e902: 68,
|
||||
|
@ -1034,14 +1100,15 @@ codepoint_classes = {
|
|||
0x52d0000052e,
|
||||
0x52f00000530,
|
||||
0x5590000055a,
|
||||
0x56100000587,
|
||||
0x56000000587,
|
||||
0x58800000589,
|
||||
0x591000005be,
|
||||
0x5bf000005c0,
|
||||
0x5c1000005c3,
|
||||
0x5c4000005c6,
|
||||
0x5c7000005c8,
|
||||
0x5d0000005eb,
|
||||
0x5f0000005f3,
|
||||
0x5ef000005f3,
|
||||
0x6100000061b,
|
||||
0x62000000640,
|
||||
0x64100000660,
|
||||
|
@ -1054,12 +1121,13 @@ codepoint_classes = {
|
|||
0x7100000074b,
|
||||
0x74d000007b2,
|
||||
0x7c0000007f6,
|
||||
0x7fd000007fe,
|
||||
0x8000000082e,
|
||||
0x8400000085c,
|
||||
0x8600000086b,
|
||||
0x8a0000008b5,
|
||||
0x8b6000008be,
|
||||
0x8d4000008e2,
|
||||
0x8d3000008e2,
|
||||
0x8e300000958,
|
||||
0x96000000964,
|
||||
0x96600000970,
|
||||
|
@ -1077,6 +1145,7 @@ codepoint_classes = {
|
|||
0x9e0000009e4,
|
||||
0x9e6000009f2,
|
||||
0x9fc000009fd,
|
||||
0x9fe000009ff,
|
||||
0xa0100000a04,
|
||||
0xa0500000a0b,
|
||||
0xa0f00000a11,
|
||||
|
@ -1136,8 +1205,7 @@ codepoint_classes = {
|
|||
0xbd000000bd1,
|
||||
0xbd700000bd8,
|
||||
0xbe600000bf0,
|
||||
0xc0000000c04,
|
||||
0xc0500000c0d,
|
||||
0xc0000000c0d,
|
||||
0xc0e00000c11,
|
||||
0xc1200000c29,
|
||||
0xc2a00000c3a,
|
||||
|
@ -1276,7 +1344,7 @@ codepoint_classes = {
|
|||
0x17dc000017de,
|
||||
0x17e0000017ea,
|
||||
0x18100000181a,
|
||||
0x182000001878,
|
||||
0x182000001879,
|
||||
0x1880000018ab,
|
||||
0x18b0000018f6,
|
||||
0x19000000191f,
|
||||
|
@ -1544,11 +1612,11 @@ codepoint_classes = {
|
|||
0x309d0000309f,
|
||||
0x30a1000030fb,
|
||||
0x30fc000030ff,
|
||||
0x31050000312f,
|
||||
0x310500003130,
|
||||
0x31a0000031bb,
|
||||
0x31f000003200,
|
||||
0x340000004db6,
|
||||
0x4e0000009feb,
|
||||
0x4e0000009ff0,
|
||||
0xa0000000a48d,
|
||||
0xa4d00000a4fe,
|
||||
0xa5000000a60d,
|
||||
|
@ -1655,8 +1723,10 @@ codepoint_classes = {
|
|||
0xa7a50000a7a6,
|
||||
0xa7a70000a7a8,
|
||||
0xa7a90000a7aa,
|
||||
0xa7af0000a7b0,
|
||||
0xa7b50000a7b6,
|
||||
0xa7b70000a7b8,
|
||||
0xa7b90000a7ba,
|
||||
0xa7f70000a7f8,
|
||||
0xa7fa0000a828,
|
||||
0xa8400000a874,
|
||||
|
@ -1664,8 +1734,7 @@ codepoint_classes = {
|
|||
0xa8d00000a8da,
|
||||
0xa8e00000a8f8,
|
||||
0xa8fb0000a8fc,
|
||||
0xa8fd0000a8fe,
|
||||
0xa9000000a92e,
|
||||
0xa8fd0000a92e,
|
||||
0xa9300000a954,
|
||||
0xa9800000a9c1,
|
||||
0xa9cf0000a9da,
|
||||
|
@ -1743,7 +1812,7 @@ codepoint_classes = {
|
|||
0x10a0500010a07,
|
||||
0x10a0c00010a14,
|
||||
0x10a1500010a18,
|
||||
0x10a1900010a34,
|
||||
0x10a1900010a36,
|
||||
0x10a3800010a3b,
|
||||
0x10a3f00010a40,
|
||||
0x10a6000010a7d,
|
||||
|
@ -1756,6 +1825,11 @@ codepoint_classes = {
|
|||
0x10b8000010b92,
|
||||
0x10c0000010c49,
|
||||
0x10cc000010cf3,
|
||||
0x10d0000010d28,
|
||||
0x10d3000010d3a,
|
||||
0x10f0000010f1d,
|
||||
0x10f2700010f28,
|
||||
0x10f3000010f51,
|
||||
0x1100000011047,
|
||||
0x1106600011070,
|
||||
0x1107f000110bb,
|
||||
|
@ -1763,10 +1837,11 @@ codepoint_classes = {
|
|||
0x110f0000110fa,
|
||||
0x1110000011135,
|
||||
0x1113600011140,
|
||||
0x1114400011147,
|
||||
0x1115000011174,
|
||||
0x1117600011177,
|
||||
0x11180000111c5,
|
||||
0x111ca000111cd,
|
||||
0x111c9000111cd,
|
||||
0x111d0000111db,
|
||||
0x111dc000111dd,
|
||||
0x1120000011212,
|
||||
|
@ -1786,7 +1861,7 @@ codepoint_classes = {
|
|||
0x1132a00011331,
|
||||
0x1133200011334,
|
||||
0x113350001133a,
|
||||
0x1133c00011345,
|
||||
0x1133b00011345,
|
||||
0x1134700011349,
|
||||
0x1134b0001134e,
|
||||
0x1135000011351,
|
||||
|
@ -1796,6 +1871,7 @@ codepoint_classes = {
|
|||
0x1137000011375,
|
||||
0x114000001144b,
|
||||
0x114500001145a,
|
||||
0x1145e0001145f,
|
||||
0x11480000114c6,
|
||||
0x114c7000114c8,
|
||||
0x114d0000114da,
|
||||
|
@ -1807,15 +1883,17 @@ codepoint_classes = {
|
|||
0x116500001165a,
|
||||
0x11680000116b8,
|
||||
0x116c0000116ca,
|
||||
0x117000001171a,
|
||||
0x117000001171b,
|
||||
0x1171d0001172c,
|
||||
0x117300001173a,
|
||||
0x118000001183b,
|
||||
0x118c0000118ea,
|
||||
0x118ff00011900,
|
||||
0x11a0000011a3f,
|
||||
0x11a4700011a48,
|
||||
0x11a5000011a84,
|
||||
0x11a8600011a9a,
|
||||
0x11a9d00011a9e,
|
||||
0x11ac000011af9,
|
||||
0x11c0000011c09,
|
||||
0x11c0a00011c37,
|
||||
|
@ -1831,6 +1909,13 @@ codepoint_classes = {
|
|||
0x11d3c00011d3e,
|
||||
0x11d3f00011d48,
|
||||
0x11d5000011d5a,
|
||||
0x11d6000011d66,
|
||||
0x11d6700011d69,
|
||||
0x11d6a00011d8f,
|
||||
0x11d9000011d92,
|
||||
0x11d9300011d99,
|
||||
0x11da000011daa,
|
||||
0x11ee000011ef7,
|
||||
0x120000001239a,
|
||||
0x1248000012544,
|
||||
0x130000001342f,
|
||||
|
@ -1845,11 +1930,12 @@ codepoint_classes = {
|
|||
0x16b5000016b5a,
|
||||
0x16b6300016b78,
|
||||
0x16b7d00016b90,
|
||||
0x16e6000016e80,
|
||||
0x16f0000016f45,
|
||||
0x16f5000016f7f,
|
||||
0x16f8f00016fa0,
|
||||
0x16fe000016fe2,
|
||||
0x17000000187ed,
|
||||
0x17000000187f2,
|
||||
0x1880000018af3,
|
||||
0x1b0000001b11f,
|
||||
0x1b1700001b2fc,
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
__version__ = '2.7'
|
||||
__version__ = '2.8'
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,18 +4,24 @@
|
|||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__all__ = [
|
||||
"__title__", "__summary__", "__uri__", "__version__", "__author__",
|
||||
"__email__", "__license__", "__copyright__",
|
||||
"__title__",
|
||||
"__summary__",
|
||||
"__uri__",
|
||||
"__version__",
|
||||
"__author__",
|
||||
"__email__",
|
||||
"__license__",
|
||||
"__copyright__",
|
||||
]
|
||||
|
||||
__title__ = "packaging"
|
||||
__summary__ = "Core utilities for Python packages"
|
||||
__uri__ = "https://github.com/pypa/packaging"
|
||||
|
||||
__version__ = "18.0"
|
||||
__version__ = "19.0"
|
||||
|
||||
__author__ = "Donald Stufft and individual contributors"
|
||||
__email__ = "donald@stufft.io"
|
||||
|
||||
__license__ = "BSD or Apache License, Version 2.0"
|
||||
__copyright__ = "Copyright 2014-2018 %s" % __author__
|
||||
__copyright__ = "Copyright 2014-2019 %s" % __author__
|
||||
|
|
|
@ -4,11 +4,23 @@
|
|||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from .__about__ import (
|
||||
__author__, __copyright__, __email__, __license__, __summary__, __title__,
|
||||
__uri__, __version__
|
||||
__author__,
|
||||
__copyright__,
|
||||
__email__,
|
||||
__license__,
|
||||
__summary__,
|
||||
__title__,
|
||||
__uri__,
|
||||
__version__,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"__title__", "__summary__", "__uri__", "__version__", "__author__",
|
||||
"__email__", "__license__", "__copyright__",
|
||||
"__title__",
|
||||
"__summary__",
|
||||
"__uri__",
|
||||
"__version__",
|
||||
"__author__",
|
||||
"__email__",
|
||||
"__license__",
|
||||
"__copyright__",
|
||||
]
|
||||
|
|
|
@ -12,9 +12,9 @@ PY3 = sys.version_info[0] == 3
|
|||
# flake8: noqa
|
||||
|
||||
if PY3:
|
||||
string_types = str,
|
||||
string_types = (str,)
|
||||
else:
|
||||
string_types = basestring,
|
||||
string_types = (basestring,)
|
||||
|
||||
|
||||
def with_metaclass(meta, *bases):
|
||||
|
@ -27,4 +27,5 @@ def with_metaclass(meta, *bases):
|
|||
class metaclass(meta):
|
||||
def __new__(cls, name, this_bases, d):
|
||||
return meta(name, bases, d)
|
||||
return type.__new__(metaclass, 'temporary_class', (), {})
|
||||
|
||||
return type.__new__(metaclass, "temporary_class", (), {})
|
||||
|
|
|
@ -5,7 +5,6 @@ from __future__ import absolute_import, division, print_function
|
|||
|
||||
|
||||
class Infinity(object):
|
||||
|
||||
def __repr__(self):
|
||||
return "Infinity"
|
||||
|
||||
|
@ -38,7 +37,6 @@ Infinity = Infinity()
|
|||
|
||||
|
||||
class NegativeInfinity(object):
|
||||
|
||||
def __repr__(self):
|
||||
return "-Infinity"
|
||||
|
||||
|
|
|
@ -17,8 +17,11 @@ from .specifiers import Specifier, InvalidSpecifier
|
|||
|
||||
|
||||
__all__ = [
|
||||
"InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName",
|
||||
"Marker", "default_environment",
|
||||
"InvalidMarker",
|
||||
"UndefinedComparison",
|
||||
"UndefinedEnvironmentName",
|
||||
"Marker",
|
||||
"default_environment",
|
||||
]
|
||||
|
||||
|
||||
|
@ -42,7 +45,6 @@ class UndefinedEnvironmentName(ValueError):
|
|||
|
||||
|
||||
class Node(object):
|
||||
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
|
@ -57,62 +59,52 @@ class Node(object):
|
|||
|
||||
|
||||
class Variable(Node):
|
||||
|
||||
def serialize(self):
|
||||
return str(self)
|
||||
|
||||
|
||||
class Value(Node):
|
||||
|
||||
def serialize(self):
|
||||
return '"{0}"'.format(self)
|
||||
|
||||
|
||||
class Op(Node):
|
||||
|
||||
def serialize(self):
|
||||
return str(self)
|
||||
|
||||
|
||||
VARIABLE = (
|
||||
L("implementation_version") |
|
||||
L("platform_python_implementation") |
|
||||
L("implementation_name") |
|
||||
L("python_full_version") |
|
||||
L("platform_release") |
|
||||
L("platform_version") |
|
||||
L("platform_machine") |
|
||||
L("platform_system") |
|
||||
L("python_version") |
|
||||
L("sys_platform") |
|
||||
L("os_name") |
|
||||
L("os.name") | # PEP-345
|
||||
L("sys.platform") | # PEP-345
|
||||
L("platform.version") | # PEP-345
|
||||
L("platform.machine") | # PEP-345
|
||||
L("platform.python_implementation") | # PEP-345
|
||||
L("python_implementation") | # undocumented setuptools legacy
|
||||
L("extra")
|
||||
L("implementation_version")
|
||||
| L("platform_python_implementation")
|
||||
| L("implementation_name")
|
||||
| L("python_full_version")
|
||||
| L("platform_release")
|
||||
| L("platform_version")
|
||||
| L("platform_machine")
|
||||
| L("platform_system")
|
||||
| L("python_version")
|
||||
| L("sys_platform")
|
||||
| L("os_name")
|
||||
| L("os.name")
|
||||
| L("sys.platform") # PEP-345
|
||||
| L("platform.version") # PEP-345
|
||||
| L("platform.machine") # PEP-345
|
||||
| L("platform.python_implementation") # PEP-345
|
||||
| L("python_implementation") # PEP-345
|
||||
| L("extra") # undocumented setuptools legacy
|
||||
)
|
||||
ALIASES = {
|
||||
'os.name': 'os_name',
|
||||
'sys.platform': 'sys_platform',
|
||||
'platform.version': 'platform_version',
|
||||
'platform.machine': 'platform_machine',
|
||||
'platform.python_implementation': 'platform_python_implementation',
|
||||
'python_implementation': 'platform_python_implementation'
|
||||
"os.name": "os_name",
|
||||
"sys.platform": "sys_platform",
|
||||
"platform.version": "platform_version",
|
||||
"platform.machine": "platform_machine",
|
||||
"platform.python_implementation": "platform_python_implementation",
|
||||
"python_implementation": "platform_python_implementation",
|
||||
}
|
||||
VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0])))
|
||||
|
||||
VERSION_CMP = (
|
||||
L("===") |
|
||||
L("==") |
|
||||
L(">=") |
|
||||
L("<=") |
|
||||
L("!=") |
|
||||
L("~=") |
|
||||
L(">") |
|
||||
L("<")
|
||||
L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<")
|
||||
)
|
||||
|
||||
MARKER_OP = VERSION_CMP | L("not in") | L("in")
|
||||
|
@ -152,8 +144,11 @@ def _format_marker(marker, first=True):
|
|||
# where the single item is itself it's own list. In that case we want skip
|
||||
# the rest of this function so that we don't get extraneous () on the
|
||||
# outside.
|
||||
if (isinstance(marker, list) and len(marker) == 1 and
|
||||
isinstance(marker[0], (list, tuple))):
|
||||
if (
|
||||
isinstance(marker, list)
|
||||
and len(marker) == 1
|
||||
and isinstance(marker[0], (list, tuple))
|
||||
):
|
||||
return _format_marker(marker[0])
|
||||
|
||||
if isinstance(marker, list):
|
||||
|
@ -239,20 +234,20 @@ def _evaluate_markers(markers, environment):
|
|||
|
||||
|
||||
def format_full_version(info):
|
||||
version = '{0.major}.{0.minor}.{0.micro}'.format(info)
|
||||
version = "{0.major}.{0.minor}.{0.micro}".format(info)
|
||||
kind = info.releaselevel
|
||||
if kind != 'final':
|
||||
if kind != "final":
|
||||
version += kind[0] + str(info.serial)
|
||||
return version
|
||||
|
||||
|
||||
def default_environment():
|
||||
if hasattr(sys, 'implementation'):
|
||||
if hasattr(sys, "implementation"):
|
||||
iver = format_full_version(sys.implementation.version)
|
||||
implementation_name = sys.implementation.name
|
||||
else:
|
||||
iver = '0'
|
||||
implementation_name = ''
|
||||
iver = "0"
|
||||
implementation_name = ""
|
||||
|
||||
return {
|
||||
"implementation_name": implementation_name,
|
||||
|
@ -270,13 +265,13 @@ def default_environment():
|
|||
|
||||
|
||||
class Marker(object):
|
||||
|
||||
def __init__(self, marker):
|
||||
try:
|
||||
self._markers = _coerce_parse_result(MARKER.parseString(marker))
|
||||
except ParseException as e:
|
||||
err_str = "Invalid marker: {0!r}, parse error at {1!r}".format(
|
||||
marker, marker[e.loc:e.loc + 8])
|
||||
marker, marker[e.loc : e.loc + 8]
|
||||
)
|
||||
raise InvalidMarker(err_str)
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -38,8 +38,8 @@ IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END))
|
|||
NAME = IDENTIFIER("name")
|
||||
EXTRA = IDENTIFIER
|
||||
|
||||
URI = Regex(r'[^ ]+')("url")
|
||||
URL = (AT + URI)
|
||||
URI = Regex(r"[^ ]+")("url")
|
||||
URL = AT + URI
|
||||
|
||||
EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA)
|
||||
EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras")
|
||||
|
@ -48,17 +48,18 @@ VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE)
|
|||
VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY
|
||||
VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE),
|
||||
joinString=",", adjacent=False)("_raw_spec")
|
||||
VERSION_MANY = Combine(
|
||||
VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False
|
||||
)("_raw_spec")
|
||||
_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY))
|
||||
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '')
|
||||
_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "")
|
||||
|
||||
VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier")
|
||||
VERSION_SPEC.setParseAction(lambda s, l, t: t[1])
|
||||
|
||||
MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
|
||||
MARKER_EXPR.setParseAction(
|
||||
lambda s, l, t: Marker(s[t._original_start:t._original_end])
|
||||
lambda s, l, t: Marker(s[t._original_start : t._original_end])
|
||||
)
|
||||
MARKER_SEPARATOR = SEMICOLON
|
||||
MARKER = MARKER_SEPARATOR + MARKER_EXPR
|
||||
|
@ -66,8 +67,7 @@ MARKER = MARKER_SEPARATOR + MARKER_EXPR
|
|||
VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER)
|
||||
URL_AND_MARKER = URL + Optional(MARKER)
|
||||
|
||||
NAMED_REQUIREMENT = \
|
||||
NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
|
||||
NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER)
|
||||
|
||||
REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd
|
||||
# pyparsing isn't thread safe during initialization, so we do it eagerly, see
|
||||
|
@ -92,15 +92,21 @@ class Requirement(object):
|
|||
try:
|
||||
req = REQUIREMENT.parseString(requirement_string)
|
||||
except ParseException as e:
|
||||
raise InvalidRequirement("Parse error at \"{0!r}\": {1}".format(
|
||||
requirement_string[e.loc:e.loc + 8], e.msg
|
||||
))
|
||||
raise InvalidRequirement(
|
||||
'Parse error at "{0!r}": {1}'.format(
|
||||
requirement_string[e.loc : e.loc + 8], e.msg
|
||||
)
|
||||
)
|
||||
|
||||
self.name = req.name
|
||||
if req.url:
|
||||
parsed_url = urlparse.urlparse(req.url)
|
||||
if not (parsed_url.scheme and parsed_url.netloc) or (
|
||||
not parsed_url.scheme and not parsed_url.netloc):
|
||||
if parsed_url.scheme == "file":
|
||||
if urlparse.urlunparse(parsed_url) != req.url:
|
||||
raise InvalidRequirement("Invalid URL given")
|
||||
elif not (parsed_url.scheme and parsed_url.netloc) or (
|
||||
not parsed_url.scheme and not parsed_url.netloc
|
||||
):
|
||||
raise InvalidRequirement("Invalid URL: {0}".format(req.url))
|
||||
self.url = req.url
|
||||
else:
|
||||
|
@ -120,6 +126,8 @@ class Requirement(object):
|
|||
|
||||
if self.url:
|
||||
parts.append("@ {0}".format(self.url))
|
||||
if self.marker:
|
||||
parts.append(" ")
|
||||
|
||||
if self.marker:
|
||||
parts.append("; {0}".format(self.marker))
|
||||
|
|
|
@ -19,7 +19,6 @@ class InvalidSpecifier(ValueError):
|
|||
|
||||
|
||||
class BaseSpecifier(with_metaclass(abc.ABCMeta, object)):
|
||||
|
||||
@abc.abstractmethod
|
||||
def __str__(self):
|
||||
"""
|
||||
|
@ -84,10 +83,7 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
if not match:
|
||||
raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec))
|
||||
|
||||
self._spec = (
|
||||
match.group("operator").strip(),
|
||||
match.group("version").strip(),
|
||||
)
|
||||
self._spec = (match.group("operator").strip(), match.group("version").strip())
|
||||
|
||||
# Store whether or not this Specifier should accept prereleases
|
||||
self._prereleases = prereleases
|
||||
|
@ -99,11 +95,7 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
else ""
|
||||
)
|
||||
|
||||
return "<{0}({1!r}{2})>".format(
|
||||
self.__class__.__name__,
|
||||
str(self),
|
||||
pre,
|
||||
)
|
||||
return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre)
|
||||
|
||||
def __str__(self):
|
||||
return "{0}{1}".format(*self._spec)
|
||||
|
@ -194,8 +186,9 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
# If our version is a prerelease, and we were not set to allow
|
||||
# prereleases, then we'll store it for later incase nothing
|
||||
# else matches this specifier.
|
||||
if (parsed_version.is_prerelease and not
|
||||
(prereleases or self.prereleases)):
|
||||
if parsed_version.is_prerelease and not (
|
||||
prereleases or self.prereleases
|
||||
):
|
||||
found_prereleases.append(version)
|
||||
# Either this is not a prerelease, or we should have been
|
||||
# accepting prereleases from the beginning.
|
||||
|
@ -213,8 +206,7 @@ class _IndividualSpecifier(BaseSpecifier):
|
|||
|
||||
class LegacySpecifier(_IndividualSpecifier):
|
||||
|
||||
_regex_str = (
|
||||
r"""
|
||||
_regex_str = r"""
|
||||
(?P<operator>(==|!=|<=|>=|<|>))
|
||||
\s*
|
||||
(?P<version>
|
||||
|
@ -225,10 +217,8 @@ class LegacySpecifier(_IndividualSpecifier):
|
|||
# them, and a comma since it's a version separator.
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
_regex = re.compile(
|
||||
r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
_regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
_operators = {
|
||||
"==": "equal",
|
||||
|
@ -269,13 +259,13 @@ def _require_version_compare(fn):
|
|||
if not isinstance(prospective, Version):
|
||||
return False
|
||||
return fn(self, prospective, spec)
|
||||
|
||||
return wrapped
|
||||
|
||||
|
||||
class Specifier(_IndividualSpecifier):
|
||||
|
||||
_regex_str = (
|
||||
r"""
|
||||
_regex_str = r"""
|
||||
(?P<operator>(~=|==|!=|<=|>=|<|>|===))
|
||||
(?P<version>
|
||||
(?:
|
||||
|
@ -367,10 +357,8 @@ class Specifier(_IndividualSpecifier):
|
|||
)
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
_regex = re.compile(
|
||||
r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
_regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE)
|
||||
|
||||
_operators = {
|
||||
"~=": "compatible",
|
||||
|
@ -397,8 +385,7 @@ class Specifier(_IndividualSpecifier):
|
|||
prefix = ".".join(
|
||||
list(
|
||||
itertools.takewhile(
|
||||
lambda x: (not x.startswith("post") and not
|
||||
x.startswith("dev")),
|
||||
lambda x: (not x.startswith("post") and not x.startswith("dev")),
|
||||
_version_split(spec),
|
||||
)
|
||||
)[:-1]
|
||||
|
@ -407,8 +394,9 @@ class Specifier(_IndividualSpecifier):
|
|||
# Add the prefix notation to the end of our string
|
||||
prefix += ".*"
|
||||
|
||||
return (self._get_operator(">=")(prospective, spec) and
|
||||
self._get_operator("==")(prospective, prefix))
|
||||
return self._get_operator(">=")(prospective, spec) and self._get_operator("==")(
|
||||
prospective, prefix
|
||||
)
|
||||
|
||||
@_require_version_compare
|
||||
def _compare_equal(self, prospective, spec):
|
||||
|
@ -428,7 +416,7 @@ class Specifier(_IndividualSpecifier):
|
|||
# Shorten the prospective version to be the same length as the spec
|
||||
# so that we can determine if the specifier is a prefix of the
|
||||
# prospective version or not.
|
||||
prospective = prospective[:len(spec)]
|
||||
prospective = prospective[: len(spec)]
|
||||
|
||||
# Pad out our two sides with zeros so that they both equal the same
|
||||
# length.
|
||||
|
@ -567,27 +555,17 @@ def _pad_version(left, right):
|
|||
right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
|
||||
|
||||
# Get the rest of our versions
|
||||
left_split.append(left[len(left_split[0]):])
|
||||
right_split.append(right[len(right_split[0]):])
|
||||
left_split.append(left[len(left_split[0]) :])
|
||||
right_split.append(right[len(right_split[0]) :])
|
||||
|
||||
# Insert our padding
|
||||
left_split.insert(
|
||||
1,
|
||||
["0"] * max(0, len(right_split[0]) - len(left_split[0])),
|
||||
)
|
||||
right_split.insert(
|
||||
1,
|
||||
["0"] * max(0, len(left_split[0]) - len(right_split[0])),
|
||||
)
|
||||
left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
|
||||
right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
|
||||
|
||||
return (
|
||||
list(itertools.chain(*left_split)),
|
||||
list(itertools.chain(*right_split)),
|
||||
)
|
||||
return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split)))
|
||||
|
||||
|
||||
class SpecifierSet(BaseSpecifier):
|
||||
|
||||
def __init__(self, specifiers="", prereleases=None):
|
||||
# Split on , to break each indidivual specifier into it's own item, and
|
||||
# strip each item to remove leading/trailing whitespace.
|
||||
|
@ -721,10 +699,7 @@ class SpecifierSet(BaseSpecifier):
|
|||
# given version is contained within all of them.
|
||||
# Note: This use of all() here means that an empty set of specifiers
|
||||
# will always return True, this is an explicit design decision.
|
||||
return all(
|
||||
s.contains(item, prereleases=prereleases)
|
||||
for s in self._specs
|
||||
)
|
||||
return all(s.contains(item, prereleases=prereleases) for s in self._specs)
|
||||
|
||||
def filter(self, iterable, prereleases=None):
|
||||
# Determine if we're forcing a prerelease or not, if we're not forcing
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue