mirror of https://github.com/pypa/pip
Merge pull request #9335 from hugovk/rm-2
Remove redundant Python 2.7 code
This commit is contained in:
commit
1eebb12550
|
@ -74,10 +74,6 @@ repos:
|
|||
- id: mypy
|
||||
exclude: docs|tests
|
||||
args: ["--pretty"]
|
||||
- id: mypy
|
||||
name: mypy, for Python 2
|
||||
exclude: noxfile.py|tools/automation/release|docs|tests
|
||||
args: ["--pretty", "-2"]
|
||||
|
||||
- repo: https://github.com/pre-commit/pygrep-hooks
|
||||
rev: v1.6.0
|
||||
|
|
|
@ -79,7 +79,7 @@ To run tests without parallelization, run:
|
|||
$ tox -e py36
|
||||
|
||||
The example above runs tests against Python 3.6. You can also use other
|
||||
versions like ``py27`` and ``pypy3``.
|
||||
versions like ``py39`` and ``pypy3``.
|
||||
|
||||
``tox`` has been configured to forward any additional arguments it is given to
|
||||
``pytest``. This enables the use of pytest's `rich CLI`_. As an example, you
|
||||
|
|
|
@ -173,4 +173,3 @@ order to create one of these the changes should already be merged into the
|
|||
.. _`get-pip repository`: https://github.com/pypa/get-pip
|
||||
.. _`psf-salt repository`: https://github.com/python/psf-salt
|
||||
.. _`CPython`: https://github.com/python/cpython
|
||||
.. _`CPython 2.7 EOL date`: https://www.python.org/doc/sunset-python-2/
|
||||
|
|
|
@ -291,7 +291,7 @@ Since version 6.0, pip also supports specifiers containing `environment markers
|
|||
|
||||
::
|
||||
|
||||
SomeProject ==5.4 ; python_version < '2.7'
|
||||
SomeProject ==5.4 ; python_version < '3.8'
|
||||
SomeProject; sys_platform == 'win32'
|
||||
|
||||
Since version 19.1, pip also supports `direct references
|
||||
|
|
|
@ -41,8 +41,8 @@ Examples
|
|||
|
||||
$ python -m pip uninstall simplejson
|
||||
Uninstalling simplejson:
|
||||
/home/me/env/lib/python2.7/site-packages/simplejson
|
||||
/home/me/env/lib/python2.7/site-packages/simplejson-2.2.1-py2.7.egg-info
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson-2.2.1-py3.9.egg-info
|
||||
Proceed (y/n)? y
|
||||
Successfully uninstalled simplejson
|
||||
|
||||
|
@ -52,7 +52,7 @@ Examples
|
|||
|
||||
C:\> py -m pip uninstall simplejson
|
||||
Uninstalling simplejson:
|
||||
/home/me/env/lib/python2.7/site-packages/simplejson
|
||||
/home/me/env/lib/python2.7/site-packages/simplejson-2.2.1-py2.7.egg-info
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson
|
||||
/home/me/env/lib/python3.9/site-packages/simplejson-2.2.1-py3.9.egg-info
|
||||
Proceed (y/n)? y
|
||||
Successfully uninstalled simplejson
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Modernise the codebase after Python 2.
|
|
@ -9,8 +9,6 @@ import os
|
|||
import sys
|
||||
import traceback
|
||||
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.command_context import CommandContextMixIn
|
||||
from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
|
||||
|
@ -183,7 +181,7 @@ class Command(CommandContextMixIn):
|
|||
issue=8333,
|
||||
)
|
||||
|
||||
if '2020-resolver' in options.features_enabled and not PY2:
|
||||
if '2020-resolver' in options.features_enabled:
|
||||
logger.warning(
|
||||
"--use-feature=2020-resolver no longer has any effect, "
|
||||
"since it is now the default dependency resolver in pip. "
|
||||
|
|
|
@ -7,16 +7,15 @@ from __future__ import absolute_import
|
|||
|
||||
import logging
|
||||
import optparse
|
||||
import shutil
|
||||
import sys
|
||||
import textwrap
|
||||
from distutils.util import strtobool
|
||||
|
||||
from pip._vendor.contextlib2 import suppress
|
||||
from pip._vendor.six import string_types
|
||||
|
||||
from pip._internal.cli.status_codes import UNKNOWN_ERROR
|
||||
from pip._internal.configuration import Configuration, ConfigurationError
|
||||
from pip._internal.utils.compat import get_terminal_size
|
||||
from pip._internal.utils.misc import redact_auth_from_url
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -29,7 +28,7 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
|||
# help position must be aligned with __init__.parseopts.description
|
||||
kwargs['max_help_position'] = 30
|
||||
kwargs['indent_increment'] = 1
|
||||
kwargs['width'] = get_terminal_size()[0] - 2
|
||||
kwargs['width'] = shutil.get_terminal_size()[0] - 2
|
||||
optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs)
|
||||
|
||||
def format_option_strings(self, option):
|
||||
|
@ -119,7 +118,7 @@ class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter):
|
|||
help_text = optparse.IndentedHelpFormatter.expand_default(self, option)
|
||||
|
||||
if default_values and option.metavar == 'URL':
|
||||
if isinstance(default_values, string_types):
|
||||
if isinstance(default_values, str):
|
||||
default_values = [default_values]
|
||||
|
||||
# If its not a list, we should abort and just return the help text
|
||||
|
@ -275,7 +274,7 @@ class ConfigOptionParser(CustomOptionParser):
|
|||
defaults = self._update_defaults(self.defaults.copy()) # ours
|
||||
for option in self._get_all_options():
|
||||
default = defaults.get(option.dest)
|
||||
if isinstance(default, string_types):
|
||||
if isinstance(default, str):
|
||||
opt_str = option.get_opt_string()
|
||||
defaults[option.dest] = option.check_value(opt_str, default)
|
||||
return optparse.Values(defaults)
|
||||
|
|
|
@ -4,7 +4,6 @@ import itertools
|
|||
import sys
|
||||
from signal import SIGINT, default_int_handler, signal
|
||||
|
||||
from pip._vendor import six
|
||||
from pip._vendor.progress.bar import Bar, FillingCirclesBar, IncrementalBar
|
||||
from pip._vendor.progress.spinner import Spinner
|
||||
|
||||
|
@ -36,8 +35,8 @@ def _select_progress_class(preferred, fallback):
|
|||
# Collect all of the possible characters we want to use with the preferred
|
||||
# bar.
|
||||
characters = [
|
||||
getattr(preferred, "empty_fill", six.text_type()),
|
||||
getattr(preferred, "fill", six.text_type()),
|
||||
getattr(preferred, "empty_fill", ""),
|
||||
getattr(preferred, "fill", ""),
|
||||
]
|
||||
characters += list(getattr(preferred, "phases", []))
|
||||
|
||||
|
@ -45,7 +44,7 @@ def _select_progress_class(preferred, fallback):
|
|||
# of the given file, if this works then we'll assume that we can use the
|
||||
# fancier bar and if not we'll fall back to the plaintext bar.
|
||||
try:
|
||||
six.text_type().join(characters).encode(encoding)
|
||||
"".join(characters).encode(encoding)
|
||||
except UnicodeEncodeError:
|
||||
return fallback
|
||||
else:
|
||||
|
|
|
@ -9,8 +9,6 @@ import logging
|
|||
import os
|
||||
from functools import partial
|
||||
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.base_command import Command
|
||||
from pip._internal.cli.command_context import CommandContextMixIn
|
||||
|
@ -200,14 +198,6 @@ class RequirementCommand(IndexGroupCommand):
|
|||
def determine_resolver_variant(options):
|
||||
# type: (Values) -> str
|
||||
"""Determines which resolver should be used, based on the given options."""
|
||||
# We didn't want to change things for Python 2, since it's nearly done with
|
||||
# and we're using performance improvements that only work on Python 3.
|
||||
if PY2:
|
||||
if '2020-resolver' in options.features_enabled:
|
||||
return "2020-resolver"
|
||||
else:
|
||||
return "legacy"
|
||||
|
||||
if "legacy-resolver" in options.deprecated_features_enabled:
|
||||
return "legacy"
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@ from __future__ import absolute_import
|
|||
import json
|
||||
import logging
|
||||
|
||||
from pip._vendor import six
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.req_command import IndexGroupCommand
|
||||
from pip._internal.cli.status_codes import SUCCESS
|
||||
|
@ -315,13 +313,13 @@ def format_for_json(packages, options):
|
|||
for dist in packages:
|
||||
info = {
|
||||
'name': dist.project_name,
|
||||
'version': six.text_type(dist.version),
|
||||
'version': str(dist.version),
|
||||
}
|
||||
if options.verbose >= 1:
|
||||
info['location'] = dist.location
|
||||
info['installer'] = get_installer(dist)
|
||||
if options.outdated:
|
||||
info['latest_version'] = six.text_type(dist.latest_version)
|
||||
info['latest_version'] = str(dist.latest_version)
|
||||
info['latest_filetype'] = dist.latest_filetype
|
||||
data.append(info)
|
||||
return json.dumps(data)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import shutil
|
||||
import sys
|
||||
import textwrap
|
||||
from collections import OrderedDict
|
||||
|
@ -18,7 +19,6 @@ from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS
|
|||
from pip._internal.exceptions import CommandError
|
||||
from pip._internal.models.index import PyPI
|
||||
from pip._internal.network.xmlrpc import PipXmlrpcTransport
|
||||
from pip._internal.utils.compat import get_terminal_size
|
||||
from pip._internal.utils.logging import indent_log
|
||||
from pip._internal.utils.misc import get_distribution, write_output
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
@ -64,7 +64,7 @@ class SearchCommand(Command, SessionCommandMixin):
|
|||
|
||||
terminal_width = None
|
||||
if sys.stdout.isatty():
|
||||
terminal_width = get_terminal_size()[0]
|
||||
terminal_width = shutil.get_terminal_size()[0]
|
||||
|
||||
print_results(hits, terminal_width=terminal_width)
|
||||
if pypi_hits:
|
||||
|
|
|
@ -11,13 +11,12 @@ Some terminology:
|
|||
A single word describing where the configuration key-value pair came from
|
||||
"""
|
||||
|
||||
import configparser
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pip._vendor.six.moves import configparser
|
||||
|
||||
from pip._internal.exceptions import (
|
||||
ConfigurationError,
|
||||
ConfigurationFileCouldNotBeLoaded,
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import abc
|
||||
|
||||
from pip._vendor.six import add_metaclass
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
|
@ -13,8 +11,7 @@ if MYPY_CHECK_RUNNING:
|
|||
from pip._internal.req import InstallRequirement
|
||||
|
||||
|
||||
@add_metaclass(abc.ABCMeta)
|
||||
class AbstractDistribution(object):
|
||||
class AbstractDistribution(object, metaclass=abc.ABCMeta):
|
||||
"""A base class for handling installable artifacts.
|
||||
|
||||
The requirements for anything installable are as follows:
|
||||
|
@ -29,7 +26,6 @@ class AbstractDistribution(object):
|
|||
- we must be able to create a Distribution object exposing the
|
||||
above metadata.
|
||||
"""
|
||||
|
||||
def __init__(self, req):
|
||||
# type: (InstallRequirement) -> None
|
||||
super(AbstractDistribution, self).__init__()
|
||||
|
|
|
@ -4,25 +4,18 @@ from __future__ import absolute_import
|
|||
|
||||
from itertools import chain, groupby, repeat
|
||||
|
||||
from pip._vendor.six import iteritems
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
import configparser
|
||||
from hashlib import _Hash
|
||||
from typing import Any, Dict, List, Optional, Text
|
||||
|
||||
from pip._vendor.pkg_resources import Distribution
|
||||
from pip._vendor.requests.models import Request, Response
|
||||
from pip._vendor.six import PY3
|
||||
from pip._vendor.six.moves import configparser
|
||||
|
||||
from pip._internal.req.req_install import InstallRequirement
|
||||
|
||||
if PY3:
|
||||
from hashlib import _Hash
|
||||
else:
|
||||
from hashlib import _hash as _Hash
|
||||
|
||||
|
||||
class PipError(Exception):
|
||||
"""Base pip exception"""
|
||||
|
@ -346,7 +339,7 @@ class HashMismatch(HashError):
|
|||
return chain([hash_name], repeat(' or'))
|
||||
|
||||
lines = [] # type: List[str]
|
||||
for hash_name, expecteds in iteritems(self.allowed):
|
||||
for hash_name, expecteds in self.allowed.items():
|
||||
prefix = hash_then_or(hash_name)
|
||||
lines.extend((' Expected {} {}'.format(next(prefix), e))
|
||||
for e in expecteds)
|
||||
|
|
|
@ -10,12 +10,12 @@ import mimetypes
|
|||
import os
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
from urllib import parse as urllib_parse
|
||||
from urllib import request as urllib_request
|
||||
|
||||
from pip._vendor import html5lib, requests
|
||||
from pip._vendor.distlib.compat import unescape
|
||||
from pip._vendor.requests.exceptions import RetryError, SSLError
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from pip._vendor.six.moves.urllib import request as urllib_request
|
||||
|
||||
from pip._internal.exceptions import NetworkConnectionError
|
||||
from pip._internal.models.link import Link
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
""" PEP 610 """
|
||||
import json
|
||||
import re
|
||||
|
||||
from pip._vendor import six
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
|
@ -35,8 +33,6 @@ def _get(d, expected_type, key, default=None):
|
|||
if key not in d:
|
||||
return default
|
||||
value = d[key]
|
||||
if six.PY2 and expected_type is str:
|
||||
expected_type = six.string_types # type: ignore
|
||||
if not isinstance(value, expected_type):
|
||||
raise DirectUrlValidationError(
|
||||
"{!r} has unexpected type for {} (expected {})".format(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
|
||||
class PackageIndex(object):
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import os
|
||||
import posixpath
|
||||
import re
|
||||
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.utils.filetypes import WHEEL_EXTENSION
|
||||
from pip._internal.utils.misc import (
|
||||
|
|
|
@ -2,9 +2,9 @@ import itertools
|
|||
import logging
|
||||
import os
|
||||
import posixpath
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.models.index import PyPI
|
||||
from pip._internal.utils.compat import has_tls
|
||||
|
|
|
@ -5,10 +5,10 @@ providing credentials in the context of network requests.
|
|||
"""
|
||||
|
||||
import logging
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth
|
||||
from pip._vendor.requests.utils import get_netrc_auth
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.utils.misc import (
|
||||
ask,
|
||||
|
|
|
@ -8,7 +8,6 @@ from tempfile import NamedTemporaryFile
|
|||
from zipfile import BadZipfile, ZipFile
|
||||
|
||||
from pip._vendor.requests.models import CONTENT_CHUNK_SIZE
|
||||
from pip._vendor.six.moves import range
|
||||
|
||||
from pip._internal.network.utils import HEADERS, raise_for_status, response_chunks
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
|
|
@ -13,13 +13,13 @@ import os
|
|||
import platform
|
||||
import sys
|
||||
import warnings
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._vendor import requests, six, urllib3
|
||||
from pip._vendor.cachecontrol import CacheControlAdapter
|
||||
from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter
|
||||
from pip._vendor.requests.models import Response
|
||||
from pip._vendor.requests.structures import CaseInsensitiveDict
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from pip._vendor.urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
from pip import __version__
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
"""
|
||||
|
||||
import logging
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is
|
||||
# why we ignore the type on this import
|
||||
from pip._vendor.six.moves import xmlrpc_client # type: ignore
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.exceptions import NetworkConnectionError
|
||||
from pip._internal.network.utils import raise_for_status
|
||||
|
|
|
@ -4,7 +4,6 @@ import collections
|
|||
import logging
|
||||
import os
|
||||
|
||||
from pip._vendor import six
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
from pip._vendor.pkg_resources import RequirementParseError
|
||||
|
||||
|
@ -162,7 +161,7 @@ def freeze(
|
|||
|
||||
# Warn about requirements that were included multiple times (in a
|
||||
# single requirements file or in different requirements files).
|
||||
for name, files in six.iteritems(req_files):
|
||||
for name, files in req_files.items():
|
||||
if len(files) > 1:
|
||||
logger.warning("Requirement %s included multiple times [%s]",
|
||||
name, ', '.join(sorted(set(files))))
|
||||
|
|
|
@ -15,14 +15,13 @@ import shutil
|
|||
import sys
|
||||
import warnings
|
||||
from base64 import urlsafe_b64encode
|
||||
from itertools import chain, starmap
|
||||
from itertools import chain, filterfalse, starmap
|
||||
from zipfile import ZipFile
|
||||
|
||||
from pip._vendor import pkg_resources
|
||||
from pip._vendor.distlib.scripts import ScriptMaker
|
||||
from pip._vendor.distlib.util import get_export_entry
|
||||
from pip._vendor.six import PY2, ensure_str, ensure_text, itervalues, reraise, text_type
|
||||
from pip._vendor.six.moves import filterfalse, map
|
||||
from pip._vendor.six import ensure_str, ensure_text, reraise
|
||||
|
||||
from pip._internal.exceptions import InstallationError
|
||||
from pip._internal.locations import get_major_minor_version
|
||||
|
@ -70,12 +69,12 @@ else:
|
|||
from pip._internal.models.scheme import Scheme
|
||||
from pip._internal.utils.filesystem import NamedTemporaryFileResult
|
||||
|
||||
RecordPath = NewType('RecordPath', text_type)
|
||||
RecordPath = NewType('RecordPath', str)
|
||||
InstalledCSVRow = Tuple[RecordPath, str, Union[int, str]]
|
||||
|
||||
class File(Protocol):
|
||||
src_record_path = None # type: RecordPath
|
||||
dest_path = None # type: text_type
|
||||
dest_path = None # type: str
|
||||
changed = None # type: bool
|
||||
|
||||
def save(self):
|
||||
|
@ -87,7 +86,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def rehash(path, blocksize=1 << 20):
|
||||
# type: (text_type, int) -> Tuple[str, str]
|
||||
# type: (str, int) -> Tuple[str, str]
|
||||
"""Return (encoded_digest, length) for path using hashlib.sha256()"""
|
||||
h, length = hash_file(path, blocksize)
|
||||
digest = 'sha256=' + urlsafe_b64encode(
|
||||
|
@ -102,14 +101,11 @@ def csv_io_kwargs(mode):
|
|||
"""Return keyword arguments to properly open a CSV file
|
||||
in the given mode.
|
||||
"""
|
||||
if PY2:
|
||||
return {'mode': '{}b'.format(mode)}
|
||||
else:
|
||||
return {'mode': mode, 'newline': '', 'encoding': 'utf-8'}
|
||||
return {'mode': mode, 'newline': '', 'encoding': 'utf-8'}
|
||||
|
||||
|
||||
def fix_script(path):
|
||||
# type: (text_type) -> bool
|
||||
# type: (str) -> bool
|
||||
"""Replace #!python with #!/path/to/python
|
||||
Return True if file was changed.
|
||||
"""
|
||||
|
@ -257,12 +253,12 @@ def _normalized_outrows(outrows):
|
|||
|
||||
|
||||
def _record_to_fs_path(record_path):
|
||||
# type: (RecordPath) -> text_type
|
||||
# type: (RecordPath) -> str
|
||||
return record_path
|
||||
|
||||
|
||||
def _fs_to_record_path(path, relative_to=None):
|
||||
# type: (text_type, Optional[text_type]) -> RecordPath
|
||||
# type: (str, Optional[str]) -> RecordPath
|
||||
if relative_to is not None:
|
||||
# On Windows, do not handle relative paths if they belong to different
|
||||
# logical disks
|
||||
|
@ -307,7 +303,7 @@ def get_csv_rows_for_installed(
|
|||
path = _fs_to_record_path(f, lib_dir)
|
||||
digest, length = rehash(f)
|
||||
installed_rows.append((path, digest, length))
|
||||
for installed_record_path in itervalues(installed):
|
||||
for installed_record_path in installed.values():
|
||||
installed_rows.append((installed_record_path, '', ''))
|
||||
return installed_rows
|
||||
|
||||
|
@ -400,7 +396,7 @@ def get_console_script_specs(console):
|
|||
|
||||
class ZipBackedFile(object):
|
||||
def __init__(self, src_record_path, dest_path, zip_file):
|
||||
# type: (RecordPath, text_type, ZipFile) -> None
|
||||
# type: (RecordPath, str, ZipFile) -> None
|
||||
self.src_record_path = src_record_path
|
||||
self.dest_path = dest_path
|
||||
self._zip_file = zip_file
|
||||
|
@ -408,12 +404,7 @@ class ZipBackedFile(object):
|
|||
|
||||
def _getinfo(self):
|
||||
# type: () -> ZipInfo
|
||||
if not PY2:
|
||||
return self._zip_file.getinfo(self.src_record_path)
|
||||
# Python 2 does not expose a way to detect a ZIP's encoding, but the
|
||||
# wheel specification (PEP 427) explicitly mandates that paths should
|
||||
# use UTF-8, so we assume it is true.
|
||||
return self._zip_file.getinfo(self.src_record_path.encode("utf-8"))
|
||||
return self._zip_file.getinfo(self.src_record_path)
|
||||
|
||||
def save(self):
|
||||
# type: () -> None
|
||||
|
@ -525,7 +516,7 @@ def _install_wheel(
|
|||
generated = [] # type: List[str]
|
||||
|
||||
def record_installed(srcfile, destfile, modified=False):
|
||||
# type: (RecordPath, text_type, bool) -> None
|
||||
# type: (RecordPath, str, bool) -> None
|
||||
"""Map archive RECORD paths to installation RECORD paths."""
|
||||
newpath = _fs_to_record_path(destfile, lib_dir)
|
||||
installed[srcfile] = newpath
|
||||
|
@ -546,7 +537,7 @@ def _install_wheel(
|
|||
return path.endswith("/")
|
||||
|
||||
def assert_no_path_traversal(dest_dir_path, target_path):
|
||||
# type: (text_type, text_type) -> None
|
||||
# type: (str, str) -> None
|
||||
if not is_within_directory(dest_dir_path, target_path):
|
||||
message = (
|
||||
"The wheel {!r} has a file {!r} trying to install"
|
||||
|
@ -557,7 +548,7 @@ def _install_wheel(
|
|||
)
|
||||
|
||||
def root_scheme_file_maker(zip_file, dest):
|
||||
# type: (ZipFile, text_type) -> Callable[[RecordPath], File]
|
||||
# type: (ZipFile, str) -> Callable[[RecordPath], File]
|
||||
def make_root_scheme_file(record_path):
|
||||
# type: (RecordPath) -> File
|
||||
normed_path = os.path.normpath(record_path)
|
||||
|
@ -675,7 +666,7 @@ def _install_wheel(
|
|||
record_installed(file.src_record_path, file.dest_path, file.changed)
|
||||
|
||||
def pyc_source_file_paths():
|
||||
# type: () -> Iterator[text_type]
|
||||
# type: () -> Iterator[str]
|
||||
# We de-duplicate installation paths, since there can be overlap (e.g.
|
||||
# file in .data maps to same location as file in wheel root).
|
||||
# Sorting installation paths makes it easier to reproduce and debug
|
||||
|
@ -689,16 +680,10 @@ def _install_wheel(
|
|||
yield full_installed_path
|
||||
|
||||
def pyc_output_path(path):
|
||||
# type: (text_type) -> text_type
|
||||
# type: (str) -> str
|
||||
"""Return the path the pyc file would have been written to.
|
||||
"""
|
||||
if PY2:
|
||||
if sys.flags.optimize:
|
||||
return path + 'o'
|
||||
else:
|
||||
return path + 'c'
|
||||
else:
|
||||
return importlib.util.cache_from_source(path)
|
||||
return importlib.util.cache_from_source(path)
|
||||
|
||||
# Compile all of the pyc files for the installed files
|
||||
if pycompile:
|
||||
|
|
|
@ -10,7 +10,6 @@ import os
|
|||
import shutil
|
||||
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.distributions import make_distribution_for_install_requirement
|
||||
from pip._internal.distributions.installed import InstalledDistribution
|
||||
|
@ -51,26 +50,16 @@ if MYPY_CHECK_RUNNING:
|
|||
from pip._internal.req.req_tracker import RequirementTracker
|
||||
from pip._internal.utils.hashes import Hashes
|
||||
|
||||
if PY2:
|
||||
CopytreeKwargs = TypedDict(
|
||||
'CopytreeKwargs',
|
||||
{
|
||||
'ignore': Callable[[str, List[str]], List[str]],
|
||||
'symlinks': bool,
|
||||
},
|
||||
total=False,
|
||||
)
|
||||
else:
|
||||
CopytreeKwargs = TypedDict(
|
||||
'CopytreeKwargs',
|
||||
{
|
||||
'copy_function': Callable[[str, str], None],
|
||||
'ignore': Callable[[str, List[str]], List[str]],
|
||||
'ignore_dangling_symlinks': bool,
|
||||
'symlinks': bool,
|
||||
},
|
||||
total=False,
|
||||
)
|
||||
CopytreeKwargs = TypedDict(
|
||||
'CopytreeKwargs',
|
||||
{
|
||||
'copy_function': Callable[[str, str], None],
|
||||
'ignore': Callable[[str, List[str]], List[str]],
|
||||
'ignore_dangling_symlinks': bool,
|
||||
'symlinks': bool,
|
||||
},
|
||||
total=False,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -177,14 +166,13 @@ def _copy_source_tree(source, target):
|
|||
skipped += [target_basename]
|
||||
return skipped
|
||||
|
||||
kwargs = dict(ignore=ignore, symlinks=True) # type: CopytreeKwargs
|
||||
|
||||
if not PY2:
|
||||
# Python 2 does not support copy_function, so we only ignore
|
||||
# errors on special file copy in Python 3.
|
||||
kwargs['copy_function'] = _copy2_ignoring_special_files
|
||||
|
||||
shutil.copytree(source, target, **kwargs)
|
||||
shutil.copytree(
|
||||
source,
|
||||
target,
|
||||
ignore=ignore,
|
||||
symlinks=True,
|
||||
copy_function=_copy2_ignoring_special_files,
|
||||
)
|
||||
|
||||
|
||||
def get_file_url(
|
||||
|
|
|
@ -2,10 +2,9 @@ from __future__ import absolute_import
|
|||
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
|
||||
from pip._vendor import six, toml
|
||||
from pip._vendor import toml
|
||||
from pip._vendor.packaging.requirements import InvalidRequirement, Requirement
|
||||
|
||||
from pip._internal.exceptions import InstallationError
|
||||
|
@ -19,19 +18,13 @@ def _is_list_of_str(obj):
|
|||
# type: (Any) -> bool
|
||||
return (
|
||||
isinstance(obj, list) and
|
||||
all(isinstance(item, six.string_types) for item in obj)
|
||||
all(isinstance(item, str) for item in obj)
|
||||
)
|
||||
|
||||
|
||||
def make_pyproject_path(unpacked_source_directory):
|
||||
# type: (str) -> str
|
||||
path = os.path.join(unpacked_source_directory, 'pyproject.toml')
|
||||
|
||||
# Python2 __file__ should not be unicode
|
||||
if six.PY2 and isinstance(path, six.text_type):
|
||||
path = path.encode(sys.getfilesystemencoding())
|
||||
|
||||
return path
|
||||
return os.path.join(unpacked_source_directory, 'pyproject.toml')
|
||||
|
||||
|
||||
BuildSystemDetails = namedtuple('BuildSystemDetails', [
|
||||
|
|
|
@ -8,9 +8,7 @@ import optparse
|
|||
import os
|
||||
import re
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.exceptions import InstallationError, RequirementsFileParseError
|
||||
|
@ -410,10 +408,6 @@ def get_line_parser(finder):
|
|||
defaults.format_control = finder.format_control
|
||||
|
||||
args_str, options_str = break_args_options(line)
|
||||
# Prior to 2.7.3, shlex cannot deal with unicode entries
|
||||
if sys.version_info < (2, 7, 3):
|
||||
# https://github.com/python/mypy/issues/1174
|
||||
options_str = options_str.encode('utf8') # type: ignore
|
||||
|
||||
# https://github.com/python/mypy/issues/1174
|
||||
opts, _ = parser.parse_args(
|
||||
|
|
|
@ -223,7 +223,7 @@ class InstallRequirement(object):
|
|||
if self.satisfied_by is not None:
|
||||
s += ' in {}'.format(display_path(self.satisfied_by.location))
|
||||
if self.comes_from:
|
||||
if isinstance(self.comes_from, six.string_types):
|
||||
if isinstance(self.comes_from, str):
|
||||
comes_from = self.comes_from # type: Optional[str]
|
||||
else:
|
||||
comes_from = self.comes_from.from_path()
|
||||
|
@ -334,7 +334,7 @@ class InstallRequirement(object):
|
|||
return None
|
||||
s = str(self.req)
|
||||
if self.comes_from:
|
||||
if isinstance(self.comes_from, six.string_types):
|
||||
if isinstance(self.comes_from, str):
|
||||
comes_from = self.comes_from
|
||||
else:
|
||||
comes_from = self.comes_from.from_path()
|
||||
|
@ -480,10 +480,6 @@ class InstallRequirement(object):
|
|||
assert self.source_dir, "No source dir for {}".format(self)
|
||||
setup_py = os.path.join(self.unpacked_source_directory, 'setup.py')
|
||||
|
||||
# Python2 __file__ should not be unicode
|
||||
if six.PY2 and isinstance(setup_py, six.text_type):
|
||||
setup_py = setup_py.encode(sys.getfilesystemencoding())
|
||||
|
||||
return setup_py
|
||||
|
||||
@property
|
||||
|
|
|
@ -6,12 +6,13 @@ import logging
|
|||
import os
|
||||
import sys
|
||||
import sysconfig
|
||||
from importlib.util import cache_from_source
|
||||
|
||||
from pip._vendor import pkg_resources
|
||||
|
||||
from pip._internal.exceptions import UninstallationError
|
||||
from pip._internal.locations import bin_py, bin_user
|
||||
from pip._internal.utils.compat import WINDOWS, cache_from_source, uses_pycache
|
||||
from pip._internal.utils.compat import WINDOWS
|
||||
from pip._internal.utils.logging import indent_log
|
||||
from pip._internal.utils.misc import (
|
||||
FakeFile,
|
||||
|
@ -363,7 +364,7 @@ class UninstallPathSet(object):
|
|||
|
||||
# __pycache__ files can show up after 'installed-files.txt' is created,
|
||||
# due to imports
|
||||
if os.path.splitext(path)[1] == '.py' and uses_pycache:
|
||||
if os.path.splitext(path)[1] == '.py':
|
||||
self.add(cache_from_source(path))
|
||||
|
||||
def add_pth(self, pth_file, entry):
|
||||
|
@ -609,7 +610,7 @@ class UninstallPthEntries(object):
|
|||
# treats non-absolute paths with drive letter markings like c:foo\bar
|
||||
# as absolute paths. It also does not recognize UNC paths if they don't
|
||||
# have more than "\\sever\share". Valid examples: "\\server\share\" or
|
||||
# "\\server\share\folder". Python 2.7.8+ support UNC in splitdrive.
|
||||
# "\\server\share\folder".
|
||||
if WINDOWS and not os.path.splitdrive(entry)[0]:
|
||||
entry = entry.replace('\\', '/')
|
||||
self.entries.add(entry)
|
||||
|
|
|
@ -11,15 +11,12 @@ import functools
|
|||
import locale
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from pip._vendor.six import PY2, text_type
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Callable, Optional, Protocol, Text, Tuple, TypeVar, Union
|
||||
from typing import Callable, Optional, Protocol, Text, TypeVar, Union
|
||||
|
||||
# Used in the @lru_cache polyfill.
|
||||
F = TypeVar('F')
|
||||
|
@ -41,47 +38,13 @@ except ImportError:
|
|||
|
||||
|
||||
__all__ = [
|
||||
"ipaddress", "uses_pycache", "console_to_str",
|
||||
"get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size",
|
||||
"ipaddress", "console_to_str",
|
||||
"get_path_uid", "stdlib_pkgs", "WINDOWS",
|
||||
]
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
if PY2:
|
||||
import imp
|
||||
|
||||
try:
|
||||
cache_from_source = imp.cache_from_source # type: ignore
|
||||
except AttributeError:
|
||||
# does not use __pycache__
|
||||
cache_from_source = None
|
||||
|
||||
uses_pycache = cache_from_source is not None
|
||||
else:
|
||||
uses_pycache = True
|
||||
from importlib.util import cache_from_source
|
||||
|
||||
|
||||
if PY2:
|
||||
# In Python 2.7, backslashreplace exists
|
||||
# but does not support use for decoding.
|
||||
# We implement our own replace handler for this
|
||||
# situation, so that we can consistently use
|
||||
# backslash replacement for all versions.
|
||||
def backslashreplace_decode_fn(err):
|
||||
raw_bytes = (err.object[i] for i in range(err.start, err.end))
|
||||
# Python 2 gave us characters - convert to numeric bytes
|
||||
raw_bytes = (ord(b) for b in raw_bytes)
|
||||
return u"".join(map(u"\\x{:x}".format, raw_bytes)), err.end
|
||||
codecs.register_error(
|
||||
"backslashreplace_decode",
|
||||
backslashreplace_decode_fn,
|
||||
)
|
||||
backslashreplace_decode = "backslashreplace_decode"
|
||||
else:
|
||||
backslashreplace_decode = "backslashreplace"
|
||||
|
||||
|
||||
def has_tls():
|
||||
# type: () -> bool
|
||||
|
@ -114,7 +77,7 @@ def str_to_display(data, desc=None):
|
|||
We also ensure that the output can be safely written to standard output
|
||||
without encoding errors.
|
||||
"""
|
||||
if isinstance(data, text_type):
|
||||
if isinstance(data, str):
|
||||
return data
|
||||
|
||||
# Otherwise, data is a bytes object (str in Python 2).
|
||||
|
@ -135,7 +98,7 @@ def str_to_display(data, desc=None):
|
|||
desc or 'Bytes object',
|
||||
encoding,
|
||||
)
|
||||
decoded_data = data.decode(encoding, errors=backslashreplace_decode)
|
||||
decoded_data = data.decode(encoding, errors="backslashreplace")
|
||||
|
||||
# Make sure we can print the output, by encoding it to the output
|
||||
# encoding with replacement of unencodable characters, and then
|
||||
|
@ -226,60 +189,6 @@ WINDOWS = (sys.platform.startswith("win") or
|
|||
(sys.platform == 'cli' and os.name == 'nt'))
|
||||
|
||||
|
||||
def samefile(file1, file2):
|
||||
# type: (str, str) -> bool
|
||||
"""Provide an alternative for os.path.samefile on Windows/Python2"""
|
||||
if hasattr(os.path, 'samefile'):
|
||||
return os.path.samefile(file1, file2)
|
||||
else:
|
||||
path1 = os.path.normcase(os.path.abspath(file1))
|
||||
path2 = os.path.normcase(os.path.abspath(file2))
|
||||
return path1 == path2
|
||||
|
||||
|
||||
if hasattr(shutil, 'get_terminal_size'):
|
||||
def get_terminal_size():
|
||||
# type: () -> Tuple[int, int]
|
||||
"""
|
||||
Returns a tuple (x, y) representing the width(x) and the height(y)
|
||||
in characters of the terminal window.
|
||||
"""
|
||||
return tuple(shutil.get_terminal_size()) # type: ignore
|
||||
else:
|
||||
def get_terminal_size():
|
||||
# type: () -> Tuple[int, int]
|
||||
"""
|
||||
Returns a tuple (x, y) representing the width(x) and the height(y)
|
||||
in characters of the terminal window.
|
||||
"""
|
||||
def ioctl_GWINSZ(fd):
|
||||
try:
|
||||
import fcntl
|
||||
import struct
|
||||
import termios
|
||||
cr = struct.unpack_from(
|
||||
'hh',
|
||||
fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678')
|
||||
)
|
||||
except Exception:
|
||||
return None
|
||||
if cr == (0, 0):
|
||||
return None
|
||||
return cr
|
||||
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
|
||||
if not cr:
|
||||
if sys.platform != "win32":
|
||||
try:
|
||||
fd = os.open(os.ctermid(), os.O_RDONLY)
|
||||
cr = ioctl_GWINSZ(fd)
|
||||
os.close(fd)
|
||||
except Exception:
|
||||
pass
|
||||
if not cr:
|
||||
cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80))
|
||||
return int(cr[1]), int(cr[0])
|
||||
|
||||
|
||||
# Fallback to noop_lru_cache in Python 2
|
||||
# TODO: this can be removed when python 2 support is dropped!
|
||||
def noop_lru_cache(maxsize=None):
|
||||
|
|
|
@ -12,7 +12,6 @@ from tempfile import NamedTemporaryFile
|
|||
# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is
|
||||
# why we ignore the type on this import.
|
||||
from pip._vendor.retrying import retry # type: ignore
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.utils.compat import get_path_uid
|
||||
from pip._internal.utils.misc import format_size
|
||||
|
@ -114,18 +113,7 @@ def adjacent_tmp_file(path, **kwargs):
|
|||
|
||||
_replace_retry = retry(stop_max_delay=1000, wait_fixed=250)
|
||||
|
||||
if PY2:
|
||||
@_replace_retry
|
||||
def replace(src, dest):
|
||||
# type: (str, str) -> None
|
||||
try:
|
||||
os.rename(src, dest)
|
||||
except OSError:
|
||||
os.remove(dest)
|
||||
os.rename(src, dest)
|
||||
|
||||
else:
|
||||
replace = _replace_retry(os.replace)
|
||||
replace = _replace_retry(os.replace)
|
||||
|
||||
|
||||
# test_writable_dir and _test_writable_dir_win are copied from Flit,
|
||||
|
|
|
@ -2,21 +2,14 @@ from __future__ import absolute_import
|
|||
|
||||
import hashlib
|
||||
|
||||
from pip._vendor.six import iteritems, iterkeys, itervalues
|
||||
|
||||
from pip._internal.exceptions import HashMismatch, HashMissing, InstallationError
|
||||
from pip._internal.utils.misc import read_chunks
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from hashlib import _Hash
|
||||
from typing import BinaryIO, Dict, Iterator, List, NoReturn
|
||||
|
||||
from pip._vendor.six import PY3
|
||||
if PY3:
|
||||
from hashlib import _Hash
|
||||
else:
|
||||
from hashlib import _hash as _Hash
|
||||
|
||||
|
||||
# The recommended hash algo of the moment. Change this whenever the state of
|
||||
# the art changes; it won't hurt backward compatibility.
|
||||
|
@ -60,7 +53,7 @@ class Hashes(object):
|
|||
|
||||
# Otherwise only hashes that present in both objects are allowed.
|
||||
new = {}
|
||||
for alg, values in iteritems(other._allowed):
|
||||
for alg, values in other._allowed.items():
|
||||
if alg not in self._allowed:
|
||||
continue
|
||||
new[alg] = [v for v in values if v in self._allowed[alg]]
|
||||
|
@ -89,7 +82,7 @@ class Hashes(object):
|
|||
|
||||
"""
|
||||
gots = {}
|
||||
for hash_name in iterkeys(self._allowed):
|
||||
for hash_name in self._allowed.keys():
|
||||
try:
|
||||
gots[hash_name] = hashlib.new(hash_name)
|
||||
except (ValueError, TypeError):
|
||||
|
@ -98,10 +91,10 @@ class Hashes(object):
|
|||
)
|
||||
|
||||
for chunk in chunks:
|
||||
for hash in itervalues(gots):
|
||||
for hash in gots.values():
|
||||
hash.update(chunk)
|
||||
|
||||
for hash_name, got in iteritems(gots):
|
||||
for hash_name, got in gots.items():
|
||||
if got.hexdigest() in self._allowed[hash_name]:
|
||||
return
|
||||
self._raise(gots)
|
||||
|
|
|
@ -11,8 +11,6 @@ import os
|
|||
import sys
|
||||
from logging import Filter, getLogger
|
||||
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.utils.compat import WINDOWS
|
||||
from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX
|
||||
from pip._internal.utils.misc import ensure_dir
|
||||
|
@ -62,30 +60,18 @@ class BrokenStdoutLoggingError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
# BrokenPipeError does not exist in Python 2 and, in addition, manifests
|
||||
# differently in Windows and non-Windows.
|
||||
# BrokenPipeError 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)
|
||||
"""See the docstring for non-Windows below."""
|
||||
return ((exc_class is BrokenPipeError) or # noqa: F821
|
||||
(exc_class is OSError and
|
||||
exc.errno in (errno.EINVAL, errno.EPIPE)))
|
||||
else:
|
||||
# Then we are in the non-Windows Python 3 case.
|
||||
# Then we are in the non-Windows case.
|
||||
def _is_broken_pipe_error(exc_class, exc):
|
||||
"""
|
||||
Return whether an exception is a broken pipe error.
|
||||
|
|
|
@ -16,7 +16,10 @@ import shutil
|
|||
import stat
|
||||
import sys
|
||||
from collections import deque
|
||||
from itertools import tee
|
||||
from io import StringIO
|
||||
from itertools import filterfalse, tee, zip_longest
|
||||
from urllib import parse as urllib_parse
|
||||
from urllib.parse import unquote as urllib_unquote
|
||||
|
||||
from pip._vendor import pkg_resources
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
|
@ -24,26 +27,17 @@ from pip._vendor.packaging.utils import canonicalize_name
|
|||
# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is
|
||||
# why we ignore the type on this import.
|
||||
from pip._vendor.retrying import retry # type: ignore
|
||||
from pip._vendor.six import PY2, text_type
|
||||
from pip._vendor.six.moves import filter, filterfalse, input, map, zip_longest
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote
|
||||
|
||||
from pip import __version__
|
||||
from pip._internal.exceptions import CommandError
|
||||
from pip._internal.locations import get_major_minor_version, site_packages, user_site
|
||||
from pip._internal.utils.compat import WINDOWS, expanduser, stdlib_pkgs, str_to_display
|
||||
from pip._internal.utils.compat import WINDOWS, expanduser, stdlib_pkgs
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast
|
||||
from pip._internal.utils.virtualenv import (
|
||||
running_under_virtualenv,
|
||||
virtualenv_no_global,
|
||||
)
|
||||
|
||||
if PY2:
|
||||
from io import BytesIO as StringIO
|
||||
else:
|
||||
from io import StringIO
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import (
|
||||
Any,
|
||||
|
@ -173,7 +167,7 @@ def path_to_display(path):
|
|||
"""
|
||||
if path is None:
|
||||
return None
|
||||
if isinstance(path, text_type):
|
||||
if isinstance(path, str):
|
||||
return path
|
||||
# Otherwise, path is a bytes object (str in Python 2).
|
||||
try:
|
||||
|
@ -181,17 +175,9 @@ def path_to_display(path):
|
|||
except UnicodeDecodeError:
|
||||
# Include the full bytes to make troubleshooting easier, even though
|
||||
# it may not be very human readable.
|
||||
if PY2:
|
||||
# Convert the bytes to a readable str representation using
|
||||
# repr(), and then convert the str to unicode.
|
||||
# Also, we add the prefix "b" to the repr() return value both
|
||||
# to make the Python 2 output look like the Python 3 output, and
|
||||
# to signal to the user that this is a bytes representation.
|
||||
display_path = str_to_display('b{!r}'.format(path))
|
||||
else:
|
||||
# Silence the "F821 undefined name 'ascii'" flake8 error since
|
||||
# in Python 3 ascii() is a built-in.
|
||||
display_path = ascii(path) # noqa: F821
|
||||
# Silence the "F821 undefined name 'ascii'" flake8 error since
|
||||
# ascii() is a built-in.
|
||||
display_path = ascii(path) # noqa: F821
|
||||
|
||||
return display_path
|
||||
|
||||
|
@ -201,9 +187,6 @@ def display_path(path):
|
|||
"""Gives the display value for a given path, making it relative to cwd
|
||||
if possible."""
|
||||
path = os.path.normcase(os.path.abspath(path))
|
||||
if sys.version_info[0] == 2:
|
||||
path = path.decode(sys.getfilesystemencoding(), 'replace')
|
||||
path = path.encode(sys.getdefaultencoding(), 'replace')
|
||||
if path.startswith(os.getcwd() + os.path.sep):
|
||||
path = '.' + path[len(os.getcwd()):]
|
||||
return path
|
||||
|
@ -854,12 +837,6 @@ class HiddenText(object):
|
|||
# just the raw, original string.
|
||||
return (self.secret == other.secret)
|
||||
|
||||
# We need to provide an explicit __ne__ implementation for Python 2.
|
||||
# TODO: remove this when we drop PY2 support.
|
||||
def __ne__(self, other):
|
||||
# type: (Any) -> bool
|
||||
return not self == other
|
||||
|
||||
|
||||
def hide_value(value):
|
||||
# type: (str) -> HiddenText
|
||||
|
|
|
@ -23,8 +23,6 @@ from multiprocessing import Pool as ProcessPool
|
|||
from multiprocessing.dummy import Pool as ThreadPool
|
||||
|
||||
from pip._vendor.requests.adapters import DEFAULT_POOLSIZE
|
||||
from pip._vendor.six import PY2
|
||||
from pip._vendor.six.moves import map
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
|
@ -100,7 +98,7 @@ def _map_multithread(func, iterable, chunksize=1):
|
|||
return pool.imap_unordered(func, iterable, chunksize)
|
||||
|
||||
|
||||
if LACK_SEM_OPEN or PY2:
|
||||
if LACK_SEM_OPEN:
|
||||
map_multiprocess = map_multithread = _map_fallback
|
||||
else:
|
||||
map_multiprocess = _map_multiprocess
|
||||
|
|
|
@ -2,10 +2,9 @@ from __future__ import absolute_import
|
|||
|
||||
import logging
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
from pip._vendor.six.moves import shlex_quote
|
||||
|
||||
from pip._internal.cli.spinners import SpinnerInterface, open_spinner
|
||||
from pip._internal.exceptions import InstallationError
|
||||
from pip._internal.utils.compat import console_to_str, str_to_display
|
||||
|
@ -51,8 +50,8 @@ def format_command_args(args):
|
|||
# has type unicode and includes a non-ascii character. (The type
|
||||
# checker doesn't ensure the annotations are correct in all cases.)
|
||||
return ' '.join(
|
||||
shlex_quote(str(arg)) if isinstance(arg, HiddenText)
|
||||
else shlex_quote(arg) for arg in args
|
||||
shlex.quote(str(arg)) if isinstance(arg, HiddenText)
|
||||
else shlex.quote(arg) for arg in args
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from pip._vendor.six.moves.urllib import request as urllib_request
|
||||
from urllib import parse as urllib_parse
|
||||
from urllib import request as urllib_request
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@ from __future__ import absolute_import
|
|||
|
||||
import logging
|
||||
from email.parser import Parser
|
||||
from zipfile import ZipFile
|
||||
from zipfile import BadZipFile, ZipFile
|
||||
|
||||
from pip._vendor.packaging.utils import canonicalize_name
|
||||
from pip._vendor.pkg_resources import DistInfoDistribution
|
||||
from pip._vendor.six import PY2, ensure_str
|
||||
from pip._vendor.six import ensure_str
|
||||
|
||||
from pip._internal.exceptions import UnsupportedWheel
|
||||
from pip._internal.utils.pkg_resources import DictMetadata
|
||||
|
@ -21,11 +21,6 @@ if MYPY_CHECK_RUNNING:
|
|||
|
||||
from pip._vendor.pkg_resources import Distribution
|
||||
|
||||
if PY2:
|
||||
from zipfile import BadZipfile as BadZipFile
|
||||
else:
|
||||
from zipfile import BadZipFile
|
||||
|
||||
|
||||
VERSION_COMPATIBLE = (1, 0)
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@ from __future__ import absolute_import
|
|||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.utils.misc import display_path, rmtree
|
||||
from pip._internal.utils.subprocess import make_command
|
||||
|
|
|
@ -6,10 +6,10 @@ from __future__ import absolute_import
|
|||
import logging
|
||||
import os.path
|
||||
import re
|
||||
from urllib import parse as urllib_parse
|
||||
from urllib import request as urllib_request
|
||||
|
||||
from pip._vendor.packaging.version import parse as parse_version
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from pip._vendor.six.moves.urllib import request as urllib_request
|
||||
|
||||
from pip._internal.exceptions import BadCommand, SubProcessError
|
||||
from pip._internal.utils.misc import display_path, hide_url
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import configparser
|
||||
import logging
|
||||
import os
|
||||
|
||||
from pip._vendor.six.moves import configparser
|
||||
|
||||
from pip._internal.exceptions import BadCommand, SubProcessError
|
||||
from pip._internal.utils.misc import display_path
|
||||
from pip._internal.utils.subprocess import make_command
|
||||
|
|
|
@ -8,12 +8,12 @@ import os
|
|||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
from pip._vendor import pkg_resources
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
|
||||
from pip._internal.exceptions import BadCommand, InstallationError, SubProcessError
|
||||
from pip._internal.utils.compat import console_to_str, samefile
|
||||
from pip._internal.utils.compat import console_to_str
|
||||
from pip._internal.utils.logging import subprocess_logger
|
||||
from pip._internal.utils.misc import (
|
||||
ask_path_exists,
|
||||
|
@ -197,7 +197,7 @@ def find_path_to_setup_from_repo_root(location, repo_root):
|
|||
)
|
||||
return None
|
||||
|
||||
if samefile(repo_root, location):
|
||||
if os.path.samefile(repo_root, location):
|
||||
return None
|
||||
|
||||
return os.path.relpath(location, repo_root)
|
||||
|
@ -289,9 +289,7 @@ class VcsSupport(object):
|
|||
# Register more schemes with urlparse for various version control
|
||||
# systems
|
||||
urllib_parse.uses_netloc.extend(self.schemes)
|
||||
# Python >= 2.7.4, 3.3 doesn't have uses_fragment
|
||||
if getattr(urllib_parse, 'uses_fragment', None):
|
||||
urllib_parse.uses_fragment.extend(self.schemes)
|
||||
urllib_parse.uses_fragment.extend(self.schemes)
|
||||
super(VcsSupport, self).__init__()
|
||||
|
||||
def __iter__(self):
|
||||
|
|
|
@ -10,7 +10,6 @@ import time
|
|||
from contextlib import contextmanager
|
||||
|
||||
import pytest
|
||||
import six
|
||||
from mock import patch
|
||||
from pip._vendor.contextlib2 import ExitStack, nullcontext
|
||||
from setuptools.wheel import Wheel
|
||||
|
@ -73,15 +72,14 @@ def pytest_collection_modifyitems(config, items):
|
|||
if item.get_closest_marker('network') is not None:
|
||||
item.add_marker(pytest.mark.flaky(reruns=3, reruns_delay=2))
|
||||
|
||||
if six.PY3:
|
||||
if (item.get_closest_marker('incompatible_with_test_venv') and
|
||||
config.getoption("--use-venv")):
|
||||
item.add_marker(pytest.mark.skip(
|
||||
'Incompatible with test venv'))
|
||||
if (item.get_closest_marker('incompatible_with_venv') and
|
||||
sys.prefix != sys.base_prefix):
|
||||
item.add_marker(pytest.mark.skip(
|
||||
'Incompatible with venv'))
|
||||
if (item.get_closest_marker('incompatible_with_test_venv') and
|
||||
config.getoption("--use-venv")):
|
||||
item.add_marker(pytest.mark.skip(
|
||||
'Incompatible with test venv'))
|
||||
if (item.get_closest_marker('incompatible_with_venv') and
|
||||
sys.prefix != sys.base_prefix):
|
||||
item.add_marker(pytest.mark.skip(
|
||||
'Incompatible with venv'))
|
||||
|
||||
module_path = os.path.relpath(
|
||||
item.module.__file__,
|
||||
|
@ -111,16 +109,10 @@ def resolver_variant(request):
|
|||
features = set(os.environ.get("PIP_USE_FEATURE", "").split())
|
||||
deprecated_features = set(os.environ.get("PIP_USE_DEPRECATED", "").split())
|
||||
|
||||
if six.PY3:
|
||||
if resolver == "legacy":
|
||||
deprecated_features.add("legacy-resolver")
|
||||
else:
|
||||
deprecated_features.discard("legacy-resolver")
|
||||
if resolver == "legacy":
|
||||
deprecated_features.add("legacy-resolver")
|
||||
else:
|
||||
if resolver == "2020-resolver":
|
||||
features.add("2020-resolver")
|
||||
else:
|
||||
features.discard("2020-resolver")
|
||||
deprecated_features.discard("legacy-resolver")
|
||||
|
||||
env = {
|
||||
"PIP_USE_FEATURE": " ".join(features),
|
||||
|
@ -141,7 +133,7 @@ def tmpdir_factory(request, tmpdir_factory):
|
|||
# handle non-ASCII file names. This works around the problem by
|
||||
# passing a unicode object to rmtree().
|
||||
shutil.rmtree(
|
||||
six.text_type(tmpdir_factory.getbasetemp()),
|
||||
str(tmpdir_factory.getbasetemp()),
|
||||
ignore_errors=True,
|
||||
)
|
||||
|
||||
|
@ -166,7 +158,7 @@ def tmpdir(request, tmpdir):
|
|||
# py.path.remove() uses str paths on Python 2 and cannot
|
||||
# handle non-ASCII file names. This works around the problem by
|
||||
# passing a unicode object to rmtree().
|
||||
shutil.rmtree(six.text_type(tmpdir), ignore_errors=True)
|
||||
shutil.rmtree(str(tmpdir), ignore_errors=True)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
|
@ -337,7 +329,7 @@ def install_egg_link(venv, project_name, egg_info_dir):
|
|||
def virtualenv_template(request, tmpdir_factory, pip_src,
|
||||
setuptools_install, coverage_install):
|
||||
|
||||
if six.PY3 and request.config.getoption('--use-venv'):
|
||||
if request.config.getoption('--use-venv'):
|
||||
venv_type = 'venv'
|
||||
else:
|
||||
venv_type = 'virtualenv'
|
||||
|
@ -474,10 +466,7 @@ class InMemoryPipResult(object):
|
|||
class InMemoryPip(object):
|
||||
def pip(self, *args):
|
||||
orig_stdout = sys.stdout
|
||||
if six.PY3:
|
||||
stdout = io.StringIO()
|
||||
else:
|
||||
stdout = io.BytesIO()
|
||||
stdout = io.StringIO()
|
||||
sys.stdout = stdout
|
||||
try:
|
||||
returncode = pip_entry_point(list(args))
|
||||
|
|
|
@ -4,7 +4,6 @@ import textwrap
|
|||
from hashlib import sha256
|
||||
|
||||
import pytest
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.cli.status_codes import ERROR
|
||||
from pip._internal.utils.urls import path_to_url
|
||||
|
@ -490,7 +489,6 @@ def make_wheel_with_python_requires(script, package_name, python_requires):
|
|||
package_dir.joinpath('setup.py').write_text(text)
|
||||
script.run(
|
||||
'python', 'setup.py', 'bdist_wheel', '--universal', cwd=package_dir,
|
||||
allow_stderr_warning=PY2,
|
||||
)
|
||||
|
||||
file_name = '{}-1.0-py2.py3-none-any.whl'.format(package_name)
|
||||
|
|
|
@ -9,7 +9,6 @@ import textwrap
|
|||
from os.path import curdir, join, pardir
|
||||
|
||||
import pytest
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
||||
from pip._internal.models.index import PyPI, TestPyPI
|
||||
|
@ -26,8 +25,6 @@ from tests.lib import (
|
|||
pyversion,
|
||||
pyversion_tuple,
|
||||
requirements_file,
|
||||
skip_if_not_python2,
|
||||
skip_if_python2,
|
||||
windows_workaround_7667,
|
||||
)
|
||||
from tests.lib.filesystem import make_socket_file
|
||||
|
@ -658,22 +655,7 @@ def test_editable_install__local_dir_no_setup_py_with_pyproject(
|
|||
assert 'A "pyproject.toml" file was found' in msg
|
||||
|
||||
|
||||
@skip_if_not_python2
|
||||
@pytest.mark.xfail
|
||||
def test_install_argparse_shadowed(script):
|
||||
# When argparse is in the stdlib, we support installing it
|
||||
# even though that's pretty useless because older packages did need to
|
||||
# depend on it, and not having its metadata will cause pkg_resources
|
||||
# requirements checks to fail // trigger easy-install, both of which are
|
||||
# bad.
|
||||
# XXX: Note, this test hits the outside-environment check, not the
|
||||
# in-stdlib check, because our tests run in virtualenvs...
|
||||
result = script.pip('install', 'argparse>=1.4')
|
||||
assert "Not uninstalling argparse" in result.stdout
|
||||
|
||||
|
||||
@pytest.mark.network
|
||||
@skip_if_python2
|
||||
def test_upgrade_argparse_shadowed(script):
|
||||
# If argparse is installed - even if shadowed for imported - we support
|
||||
# upgrading it and properly remove the older versions files.
|
||||
|
@ -1568,7 +1550,7 @@ def test_install_incompatible_python_requires_wheel(script, with_wheel):
|
|||
"""))
|
||||
script.run(
|
||||
'python', 'setup.py', 'bdist_wheel', '--universal',
|
||||
cwd=pkga_path, allow_stderr_warning=PY2,
|
||||
cwd=pkga_path,
|
||||
)
|
||||
result = script.pip('install', './pkga/dist/pkga-0.1-py2.py3-none-any.whl',
|
||||
expect_error=True)
|
||||
|
@ -1837,7 +1819,6 @@ def test_install_yanked_file_and_print_warning(script, data):
|
|||
assert 'Successfully installed simple-3.0\n' in result.stdout, str(result)
|
||||
|
||||
|
||||
@skip_if_python2
|
||||
@pytest.mark.parametrize("install_args", [
|
||||
(),
|
||||
("--trusted-host", "localhost"),
|
||||
|
|
|
@ -5,7 +5,6 @@ import textwrap
|
|||
|
||||
import pytest
|
||||
|
||||
from tests.lib import skip_if_python2
|
||||
from tests.lib.server import (
|
||||
authorization_response,
|
||||
file_response,
|
||||
|
@ -130,7 +129,6 @@ def test_command_line_appends_correctly(script, data):
|
|||
), 'stdout: {}'.format(result.stdout)
|
||||
|
||||
|
||||
@skip_if_python2
|
||||
def test_config_file_override_stack(
|
||||
script, virtualenv, mock_server, shared_data
|
||||
):
|
||||
|
@ -249,7 +247,6 @@ def test_prompt_for_authentication(script, data, cert_factory):
|
|||
result.stdout, str(result)
|
||||
|
||||
|
||||
@skip_if_python2
|
||||
def test_do_not_prompt_for_authentication(script, data, cert_factory):
|
||||
"""Test behaviour if --no-input option is given while installing
|
||||
from a index url requiring authentication
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import os
|
||||
import textwrap
|
||||
|
||||
from pip._vendor.six.moves.urllib import parse as urllib_parse
|
||||
from urllib import parse as urllib_parse
|
||||
|
||||
|
||||
def test_find_links_relative_path(script, data, with_wheel):
|
||||
|
|
|
@ -8,7 +8,7 @@ import shutil
|
|||
|
||||
import pytest
|
||||
|
||||
from tests.lib import create_basic_wheel_for_package, skip_if_python2
|
||||
from tests.lib import create_basic_wheel_for_package
|
||||
from tests.lib.path import Path
|
||||
from tests.lib.wheel import make_wheel
|
||||
|
||||
|
@ -118,7 +118,6 @@ def test_basic_install_from_wheel_file(script, data):
|
|||
|
||||
# Installation seems to work, but scripttest fails to check.
|
||||
# I really don't care now since we're desupporting it soon anyway.
|
||||
@skip_if_python2
|
||||
def test_basic_install_from_unicode_wheel(script, data):
|
||||
"""
|
||||
Test installing from a wheel (that has a script)
|
||||
|
@ -394,8 +393,6 @@ def test_install_from_wheel_gen_uppercase_entrypoint(
|
|||
assert bool(os.access(script.base_path / wrapper_file, os.X_OK))
|
||||
|
||||
|
||||
# pkg_resources.EntryPoint() does not parse unicode correctly on Python 2.
|
||||
@skip_if_python2
|
||||
def test_install_from_wheel_gen_unicode_entrypoint(script):
|
||||
make_wheel(
|
||||
"script_wheel_unicode",
|
||||
|
@ -651,8 +648,6 @@ def test_wheel_installs_ok_with_badly_encoded_irrelevant_dist_info_file(
|
|||
)
|
||||
|
||||
|
||||
# Metadata is not decoded on Python 2.
|
||||
@skip_if_python2
|
||||
def test_wheel_install_fails_with_badly_encoded_metadata(script):
|
||||
package = create_basic_wheel_for_package(
|
||||
script,
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import platform
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.lib import skip_if_not_python2, skip_if_python2
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def warnings_demo(tmpdir):
|
||||
|
@ -37,33 +34,11 @@ DEPRECATION_TEXT = "drop support for Python 2.7"
|
|||
CPYTHON_DEPRECATION_TEXT = "January 1st, 2020"
|
||||
|
||||
|
||||
@skip_if_python2
|
||||
def test_version_warning_is_not_shown_if_python_version_is_not_2(script):
|
||||
result = script.pip("debug", allow_stderr_warning=True)
|
||||
assert DEPRECATION_TEXT not in result.stderr, str(result)
|
||||
assert CPYTHON_DEPRECATION_TEXT not in result.stderr, str(result)
|
||||
|
||||
|
||||
@skip_if_python2
|
||||
def test_flag_does_nothing_if_python_version_is_not_2(script):
|
||||
script.pip("list", "--no-python-version-warning")
|
||||
|
||||
|
||||
@skip_if_not_python2
|
||||
def test_version_warning_is_shown_if_python_version_is_2(script):
|
||||
result = script.pip("debug", allow_stderr_warning=True)
|
||||
assert DEPRECATION_TEXT in result.stderr, str(result)
|
||||
if platform.python_implementation() == 'CPython':
|
||||
assert CPYTHON_DEPRECATION_TEXT in result.stderr, str(result)
|
||||
else:
|
||||
assert CPYTHON_DEPRECATION_TEXT not in result.stderr, str(result)
|
||||
|
||||
|
||||
@skip_if_not_python2
|
||||
def test_version_warning_is_not_shown_when_flag_is_passed(script):
|
||||
result = script.pip(
|
||||
"debug", "--no-python-version-warning", allow_stderr_warning=True
|
||||
)
|
||||
assert DEPRECATION_TEXT not in result.stderr, str(result)
|
||||
assert CPYTHON_DEPRECATION_TEXT not in result.stderr, str(result)
|
||||
assert "--no-python-version-warning" not in result.stderr
|
||||
|
|
|
@ -15,7 +15,7 @@ from textwrap import dedent
|
|||
from zipfile import ZipFile
|
||||
|
||||
import pytest
|
||||
from pip._vendor.six import PY2, ensure_binary, text_type
|
||||
from pip._vendor.six import ensure_binary
|
||||
from scripttest import FoundDir, TestFileEnvironment
|
||||
|
||||
from pip._internal.index.collector import LinkCollector
|
||||
|
@ -1099,15 +1099,12 @@ def create_basic_sdist_for_package(
|
|||
path.parent.mkdir(exist_ok=True, parents=True)
|
||||
path.write_bytes(ensure_binary(files[fname]))
|
||||
|
||||
# The base_dir cast is required to make `shutil.make_archive()` use
|
||||
# Unicode paths on Python 2, making it able to properly archive
|
||||
# files with non-ASCII names.
|
||||
retval = script.scratch_path / archive_name
|
||||
generated = shutil.make_archive(
|
||||
retval,
|
||||
'gztar',
|
||||
root_dir=script.temp_path,
|
||||
base_dir=text_type(os.curdir),
|
||||
base_dir=os.curdir,
|
||||
)
|
||||
shutil.move(generated, retval)
|
||||
|
||||
|
@ -1164,10 +1161,6 @@ def need_mercurial(fn):
|
|||
)(fn))
|
||||
|
||||
|
||||
skip_if_python2 = pytest.mark.skipif(PY2, reason="Non-Python 2 only")
|
||||
skip_if_not_python2 = pytest.mark.skipif(not PY2, reason="Python 2 only")
|
||||
|
||||
|
||||
# Workaround for test failures after new wheel release.
|
||||
windows_workaround_7667 = pytest.mark.skipif(
|
||||
"sys.platform == 'win32' and sys.version_info < (3,)",
|
||||
|
|
|
@ -2,8 +2,7 @@ from __future__ import absolute_import
|
|||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from pip._vendor.six.moves.urllib import request as urllib_request
|
||||
from urllib import request as urllib_request
|
||||
|
||||
from pip._internal.utils.misc import hide_url
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
|
|
@ -5,9 +5,6 @@ from __future__ import absolute_import
|
|||
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from pip._vendor import six
|
||||
|
||||
try:
|
||||
from os import supports_fd
|
||||
|
@ -15,11 +12,7 @@ except ImportError:
|
|||
supports_fd = set()
|
||||
|
||||
|
||||
|
||||
_base = six.text_type if os.path.supports_unicode_filenames else str
|
||||
|
||||
|
||||
class Path(_base):
|
||||
class Path(str):
|
||||
"""
|
||||
Models a path in an object oriented way.
|
||||
"""
|
||||
|
@ -32,8 +25,8 @@ class Path(_base):
|
|||
|
||||
def __new__(cls, *paths):
|
||||
if len(paths):
|
||||
return _base.__new__(cls, os.path.join(*paths))
|
||||
return _base.__new__(cls)
|
||||
return str.__new__(cls, os.path.join(*paths))
|
||||
return str.__new__(cls)
|
||||
|
||||
def __div__(self, path):
|
||||
"""
|
||||
|
@ -71,20 +64,20 @@ class Path(_base):
|
|||
>>> Path('/home/a') + 'bc.d'
|
||||
'/home/abc.d'
|
||||
"""
|
||||
return Path(_base(self) + path)
|
||||
return Path(str(self) + path)
|
||||
|
||||
def __radd__(self, path):
|
||||
"""
|
||||
>>> '/home/a' + Path('bc.d')
|
||||
'/home/abc.d'
|
||||
"""
|
||||
return Path(path + _base(self))
|
||||
return Path(path + str(self))
|
||||
|
||||
def __repr__(self):
|
||||
return u"Path({inner})".format(inner=_base.__repr__(self))
|
||||
return u"Path({inner})".format(inner=str.__repr__(self))
|
||||
|
||||
def __hash__(self):
|
||||
return _base.__hash__(self)
|
||||
return str.__hash__(self)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
|
@ -5,7 +5,7 @@ from email import message_from_string
|
|||
from functools import partial
|
||||
from zipfile import ZipFile
|
||||
|
||||
from pip._vendor.six import ensure_text, iteritems
|
||||
from pip._vendor.six import ensure_text
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
from tests.lib.wheel import (
|
||||
|
@ -182,7 +182,7 @@ def test_make_wheel_default_record():
|
|||
],
|
||||
"simple-0.1.0.dist-info/RECORD": ["", ""],
|
||||
}
|
||||
for name, values in iteritems(expected):
|
||||
for name, values in expected.items():
|
||||
assert records[name] == values, name
|
||||
|
||||
# WHEEL and METADATA aren't constructed in a stable way, so just spot
|
||||
|
@ -191,7 +191,7 @@ def test_make_wheel_default_record():
|
|||
"simple-0.1.0.dist-info/METADATA": "51",
|
||||
"simple-0.1.0.dist-info/WHEEL": "104",
|
||||
}
|
||||
for name, length in iteritems(expected_variable):
|
||||
for name, length in expected_variable.items():
|
||||
assert records[name][0].startswith("sha256="), name
|
||||
assert records[name][1] == length, name
|
||||
|
||||
|
|
|
@ -4,15 +4,12 @@ import compileall
|
|||
import shutil
|
||||
import sys
|
||||
import textwrap
|
||||
import venv as _venv
|
||||
|
||||
import six
|
||||
import virtualenv as _virtualenv
|
||||
|
||||
from .path import Path
|
||||
|
||||
if six.PY3:
|
||||
import venv as _venv
|
||||
|
||||
|
||||
class VirtualEnvironment(object):
|
||||
"""
|
||||
|
@ -37,8 +34,7 @@ class VirtualEnvironment(object):
|
|||
self.site = Path(lib) / 'site-packages'
|
||||
# Workaround for https://github.com/pypa/virtualenv/issues/306
|
||||
if hasattr(sys, "pypy_version_info"):
|
||||
version_fmt = '{0}' if six.PY3 else '{0}.{1}'
|
||||
version_dir = version_fmt.format(*sys.version_info)
|
||||
version_dir = '{0}'.format(*sys.version_info)
|
||||
self.lib = Path(home, 'lib-python', version_dir)
|
||||
else:
|
||||
self.lib = Path(lib)
|
||||
|
|
|
@ -13,7 +13,7 @@ from zipfile import ZipFile
|
|||
|
||||
import csv23
|
||||
from pip._vendor.requests.structures import CaseInsensitiveDict
|
||||
from pip._vendor.six import ensure_binary, ensure_text, iteritems
|
||||
from pip._vendor.six import ensure_binary, ensure_text
|
||||
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
from tests.lib.path import Path
|
||||
|
@ -68,7 +68,7 @@ def message_from_dict(headers):
|
|||
List values are converted into repeated headers in the result.
|
||||
"""
|
||||
message = Message()
|
||||
for name, value in iteritems(headers):
|
||||
for name, value in headers.items():
|
||||
if isinstance(value, list):
|
||||
for v in value:
|
||||
message[name] = v
|
||||
|
@ -161,7 +161,7 @@ def make_entry_points_file(
|
|||
entry_points_data["console_scripts"] = console_scripts
|
||||
|
||||
lines = []
|
||||
for section, values in iteritems(entry_points_data):
|
||||
for section, values in entry_points_data.items():
|
||||
lines.append("[{}]".format(section))
|
||||
lines.extend(values)
|
||||
|
||||
|
@ -175,7 +175,7 @@ def make_files(files):
|
|||
# type: (Dict[str, AnyStr]) -> List[File]
|
||||
return [
|
||||
File(name, ensure_binary(contents))
|
||||
for name, contents in iteritems(files)
|
||||
for name, contents in files.items()
|
||||
]
|
||||
|
||||
|
||||
|
@ -184,7 +184,7 @@ def make_metadata_files(name, version, files):
|
|||
get_path = partial(dist_info_path, name, version)
|
||||
return [
|
||||
File(get_path(name), ensure_binary(contents))
|
||||
for name, contents in iteritems(files)
|
||||
for name, contents in files.items()
|
||||
]
|
||||
|
||||
|
||||
|
@ -193,7 +193,7 @@ def make_data_files(name, version, files):
|
|||
data_dir = "{}-{}.data".format(name, version)
|
||||
return [
|
||||
File("{}/{}".format(data_dir, name), ensure_binary(contents))
|
||||
for name, contents in iteritems(files)
|
||||
for name, contents in files.items()
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ import os.path
|
|||
import re
|
||||
import uuid
|
||||
from textwrap import dedent
|
||||
from urllib import request as urllib_request
|
||||
|
||||
import mock
|
||||
import pretend
|
||||
import pytest
|
||||
from mock import Mock, patch
|
||||
from pip._vendor import html5lib, requests
|
||||
from pip._vendor.six.moves.urllib import request as urllib_request
|
||||
|
||||
from pip._internal.exceptions import NetworkConnectionError
|
||||
from pip._internal.index.collector import (
|
||||
|
@ -30,7 +30,7 @@ from pip._internal.index.collector import (
|
|||
from pip._internal.models.index import PyPI
|
||||
from pip._internal.models.link import Link
|
||||
from pip._internal.network.session import PipSession
|
||||
from tests.lib import make_test_link_collector, skip_if_python2
|
||||
from tests.lib import make_test_link_collector
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
@ -406,7 +406,6 @@ def test_parse_links__yanked_reason(anchor_html, expected):
|
|||
assert actual == expected
|
||||
|
||||
|
||||
@skip_if_python2
|
||||
def test_parse_links_caches_same_page_by_url():
|
||||
html = (
|
||||
'<html><head><meta charset="utf-8"><head>'
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import errno
|
||||
import logging
|
||||
from threading import Thread
|
||||
|
||||
import pytest
|
||||
from mock import patch
|
||||
from pip._vendor.six import PY2
|
||||
|
||||
from pip._internal.utils.logging import (
|
||||
BrokenStdoutLoggingError,
|
||||
|
@ -17,19 +15,6 @@ from pip._internal.utils.misc import captured_stderr, captured_stdout
|
|||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# This is a Python 2/3 compatibility helper.
|
||||
def _make_broken_pipe_error():
|
||||
"""
|
||||
Return an exception object representing a broken pipe.
|
||||
"""
|
||||
if PY2:
|
||||
# This is one way a broken pipe error can show up in Python 2
|
||||
# (a non-Windows example in this case).
|
||||
return IOError(errno.EPIPE, 'Broken pipe')
|
||||
|
||||
return BrokenPipeError() # noqa: F821
|
||||
|
||||
|
||||
class TestIndentingFormatter(object):
|
||||
"""Test ``pip._internal.utils.logging.IndentingFormatter``."""
|
||||
|
||||
|
@ -146,7 +131,7 @@ class TestColorizedStreamHandler(object):
|
|||
with captured_stderr() as stderr:
|
||||
handler = ColorizedStreamHandler(stream=stderr)
|
||||
with patch('sys.stderr.flush') as mock_flush:
|
||||
mock_flush.side_effect = _make_broken_pipe_error()
|
||||
mock_flush.side_effect = BrokenPipeError()
|
||||
# The emit() call raises no exception.
|
||||
handler.emit(record)
|
||||
|
||||
|
@ -154,13 +139,9 @@ class TestColorizedStreamHandler(object):
|
|||
|
||||
assert err_text.startswith('my error')
|
||||
# Check that the logging framework tried to log the exception.
|
||||
if PY2:
|
||||
assert 'IOError: [Errno 32] Broken pipe' in err_text
|
||||
assert 'Logged from file' in err_text
|
||||
else:
|
||||
assert 'Logging error' in err_text
|
||||
assert 'BrokenPipeError' in err_text
|
||||
assert "Message: 'my error'" in err_text
|
||||
assert 'Logging error' in err_text
|
||||
assert 'BrokenPipeError' in err_text
|
||||
assert "Message: 'my error'" in err_text
|
||||
|
||||
def test_broken_pipe_in_stdout_write(self):
|
||||
"""
|
||||
|
@ -173,7 +154,7 @@ class TestColorizedStreamHandler(object):
|
|||
with captured_stdout() as stdout:
|
||||
handler = ColorizedStreamHandler(stream=stdout)
|
||||
with patch('sys.stdout.write') as mock_write:
|
||||
mock_write.side_effect = _make_broken_pipe_error()
|
||||
mock_write.side_effect = BrokenPipeError()
|
||||
with pytest.raises(BrokenStdoutLoggingError):
|
||||
handler.emit(record)
|
||||
|
||||
|
@ -188,7 +169,7 @@ class TestColorizedStreamHandler(object):
|
|||
with captured_stdout() as stdout:
|
||||
handler = ColorizedStreamHandler(stream=stdout)
|
||||
with patch('sys.stdout.flush') as mock_flush:
|
||||
mock_flush.side_effect = _make_broken_pipe_error()
|
||||
mock_flush.side_effect = BrokenPipeError()
|
||||
with pytest.raises(BrokenStdoutLoggingError):
|
||||
handler.emit(record)
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import textwrap
|
|||
|
||||
import pytest
|
||||
from mock import patch
|
||||
from pip._vendor.six import PY2
|
||||
from pretend import stub
|
||||
|
||||
import pip._internal.req.req_file # this will be monkeypatched
|
||||
|
@ -220,12 +219,11 @@ class TestProcessLine(object):
|
|||
line_number=3
|
||||
)
|
||||
|
||||
package_name = "u'my-package=1.0'" if PY2 else "'my-package=1.0'"
|
||||
expected = (
|
||||
"Invalid requirement: {} "
|
||||
"Invalid requirement: 'my-package=1.0' "
|
||||
'(from line 3 of path/requirements.txt)\n'
|
||||
'Hint: = is not a valid operator. Did you mean == ?'
|
||||
).format(package_name)
|
||||
)
|
||||
assert str(exc.value) == expected
|
||||
|
||||
def test_yield_line_requirement(self, line_processor):
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import os
|
||||
import sys
|
||||
from urllib import request as urllib_request
|
||||
|
||||
import pytest
|
||||
from pip._vendor.six.moves.urllib import request as urllib_request
|
||||
|
||||
from pip._internal.utils.urls import get_url_scheme, path_to_url, url_to_path
|
||||
|
||||
|
|
|
@ -5,11 +5,9 @@ from importlib import import_module
|
|||
from math import factorial
|
||||
from sys import modules
|
||||
|
||||
from pip._vendor.six import PY2
|
||||
from pip._vendor.six.moves import map
|
||||
from pytest import mark
|
||||
|
||||
DUNDER_IMPORT = '__builtin__.__import__' if PY2 else 'builtins.__import__'
|
||||
DUNDER_IMPORT = 'builtins.__import__'
|
||||
FUNC, ITERABLE = factorial, range(42)
|
||||
MAPS = 'map_multiprocess', 'map_multithread'
|
||||
_import = __import__
|
||||
|
@ -63,9 +61,8 @@ def test_lack_sem_open(name, monkeypatch):
|
|||
def test_have_sem_open(name, monkeypatch):
|
||||
"""Test fallback when sem_open is available."""
|
||||
monkeypatch.setattr(DUNDER_IMPORT, have_sem_open)
|
||||
impl = '_map_fallback' if PY2 else '_{}'.format(name)
|
||||
with tmp_import_parallel() as parallel:
|
||||
assert getattr(parallel, name) is getattr(parallel, impl)
|
||||
assert getattr(parallel, name) is getattr(parallel, '_{}'.format(name))
|
||||
|
||||
|
||||
@mark.parametrize('name', MAPS)
|
||||
|
|
|
@ -6,7 +6,6 @@ from pip._vendor.six import ensure_binary
|
|||
|
||||
from pip._internal.utils.packaging import get_metadata, get_requires_python
|
||||
from pip._internal.utils.pkg_resources import DictMetadata
|
||||
from tests.lib import skip_if_python2
|
||||
|
||||
|
||||
def test_dict_metadata_works():
|
||||
|
@ -45,8 +44,6 @@ def test_dict_metadata_works():
|
|||
assert requires_python == get_requires_python(dist)
|
||||
|
||||
|
||||
# Metadata is not decoded on Python 2, so no chance for error.
|
||||
@skip_if_python2
|
||||
def test_dict_metadata_throws_on_bad_unicode():
|
||||
metadata = DictMetadata({
|
||||
"METADATA": b"\xff"
|
||||
|
|
|
@ -9,7 +9,6 @@ from pip._vendor.contextlib2 import ExitStack
|
|||
from pip._internal.exceptions import UnsupportedWheel
|
||||
from pip._internal.utils import wheel
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
from tests.lib import skip_if_python2
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from tests.lib.path import Path
|
||||
|
@ -88,7 +87,6 @@ def test_wheel_metadata_fails_missing_wheel(tmpdir, zip_dir):
|
|||
assert "could not read" in str(e.value)
|
||||
|
||||
|
||||
@skip_if_python2
|
||||
def test_wheel_metadata_fails_on_bad_encoding(tmpdir, zip_dir):
|
||||
dist_info_dir = tmpdir / "simple-0.1.0.dist-info"
|
||||
dist_info_dir.mkdir()
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
Contains functional tests of the Mercurial class.
|
||||
"""
|
||||
|
||||
import configparser
|
||||
import os
|
||||
|
||||
from pip._vendor.six.moves import configparser
|
||||
|
||||
from pip._internal.utils.misc import hide_url
|
||||
from pip._internal.vcs.mercurial import Mercurial
|
||||
from tests.lib import need_mercurial
|
||||
|
|
|
@ -25,7 +25,7 @@ from pip._internal.utils.compat import WINDOWS
|
|||
from pip._internal.utils.misc import hash_file
|
||||
from pip._internal.utils.unpacking import unpack_file
|
||||
from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel
|
||||
from tests.lib import DATA_DIR, assert_paths_equal, skip_if_python2
|
||||
from tests.lib import DATA_DIR, assert_paths_equal
|
||||
from tests.lib.wheel import make_wheel
|
||||
|
||||
|
||||
|
@ -83,7 +83,7 @@ def test_get_legacy_build_wheel_path__multiple_names(caplog):
|
|||
[
|
||||
u"pip = pip._internal.main:pip",
|
||||
u"pip:pip = pip._internal.main:pip",
|
||||
pytest.param(u"進入點 = 套件.模組:函式", marks=skip_if_python2),
|
||||
u"進入點 = 套件.模組:函式",
|
||||
],
|
||||
)
|
||||
def test_get_entrypoints(console_scripts):
|
||||
|
|
Loading…
Reference in New Issue