summaryrefslogtreecommitdiff
diff options
authorMatthias Klose <doko@debian.org>2021-02-01 17:49:05 +0100
committergit-ubuntu importer <ubuntu-devel-discuss@lists.ubuntu.com>2021-02-01 22:42:33 +0000
commit6e09d260c64bc2be40f1c375d24bf7a5714bc4de (patch)
treea0787005b95cd69eec19e18200c36d35f0b73342
parent1bf04d679ff08c9e6d85b7123877e244ee2c5efd (diff)
parentb3a85ab7dd228e5f6b488afa4b78d867df7bd276 (diff)
20.9-1 (patches applied)applied/20.9-1
Imported using git-ubuntu import.
-rw-r--r--.pre-commit-config.yaml5
-rw-r--r--CHANGELOG.rst8
-rw-r--r--PKG-INFO10
-rw-r--r--debian/changelog6
-rw-r--r--docs/utils.rst53
-rw-r--r--packaging.egg-info/PKG-INFO10
-rw-r--r--packaging/__about__.py2
-rw-r--r--packaging/markers.py16
-rw-r--r--packaging/requirements.py17
-rw-r--r--packaging/specifiers.py4
-rw-r--r--packaging/tags.py26
-rw-r--r--packaging/utils.py75
-rw-r--r--setup.cfg4
-rw-r--r--tests/test_markers.py5
-rw-r--r--tests/test_requirements.py3
-rw-r--r--tests/test_specifiers.py3
-rw-r--r--tests/test_tags.py11
-rw-r--r--tests/test_utils.py70
-rw-r--r--tests/test_version.py2
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
~~~~~~~~~~~~~~~~~
diff --git a/PKG-INFO b/PKG-INFO
index 179f111..7865ede 100644
--- a/PKG-INFO
+++ b/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/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)
diff --git a/setup.cfg b/setup.cfg
index adf5ed7..e69dd12 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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(