diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2019-06-04 20:28:12 -0700 |
---|---|---|
committer | Chris Jerdonek <chris.jerdonek@gmail.com> | 2019-06-06 13:20:26 -0700 |
commit | e6b1070e145a5e95aca5d2c08aa3dce32922742e (patch) | |
tree | f2e770be22c4884a7c0e30177a0ea58ba4a818ca | |
parent | 107258da0b23acf44c18377387a1d4b21657ef8d (diff) | |
download | pip-e6b1070e145a5e95aca5d2c08aa3dce32922742e.tar.gz |
Add normalize_version_info() with tests.
-rw-r--r-- | src/pip/_internal/utils/misc.py | 37 | ||||
-rw-r--r-- | tests/unit/test_utils.py | 18 |
2 files changed, 51 insertions, 4 deletions
diff --git a/src/pip/_internal/utils/misc.py b/src/pip/_internal/utils/misc.py index 05dc23394..cb470f760 100644 --- a/src/pip/_internal/utils/misc.py +++ b/src/pip/_internal/utils/misc.py @@ -45,13 +45,23 @@ else: if MYPY_CHECK_RUNNING: from typing import ( - Optional, Tuple, Iterable, List, Match, Union, Any, Mapping, Text, - AnyStr, Container + Any, AnyStr, Container, Iterable, List, Mapping, Match, Optional, Text, + Union, ) from pip._vendor.pkg_resources import Distribution from pip._internal.models.link import Link from pip._internal.utils.ui import SpinnerInterface +try: + from typing import cast, Tuple + VersionInfo = Tuple[int, int, int] +except ImportError: + # typing's cast() isn't supported in code comments, so we need to + # define a dummy, no-op version. + def cast(typ, val): + return val + VersionInfo = None + __all__ = ['rmtree', 'display_path', 'backup_dir', 'ask', 'splitext', @@ -94,6 +104,29 @@ except ImportError: logger.debug('lzma module is not available') +def normalize_version_info(py_version_info): + # type: (Optional[Tuple[int, ...]]) -> Optional[Tuple[int, int, int]] + """ + Convert a tuple of ints representing a Python version to one of length + three. + + :param py_version_info: a tuple of ints representing a Python version, + or None to specify no version. The tuple can have any length. + + :return: a tuple of length three if `py_version_info` is non-None. + Otherwise, return `py_version_info` unchanged (i.e. None). + """ + if py_version_info is None: + return None + + if len(py_version_info) < 3: + py_version_info += (3 - len(py_version_info)) * (0,) + elif len(py_version_info) > 3: + py_version_info = py_version_info[:3] + + return cast(VersionInfo, py_version_info) + + def ensure_dir(path): # type: (AnyStr) -> None """os.path.makedirs without EEXIST.""" diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index a4550bcfe..4a8498bda 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -29,8 +29,9 @@ from pip._internal.utils.glibc import check_glibc_version from pip._internal.utils.hashes import Hashes, MissingHashes from pip._internal.utils.misc import ( call_subprocess, egg_link_path, ensure_dir, format_command_args, - get_installed_distributions, get_prog, normalize_path, path_to_url, - redact_netloc, redact_password_from_url, remove_auth_from_url, rmtree, + get_installed_distributions, get_prog, normalize_path, + normalize_version_info, path_to_url, redact_netloc, + redact_password_from_url, remove_auth_from_url, rmtree, split_auth_from_netloc, split_auth_netloc_from_url, untar_file, unzip_file, ) from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory @@ -700,6 +701,19 @@ class TestGlibc(object): assert False +@pytest.mark.parametrize('version_info, expected', [ + (None, None), + ((), (0, 0, 0)), + ((3, ), (3, 0, 0)), + ((3, 6), (3, 6, 0)), + ((3, 6, 2), (3, 6, 2)), + ((3, 6, 2, 4), (3, 6, 2)), +]) +def test_normalize_version_info(version_info, expected): + actual = normalize_version_info(version_info) + assert actual == expected + + class TestGetProg(object): @pytest.mark.parametrize( |