Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for EOL Python 3.4 (2) #6782

Merged
merged 10 commits into from
Sep 10, 2019
44 changes: 22 additions & 22 deletions src/pip/_internal/utils/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import shutil
import sys

from pip._vendor.six import text_type
from pip._vendor.six import PY2, text_type
from pip._vendor.urllib3.util import IS_PYOPENSSL

from pip._internal.utils.typing import MYPY_CHECK_RUNNING
Expand Down Expand Up @@ -47,10 +47,7 @@

HAS_TLS = (ssl is not None) or IS_PYOPENSSL

if sys.version_info >= (3, 4):
uses_pycache = True
from importlib.util import cache_from_source
else:
if PY2:
import imp

try:
Expand All @@ -60,27 +57,29 @@
cache_from_source = None

uses_pycache = cache_from_source is not None
else:
uses_pycache = True
from importlib.util import cache_from_source


if sys.version_info >= (3, 5):
backslashreplace_decode = "backslashreplace"
else:
if PY2:
# In version 3.4 and older, backslashreplace exists
hugovk marked this conversation as resolved.
Show resolved Hide resolved
# 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))
if sys.version_info[0] == 2:
# Python 2 gave us characters - convert to numeric bytes
raw_bytes = (ord(b) for b in raw_bytes)
# Python 2 gave us characters - convert to numeric bytes
raw_bytes = (ord(b) for b in raw_bytes)
return u"".join(u"\\x%x" % c for c in raw_bytes), err.end
codecs.register_error(
"backslashreplace_decode",
backslashreplace_decode_fn,
)
backslashreplace_decode = "backslashreplace_decode"
else:
backslashreplace_decode = "backslashreplace"


def str_to_display(data, desc=None):
Expand Down Expand Up @@ -156,19 +155,19 @@ def console_to_str(data):
return str_to_display(data, desc='Subprocess output')


if sys.version_info >= (3,):
if PY2:
def native_str(s, replace=False):
# type: (str, bool) -> str
if isinstance(s, bytes):
return s.decode('utf-8', 'replace' if replace else 'strict')
# Replace is ignored -- unicode to UTF-8 can't fail
if isinstance(s, text_type):
return s.encode('utf-8')
return s

else:
def native_str(s, replace=False):
# type: (str, bool) -> str
# Replace is ignored -- unicode to UTF-8 can't fail
if isinstance(s, text_type):
return s.encode('utf-8')
if isinstance(s, bytes):
return s.decode('utf-8', 'replace' if replace else 'strict')
return s


Expand Down Expand Up @@ -202,16 +201,17 @@ def get_path_uid(path):
return file_uid


if sys.version_info >= (3, 4):
from importlib.machinery import EXTENSION_SUFFIXES
if PY2:
from imp import get_suffixes

def get_extension_suffixes():
return EXTENSION_SUFFIXES
return [suffix[0] for suffix in get_suffixes()]

else:
from imp import get_suffixes
from importlib.machinery import EXTENSION_SUFFIXES

def get_extension_suffixes():
return [suffix[0] for suffix in get_suffixes()]
return EXTENSION_SUFFIXES


def expanduser(path):
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,4 @@ def in_memory_pip():
@pytest.fixture
def deprecated_python():
"""Used to indicate whether pip deprecated this python version"""
return sys.version_info[:2] in [(3, 4), (2, 7)]
return sys.version_info[:2] in [(2, 7)]
2 changes: 1 addition & 1 deletion tests/data/packages/LocalEnvironMarker/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ def path_to_url(path):
version='0.0.1',
packages=find_packages(),
extras_require={
":python_version == '2.7' or python_version == '3.4'": ['simple'],
":python_version == '2.7'": ['simple'],
}
)
7 changes: 5 additions & 2 deletions tests/functional/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from os.path import curdir, join, pardir

import pytest
from pip._vendor.six import PY2

from pip._internal import pep425tags
from pip._internal.cli.status_codes import ERROR, SUCCESS
Expand All @@ -19,6 +20,8 @@
from tests.lib.local_repos import local_checkout
from tests.lib.path import Path

python2_only = pytest.mark.skipif(not PY2, reason="Python 2 only")


@pytest.mark.parametrize('command', ('install', 'wheel'))
@pytest.mark.parametrize('variant', ('missing_setuptools', 'bad_setuptools'))
Expand Down Expand Up @@ -528,7 +531,7 @@ def test_editable_install__local_dir_no_setup_py_with_pyproject(
assert 'A "pyproject.toml" file was found' in msg


@pytest.mark.skipif("sys.version_info >= (3,4)")
@python2_only
@pytest.mark.xfail
def test_install_argparse_shadowed(script):
# When argparse is in the stdlib, we support installing it
Expand All @@ -543,7 +546,7 @@ def test_install_argparse_shadowed(script):


@pytest.mark.network
@pytest.mark.skipif("sys.version_info < (3,4)")
@pytest.mark.skipif("pip._vendor.six.PY2")
hugovk marked this conversation as resolved.
Show resolved Hide resolved
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.
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_req.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def test_no_reuse_existing_build_dir(self, data):
reqset,
)

# TODO: Update test when Python 2.7 or Python 3.4 is dropped.
# TODO: Update test when Python 2.7 is dropped.
def test_environment_marker_extras(self, data):
"""
Test that the environment marker extras are used with
Expand All @@ -99,7 +99,7 @@ def test_environment_marker_extras(self, data):
resolver = self._basic_resolver(finder)
resolver.resolve(reqset)
# This is hacky but does test both case in py2 and py3
if sys.version_info[:2] in ((2, 7), (3, 4)):
if sys.version_info[:2] == (2, 7):
assert reqset.has_requirement('simple')
else:
assert not reqset.has_requirement('simple')
Expand Down