From c115cdc81a3b94397be69534d196019263e6762a Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sat, 26 Dec 2020 08:31:00 -0800 Subject: [PATCH] Remove unnecessary uses of six.ensure_(binary|str|text) Now that Python 2 is not supported, the bytes/str boundaries are more clear and explicit. Using six.ensure_* methods for backwards compatibility is no longer necessary as the types are known and verified using mypy. One exception is tests/lib/wheel.py which allows tests to pass test setup data as either bytes or str. The module operations.install.wheel also remains untouched as it is especially delicate to bytes/str mixups and the current version is working. --- ...35a1-abe3-4532-8add-bf7491b0eea5.bugfix.rst | 0 src/pip/_internal/network/session.py | 12 +++--------- src/pip/_internal/req/req_install.py | 2 +- src/pip/_internal/self_outdated_check.py | 5 ++--- src/pip/_internal/utils/pkg_resources.py | 3 +-- src/pip/_internal/utils/temp_dir.py | 12 +----------- src/pip/_internal/utils/wheel.py | 18 ++++-------------- tests/lib/__init__.py | 3 +-- tests/lib/test_wheel.py | 4 +--- tests/lib/wheel.py | 16 +++++++++++----- tests/unit/test_utils_pkg_resources.py | 5 +---- 11 files changed, 26 insertions(+), 54 deletions(-) create mode 100644 news/bca635a1-abe3-4532-8add-bf7491b0eea5.bugfix.rst diff --git a/news/bca635a1-abe3-4532-8add-bf7491b0eea5.bugfix.rst b/news/bca635a1-abe3-4532-8add-bf7491b0eea5.bugfix.rst new file mode 100644 index 000000000..e69de29bb diff --git a/src/pip/_internal/network/session.py b/src/pip/_internal/network/session.py index 5021b8eef..46f300f91 100644 --- a/src/pip/_internal/network/session.py +++ b/src/pip/_internal/network/session.py @@ -16,7 +16,7 @@ import sys import urllib.parse import warnings -from pip._vendor import requests, six, urllib3 +from pip._vendor import requests, urllib3 from pip._vendor.cachecontrol import CacheControlAdapter from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter from pip._vendor.requests.models import Response @@ -367,14 +367,8 @@ class PipSession(requests.Session): continue try: - addr = ipaddress.ip_address( - None - if origin_host is None - else six.ensure_text(origin_host) - ) - network = ipaddress.ip_network( - six.ensure_text(secure_host) - ) + addr = ipaddress.ip_address(origin_host) + network = ipaddress.ip_network(secure_host) except ValueError: # We don't have both a valid address or a valid network, so # we'll check this origin against hostnames. diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py index 0bf001320..b453cb73b 100644 --- a/src/pip/_internal/req/req_install.py +++ b/src/pip/_internal/req/req_install.py @@ -255,7 +255,7 @@ class InstallRequirement: # type: () -> Optional[str] if self.req is None: return None - return six.ensure_str(pkg_resources.safe_name(self.req.name)) + return pkg_resources.safe_name(self.req.name) @property def specifier(self): diff --git a/src/pip/_internal/self_outdated_check.py b/src/pip/_internal/self_outdated_check.py index c22f06afe..f1ad24168 100644 --- a/src/pip/_internal/self_outdated_check.py +++ b/src/pip/_internal/self_outdated_check.py @@ -6,7 +6,6 @@ import os.path import sys from pip._vendor.packaging import version as packaging_version -from pip._vendor.six import ensure_binary from pip._internal.index.collector import LinkCollector from pip._internal.index.package_finder import PackageFinder @@ -31,7 +30,7 @@ logger = logging.getLogger(__name__) def _get_statefile_name(key): # type: (str) -> str - key_bytes = ensure_binary(key) + key_bytes = key.encode() name = hashlib.sha224(key_bytes).hexdigest() return name @@ -85,7 +84,7 @@ class SelfCheckState: text = json.dumps(state, sort_keys=True, separators=(",", ":")) with adjacent_tmp_file(self.statefile_path) as f: - f.write(ensure_binary(text)) + f.write(text.encode()) try: # Since we have a prefix-specific state file, we can just diff --git a/src/pip/_internal/utils/pkg_resources.py b/src/pip/_internal/utils/pkg_resources.py index d5b26f538..816ac1223 100644 --- a/src/pip/_internal/utils/pkg_resources.py +++ b/src/pip/_internal/utils/pkg_resources.py @@ -1,5 +1,4 @@ from pip._vendor.pkg_resources import yield_lines -from pip._vendor.six import ensure_str from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -21,7 +20,7 @@ class DictMetadata: def get_metadata(self, name): # type: (str) -> str try: - return ensure_str(self._metadata[name]) + return self._metadata[name].decode() except UnicodeDecodeError as e: # Mirrors handling done in pkg_resources.NullProvider. e.reason += f" in {name} file" diff --git a/src/pip/_internal/utils/temp_dir.py b/src/pip/_internal/utils/temp_dir.py index 91b277df6..c7fca502b 100644 --- a/src/pip/_internal/utils/temp_dir.py +++ b/src/pip/_internal/utils/temp_dir.py @@ -6,9 +6,7 @@ import tempfile from contextlib import contextmanager from pip._vendor.contextlib2 import ExitStack -from pip._vendor.six import ensure_text -from pip._internal.utils.compat import WINDOWS from pip._internal.utils.misc import enum, rmtree from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -196,15 +194,7 @@ class TempDirectory: self._deleted = True if not os.path.exists(self._path): return - # Make sure to pass unicode on Python 2 to make the contents also - # use unicode, ensuring non-ASCII names and can be represented. - # This is only done on Windows because POSIX platforms use bytes - # natively for paths, and the bytes-text conversion omission avoids - # errors caused by the environment configuring encodings incorrectly. - if WINDOWS: - rmtree(ensure_text(self._path)) - else: - rmtree(self._path) + rmtree(self._path) class AdjacentTempDirectory(TempDirectory): diff --git a/src/pip/_internal/utils/wheel.py b/src/pip/_internal/utils/wheel.py index 2c01cf992..a02fbee18 100644 --- a/src/pip/_internal/utils/wheel.py +++ b/src/pip/_internal/utils/wheel.py @@ -7,7 +7,6 @@ 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 ensure_str from pip._internal.exceptions import UnsupportedWheel from pip._internal.utils.pkg_resources import DictMetadata @@ -62,17 +61,10 @@ def pkg_resources_distribution_for_wheel(wheel_zip, name, location): metadata_text = {} # type: Dict[str, bytes] for path in metadata_files: - # If a flag is set, namelist entries may be unicode in Python 2. - # We coerce them to native str type to match the types used in the rest - # of the code. This cannot fail because unicode can always be encoded - # with UTF-8. - full_path = ensure_str(path) - _, metadata_name = full_path.split("/", 1) + _, metadata_name = path.split("/", 1) try: - metadata_text[metadata_name] = read_wheel_metadata_file( - wheel_zip, full_path - ) + metadata_text[metadata_name] = read_wheel_metadata_file(wheel_zip, path) except UnsupportedWheel as e: raise UnsupportedWheel( "{} has an invalid wheel, {}".format(name, str(e)) @@ -139,9 +131,7 @@ def wheel_dist_info_dir(source, name): ) ) - # Zip file paths can be unicode or str depending on the zip entry flags, - # so normalize it. - return ensure_str(info_dir) + return info_dir def read_wheel_metadata_file(source, path): @@ -166,7 +156,7 @@ def wheel_metadata(source, dist_info_dir): wheel_contents = read_wheel_metadata_file(source, path) try: - wheel_text = ensure_str(wheel_contents) + wheel_text = wheel_contents.decode() except UnicodeDecodeError as e: raise UnsupportedWheel(f"error decoding {path!r}: {e!r}") diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index 6a98d4acf..520a0ca2e 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -13,7 +13,6 @@ from textwrap import dedent from zipfile import ZipFile import pytest -from pip._vendor.six import ensure_binary from scripttest import FoundDir, TestFileEnvironment from pip._internal.index.collector import LinkCollector @@ -1095,7 +1094,7 @@ def create_basic_sdist_for_package( for fname in files: path = script.temp_path / fname path.parent.mkdir(exist_ok=True, parents=True) - path.write_bytes(ensure_binary(files[fname])) + path.write_bytes(files[fname].encode("utf-8")) retval = script.scratch_path / archive_name generated = shutil.make_archive( diff --git a/tests/lib/test_wheel.py b/tests/lib/test_wheel.py index 15e5a75fe..31d918abd 100644 --- a/tests/lib/test_wheel.py +++ b/tests/lib/test_wheel.py @@ -5,8 +5,6 @@ from email import message_from_string from functools import partial from zipfile import ZipFile -from pip._vendor.six import ensure_text - from pip._internal.utils.typing import MYPY_CHECK_RUNNING from tests.lib.wheel import ( _default, @@ -164,7 +162,7 @@ def test_make_wheel_default_record(): extra_data_files={"purelib/info.txt": "c"}, ).as_zipfile() as z: record_bytes = z.read("simple-0.1.0.dist-info/RECORD") - record_text = ensure_text(record_bytes) + record_text = record_bytes.decode() record_rows = list(csv.reader(record_text.splitlines())) records = { row[0]: row[1:] for row in record_rows diff --git a/tests/lib/wheel.py b/tests/lib/wheel.py index f96f5d06e..5872912b2 100644 --- a/tests/lib/wheel.py +++ b/tests/lib/wheel.py @@ -13,7 +13,6 @@ from zipfile import ZipFile import csv23 from pip._vendor.requests.structures import CaseInsensitiveDict -from pip._vendor.six import ensure_binary, ensure_text from pip._internal.utils.typing import MYPY_CHECK_RUNNING from tests.lib.path import Path @@ -61,6 +60,13 @@ if MYPY_CHECK_RUNNING: pass +def ensure_binary(value): + # type: (AnyStr) -> bytes + if isinstance(value, bytes): + return value + return value.encode() + + def message_from_dict(headers): # type: (Dict[str, HeaderValue]) -> Message """Plain key-value pairs are set in the returned message. @@ -110,7 +116,7 @@ def make_metadata_file( if body is not _default: message.set_payload(body) - return File(path, ensure_binary(message_from_dict(metadata).as_string())) + return File(path, message_from_dict(metadata).as_bytes()) def make_wheel_metadata_file( @@ -139,7 +145,7 @@ def make_wheel_metadata_file( if updates is not _default: metadata.update(updates) - return File(path, ensure_binary(message_from_dict(metadata).as_string())) + return File(path, message_from_dict(metadata).as_bytes()) def make_entry_points_file( @@ -167,7 +173,7 @@ def make_entry_points_file( return File( dist_info_path(name, version, "entry_points.txt"), - ensure_binary("\n".join(lines)), + "\n".join(lines).encode(), ) @@ -243,7 +249,7 @@ def record_file_maker_wrapper( with StringIO(newline="") as buf: writer = csv23.writer(buf) for record in records: - writer.writerow(map(ensure_text, record)) + writer.writerow(record) contents = buf.getvalue().encode("utf-8") yield File(record_path, contents) diff --git a/tests/unit/test_utils_pkg_resources.py b/tests/unit/test_utils_pkg_resources.py index ae7357ba1..7cc95b91b 100644 --- a/tests/unit/test_utils_pkg_resources.py +++ b/tests/unit/test_utils_pkg_resources.py @@ -2,7 +2,6 @@ from email.message import Message import pytest from pip._vendor.pkg_resources import DistInfoDistribution, Requirement -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 @@ -26,9 +25,7 @@ def test_dict_metadata_works(): metadata["Provides-Extra"] = extra metadata["Requires-Python"] = requires_python - inner_metadata = DictMetadata({ - "METADATA": ensure_binary(metadata.as_string()) - }) + inner_metadata = DictMetadata({"METADATA": metadata.as_bytes()}) dist = DistInfoDistribution( location="", metadata=inner_metadata, project_name=name ) -- GitLab