diff options
| author | Matthias Klose <doko@debian.org> | 2021-02-01 17:49:05 +0100 |
|---|---|---|
| committer | git-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com> | 2021-02-01 22:42:33 +0000 |
| commit | 6e09d260c64bc2be40f1c375d24bf7a5714bc4de (patch) | |
| tree | a0787005b95cd69eec19e18200c36d35f0b73342 | |
| parent | 1bf04d679ff08c9e6d85b7123877e244ee2c5efd (diff) | |
| parent | b3a85ab7dd228e5f6b488afa4b78d867df7bd276 (diff) | |
20.9-1 (patches applied)applied/20.9-1
Imported using git-ubuntu import.
| -rw-r--r-- | .pre-commit-config.yaml | 5 | ||||
| -rw-r--r-- | CHANGELOG.rst | 8 | ||||
| -rw-r--r-- | PKG-INFO | 10 | ||||
| -rw-r--r-- | debian/changelog | 6 | ||||
| -rw-r--r-- | docs/utils.rst | 53 | ||||
| -rw-r--r-- | packaging.egg-info/PKG-INFO | 10 | ||||
| -rw-r--r-- | packaging/__about__.py | 2 | ||||
| -rw-r--r-- | packaging/markers.py | 16 | ||||
| -rw-r--r-- | packaging/requirements.py | 17 | ||||
| -rw-r--r-- | packaging/specifiers.py | 4 | ||||
| -rw-r--r-- | packaging/tags.py | 26 | ||||
| -rw-r--r-- | packaging/utils.py | 75 | ||||
| -rw-r--r-- | setup.cfg | 4 | ||||
| -rw-r--r-- | tests/test_markers.py | 5 | ||||
| -rw-r--r-- | tests/test_requirements.py | 3 | ||||
| -rw-r--r-- | tests/test_specifiers.py | 3 | ||||
| -rw-r--r-- | tests/test_tags.py | 11 | ||||
| -rw-r--r-- | tests/test_utils.py | 70 | ||||
| -rw-r--r-- | tests/test_version.py | 2 |
19 files changed, 297 insertions, 33 deletions
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ec7765e..5d8ba1f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,6 +23,11 @@ repos: hooks: - id: black + - repo: https://github.com/PyCQA/isort + rev: 5.6.4 + hooks: + - id: isort + - repo: https://gitlab.com/PyCQA/flake8 rev: "3.7.8" hooks: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index df42c9b..f368c45 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,14 @@ Changelog --------- +20.9 - 2021-01-29 +~~~~~~~~~~~~~~~~~ + +* Run [isort](https://pypi.org/project/isort/) over the code base (:issue:`377`) +* Add support for the ``macosx_10_*_universal2`` platform tags (:issue:`379`) +* Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()`` + (:issue:`387` and :issue:`389`) + 20.8 - 2020-12-11 ~~~~~~~~~~~~~~~~~ @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: packaging -Version: 20.8 +Version: 20.9 Summary: Core utilities for Python packages Home-page: https://github.com/pypa/packaging Author: Donald Stufft and individual contributors @@ -83,6 +83,14 @@ Description: packaging Changelog --------- + 20.9 - 2021-01-29 + ~~~~~~~~~~~~~~~~~ + + * Run [isort](https://pypi.org/project/isort/) over the code base (`#377 <https://github.com/pypa/packaging/issues/377>`__) + * Add support for the ``macosx_10_*_universal2`` platform tags (`#379 <https://github.com/pypa/packaging/issues/379>`__) + * Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()`` + (`#387 <https://github.com/pypa/packaging/issues/387>`__ and `#389 <https://github.com/pypa/packaging/issues/389>`__) + 20.8 - 2020-12-11 ~~~~~~~~~~~~~~~~~ diff --git a/debian/changelog b/debian/changelog index a0296ea..20ca0bd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +python-packaging (20.9-1) unstable; urgency=medium + + * New upstream version. + + -- Matthias Klose <doko@debian.org> Mon, 01 Feb 2021 17:49:05 +0100 + python-packaging (20.8-1) unstable; urgency=medium * New upstream version. diff --git a/docs/utils.rst b/docs/utils.rst index 134094a..8fbb025 100644 --- a/docs/utils.rst +++ b/docs/utils.rst @@ -30,7 +30,8 @@ Reference .. function:: canonicalize_version(version) This function takes a string representing a package version (or a - ``Version`` instance), and returns the normalized form of it. + :class:`~packaging.version.Version` instance), and returns the + normalized form of it. :param str version: The version to normalize. @@ -39,3 +40,53 @@ Reference >>> from packaging.utils import canonicalize_version >>> canonicalize_version('1.4.0.0.0') '1.4' + +.. function:: parse_wheel_filename(filename) + + This function takes the filename of a wheel file, and parses it, + returning a tuple of name, version, build number, and tags. + + The name part of the tuple is normalized. The version portion is an + instance of :class:`~packaging.version.Version`. The build number + is ``()`` if there is no build number in the wheel filename, + otherwise a two-item tuple of an integer for the leading digits and + a string for the rest of the build number. The tags portion is an + instance of :class:`~packaging.tags.Tag`. + + :param str filename: The name of the wheel file. + + .. doctest:: + + >>> from packaging.utils import parse_wheel_filename + >>> from packaging.tags import Tag + >>> from packaging.version import Version + >>> name, ver, build, tags = parse_wheel_filename("foo-1.0-py3-none-any.whl") + >>> name + 'foo' + >>> ver == Version('1.0') + True + >>> tags == {Tag("py3", "none", "any")} + True + >>> not build + True + +.. function:: parse_sdist_filename(filename) + + This function takes the filename of a sdist file (as specified + in the `Source distribution format`_ documentation), and parses + it, returning a tuple of the normalized name and version as + represented by an instance of :class:`~packaging.version.Version`. + + :param str filename: The name of the sdist file. + + .. doctest:: + + >>> from packaging.utils import parse_sdist_filename + >>> from packaging.version import Version + >>> name, ver = parse_sdist_filename("foo-1.0.tar.gz") + >>> name + 'foo' + >>> ver == Version('1.0') + True + +.. _Source distribution format: https://packaging.python.org/specifications/source-distribution-format/#source-distribution-file-name diff --git a/packaging.egg-info/PKG-INFO b/packaging.egg-info/PKG-INFO index 179f111..7865ede 100644 --- a/packaging.egg-info/PKG-INFO +++ b/packaging.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: packaging -Version: 20.8 +Version: 20.9 Summary: Core utilities for Python packages Home-page: https://github.com/pypa/packaging Author: Donald Stufft and individual contributors @@ -83,6 +83,14 @@ Description: packaging Changelog --------- + 20.9 - 2021-01-29 + ~~~~~~~~~~~~~~~~~ + + * Run [isort](https://pypi.org/project/isort/) over the code base (`#377 <https://github.com/pypa/packaging/issues/377>`__) + * Add support for the ``macosx_10_*_universal2`` platform tags (`#379 <https://github.com/pypa/packaging/issues/379>`__) + * Introduce ``packaging.utils.parse_wheel_filename()`` and ``parse_sdist_filename()`` + (`#387 <https://github.com/pypa/packaging/issues/387>`__ and `#389 <https://github.com/pypa/packaging/issues/389>`__) + 20.8 - 2020-12-11 ~~~~~~~~~~~~~~~~~ diff --git a/packaging/__about__.py b/packaging/__about__.py index 2d39193..4c43a96 100644 --- a/packaging/__about__.py +++ b/packaging/__about__.py @@ -18,7 +18,7 @@ __title__ = "packaging" __summary__ = "Core utilities for Python packages" __uri__ = "https://github.com/pypa/packaging" -__version__ = "20.8" +__version__ = "20.9" __author__ = "Donald Stufft and individual contributors" __email__ = "donald@stufft.io" diff --git a/packaging/markers.py b/packaging/markers.py index 87cd3f9..e0330ab 100644 --- a/packaging/markers.py +++ b/packaging/markers.py @@ -8,13 +8,21 @@ import os import platform import sys -from pyparsing import ParseException, ParseResults, stringStart, stringEnd -from pyparsing import ZeroOrMore, Group, Forward, QuotedString -from pyparsing import Literal as L # noqa +from pyparsing import ( # noqa: N817 + Forward, + Group, + Literal as L, + ParseException, + ParseResults, + QuotedString, + ZeroOrMore, + stringEnd, + stringStart, +) from ._compat import string_types from ._typing import TYPE_CHECKING -from .specifiers import Specifier, InvalidSpecifier +from .specifiers import InvalidSpecifier, Specifier if TYPE_CHECKING: # pragma: no cover from typing import Any, Callable, Dict, List, Optional, Tuple, Union diff --git a/packaging/requirements.py b/packaging/requirements.py index 5ba8daf..aa69d50 100644 --- a/packaging/requirements.py +++ b/packaging/requirements.py @@ -3,13 +3,22 @@ # for complete details. from __future__ import absolute_import, division, print_function -import string import re +import string import sys -from pyparsing import stringStart, stringEnd, originalTextFor, ParseException -from pyparsing import ZeroOrMore, Word, Optional, Regex, Combine -from pyparsing import Literal as L # noqa +from pyparsing import ( # noqa: N817 + Combine, + Literal as L, + Optional, + ParseException, + Regex, + Word, + ZeroOrMore, + originalTextFor, + stringEnd, + stringStart, +) from ._typing import TYPE_CHECKING from .markers import MARKER_EXPR, Marker diff --git a/packaging/specifiers.py b/packaging/specifiers.py index a42cbfe..a6a83c1 100644 --- a/packaging/specifiers.py +++ b/packaging/specifiers.py @@ -12,10 +12,10 @@ import warnings from ._compat import string_types, with_metaclass from ._typing import TYPE_CHECKING from .utils import canonicalize_version -from .version import Version, LegacyVersion, parse +from .version import LegacyVersion, Version, parse if TYPE_CHECKING: # pragma: no cover - from typing import List, Dict, Union, Iterable, Iterator, Optional, Callable, Tuple + from typing import Callable, Dict, Iterable, Iterator, List, Optional, Tuple, Union ParsedVersion = Union[Version, LegacyVersion] UnparsedVersion = Union[Version, LegacyVersion, str] diff --git a/packaging/tags.py b/packaging/tags.py index 13798e3..d637f1b 100644 --- a/packaging/tags.py +++ b/packaging/tags.py @@ -27,9 +27,9 @@ from ._typing import TYPE_CHECKING, cast if TYPE_CHECKING: # pragma: no cover from typing import ( + IO, Dict, FrozenSet, - IO, Iterable, Iterator, List, @@ -458,14 +458,28 @@ def mac_platforms(version=None, arch=None): major=major_version, minor=0, binary_format=binary_format ) - if version >= (11, 0) and arch == "x86_64": + if version >= (11, 0): # Mac OS 11 on x86_64 is compatible with binaries from previous releases. # Arm64 support was introduced in 11.0, so no Arm binaries from previous # releases exist. - for minor_version in range(16, 3, -1): - compat_version = 10, minor_version - binary_formats = _mac_binary_formats(compat_version, arch) - for binary_format in binary_formats: + # + # However, the "universal2" binary format can have a + # macOS version earlier than 11.0 when the x86_64 part of the binary supports + # that version of macOS. + if arch == "x86_64": + for minor_version in range(16, 3, -1): + compat_version = 10, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield "macosx_{major}_{minor}_{binary_format}".format( + major=compat_version[0], + minor=compat_version[1], + binary_format=binary_format, + ) + else: + for minor_version in range(16, 3, -1): + compat_version = 10, minor_version + binary_format = "universal2" yield "macosx_{major}_{minor}_{binary_format}".format( major=compat_version[0], minor=compat_version[1], diff --git a/packaging/utils.py b/packaging/utils.py index 92c7b00..6e8c2a3 100644 --- a/packaging/utils.py +++ b/packaging/utils.py @@ -6,23 +6,41 @@ from __future__ import absolute_import, division, print_function import re from ._typing import TYPE_CHECKING, cast +from .tags import Tag, parse_tag from .version import InvalidVersion, Version if TYPE_CHECKING: # pragma: no cover - from typing import NewType, Union + from typing import FrozenSet, NewType, Tuple, Union + BuildTag = Union[Tuple[()], Tuple[int, str]] NormalizedName = NewType("NormalizedName", str) else: + BuildTag = tuple NormalizedName = str + +class InvalidWheelFilename(ValueError): + """ + An invalid wheel filename was found, users should refer to PEP 427. + """ + + +class InvalidSdistFilename(ValueError): + """ + An invalid sdist filename was found, users should refer to the packaging user guide. + """ + + _canonicalize_regex = re.compile(r"[-_.]+") +# PEP 427: The build number must start with a digit. +_build_tag_regex = re.compile(r"(\d+)(.*)") def canonicalize_name(name): # type: (str) -> NormalizedName # This is taken from PEP 503. value = _canonicalize_regex.sub("-", name).lower() - return cast("NormalizedName", value) + return cast(NormalizedName, value) def canonicalize_version(version): @@ -65,3 +83,56 @@ def canonicalize_version(version): parts.append("+{0}".format(version.local)) return "".join(parts) + + +def parse_wheel_filename(filename): + # type: (str) -> Tuple[NormalizedName, Version, BuildTag, FrozenSet[Tag]] + if not filename.endswith(".whl"): + raise InvalidWheelFilename( + "Invalid wheel filename (extension must be '.whl'): {0}".format(filename) + ) + + filename = filename[:-4] + dashes = filename.count("-") + if dashes not in (4, 5): + raise InvalidWheelFilename( + "Invalid wheel filename (wrong number of parts): {0}".format(filename) + ) + + parts = filename.split("-", dashes - 2) + name_part = parts[0] + # See PEP 427 for the rules on escaping the project name + if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None: + raise InvalidWheelFilename("Invalid project name: {0}".format(filename)) + name = canonicalize_name(name_part) + version = Version(parts[1]) + if dashes == 5: + build_part = parts[2] + build_match = _build_tag_regex.match(build_part) + if build_match is None: + raise InvalidWheelFilename( + "Invalid build number: {0} in '{1}'".format(build_part, filename) + ) + build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2))) + else: + build = () + tags = parse_tag(parts[-1]) + return (name, version, build, tags) + + +def parse_sdist_filename(filename): + # type: (str) -> Tuple[NormalizedName, Version] + if not filename.endswith(".tar.gz"): + raise InvalidSdistFilename( + "Invalid sdist filename (extension must be '.tar.gz'): {0}".format(filename) + ) + + # We are requiring a PEP 440 version, which cannot contain dashes, + # so we split on the last dash. + name_part, sep, version_part = filename[:-7].rpartition("-") + if not sep: + raise InvalidSdistFilename("Invalid sdist filename: {0}".format(filename)) + + name = canonicalize_name(name_part) + version = Version(version_part) + return (name, version) @@ -1,6 +1,10 @@ [bdist_wheel] universal = 1 +[isort] +profile = black +combine_as_imports = true + [egg_info] tag_build = tag_date = 0 diff --git a/tests/test_markers.py b/tests/test_markers.py index 01e4aa6..3bdbffa 100644 --- a/tests/test_markers.py +++ b/tests/test_markers.py @@ -13,16 +13,15 @@ import pretend import pytest from packaging.markers import ( - Node, InvalidMarker, + Marker, + Node, UndefinedComparison, UndefinedEnvironmentName, - Marker, default_environment, format_full_version, ) - VARIABLES = [ "extra", "implementation_name", diff --git a/tests/test_requirements.py b/tests/test_requirements.py index 50e38d6..0213d6d 100644 --- a/tests/test_requirements.py +++ b/tests/test_requirements.py @@ -6,8 +6,7 @@ from __future__ import absolute_import, division, print_function import pytest from packaging.markers import Marker -from packaging.requirements import InvalidRequirement, Requirement, URL -from packaging.requirements import URL_AND_MARKER +from packaging.requirements import URL, URL_AND_MARKER, InvalidRequirement, Requirement from packaging.specifiers import SpecifierSet diff --git a/tests/test_specifiers.py b/tests/test_specifiers.py index c9a4446..41e93fe 100644 --- a/tests/test_specifiers.py +++ b/tests/test_specifiers.py @@ -17,8 +17,7 @@ from packaging.specifiers import ( ) from packaging.version import LegacyVersion, Version, parse -from .test_version import VERSIONS, LEGACY_VERSIONS - +from .test_version import LEGACY_VERSIONS, VERSIONS LEGACY_SPECIFIERS = [ "==2.1.0.3", diff --git a/tests/test_tags.py b/tests/test_tags.py index 2a79064..6b0e5b6 100644 --- a/tests/test_tags.py +++ b/tests/test_tags.py @@ -12,7 +12,6 @@ try: except ImportError: ctypes = None import distutils.util - import os import platform import re @@ -265,8 +264,14 @@ class TestMacOSPlatforms: platform, "mac_ver", lambda: ("10.14", ("", "", ""), "x86_64") ) version = platform.mac_ver()[0].split(".") - expected = "macosx_{major}_{minor}".format(major=version[0], minor=version[1]) + if version[0] == "10": + expected = "macosx_{major}_{minor}".format( + major=version[0], minor=version[1] + ) + else: + expected = "macosx_{major}_{minor}".format(major=version[0], minor=0) platforms = list(tags.mac_platforms(arch="x86_64")) + print(platforms, expected) assert platforms[0].startswith(expected) @pytest.mark.parametrize("arch", ["x86_64", "i386"]) @@ -312,6 +317,7 @@ class TestMacOSPlatforms: # with the environment variable SYSTEM_VERSION_COMPAT=1. assert "macosx_10_16_x86_64" in platforms assert "macosx_10_15_x86_64" in platforms + assert "macosx_10_15_universal2" in platforms assert "macosx_10_4_x86_64" in platforms assert "macosx_10_3_x86_64" not in platforms if major >= 12: @@ -324,6 +330,7 @@ class TestMacOSPlatforms: assert "macosx_11_3_arm64" not in platforms assert "macosx_11_0_universal" not in platforms assert "macosx_11_0_universal2" in platforms + assert "macosx_10_15_universal2" in platforms assert "macosx_10_15_x86_64" not in platforms assert "macosx_10_4_x86_64" not in platforms assert "macosx_10_3_x86_64" not in platforms diff --git a/tests/test_utils.py b/tests/test_utils.py index a8ea6bd..d2a7c91 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -5,7 +5,15 @@ from __future__ import absolute_import, division, print_function import pytest -from packaging.utils import canonicalize_name, canonicalize_version +from packaging.tags import Tag +from packaging.utils import ( + InvalidSdistFilename, + InvalidWheelFilename, + canonicalize_name, + canonicalize_version, + parse_sdist_filename, + parse_wheel_filename, +) from packaging.version import Version @@ -47,3 +55,63 @@ def test_canonicalize_name(name, expected): ) def test_canonicalize_version(version, expected): assert canonicalize_version(version) == expected + + +@pytest.mark.parametrize( + ("filename", "name", "version", "build", "tags"), + [ + ( + "foo-1.0-py3-none-any.whl", + "foo", + Version("1.0"), + (), + {Tag("py3", "none", "any")}, + ), + ( + "foo-1.0-1000-py3-none-any.whl", + "foo", + Version("1.0"), + (1000, ""), + {Tag("py3", "none", "any")}, + ), + ( + "foo-1.0-1000abc-py3-none-any.whl", + "foo", + Version("1.0"), + (1000, "abc"), + {Tag("py3", "none", "any")}, + ), + ], +) +def test_parse_wheel_filename(filename, name, version, build, tags): + assert parse_wheel_filename(filename) == (name, version, build, tags) + + +@pytest.mark.parametrize( + ("filename"), + [ + ("foo-1.0.whl"), # Missing tags + ("foo-1.0-py3-none-any.wheel"), # Incorrect file extension (`.wheel`) + ("foo__bar-1.0-py3-none-any.whl"), # Invalid name (`__`) + ("foo#bar-1.0-py3-none-any.whl"), # Invalid name (`#`) + # Build number doesn't start with a digit (`abc`) + ("foo-1.0-abc-py3-none-any.whl"), + ("foo-1.0-200-py3-none-any-junk.whl"), # Too many dashes (`-junk`) + ], +) +def test_parse_wheel_invalid_filename(filename): + with pytest.raises(InvalidWheelFilename): + parse_wheel_filename(filename) + + +@pytest.mark.parametrize( + ("filename", "name", "version"), [("foo-1.0.tar.gz", "foo", Version("1.0"))] +) +def test_parse_sdist_filename(filename, name, version): + assert parse_sdist_filename(filename) == (name, version) + + +@pytest.mark.parametrize(("filename"), [("foo-1.0.zip"), ("foo1.0.tar.gz")]) +def test_parse_sdist_invalid_filename(filename): + with pytest.raises(InvalidSdistFilename): + parse_sdist_filename(filename) diff --git a/tests/test_version.py b/tests/test_version.py index 961fca2..3d72281 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -10,7 +10,7 @@ import warnings import pretend import pytest -from packaging.version import Version, LegacyVersion, InvalidVersion, parse +from packaging.version import InvalidVersion, LegacyVersion, Version, parse @pytest.mark.parametrize( |
