Hello community,
here is the log from the commit of package python-packaging for
openSUSE:Factory checked in at 2019-08-27 15:22:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-packaging (Old)
and /work/SRC/openSUSE:Factory/.python-packaging.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-packaging"
Tue Aug 27 15:22:44 2019 rev:12 rq:724992 version:19.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-packaging/python-packaging.changes
2019-03-12 09:45:52.635628212 +0100
+++
/work/SRC/openSUSE:Factory/.python-packaging.new.7948/python-packaging.changes
2019-08-27 15:23:16.772783693 +0200
@@ -1,0 +2,38 @@
+Mon Aug 19 08:15:30 UTC 2019 - Dan Čermák <[email protected]>
+
+- Remove dependency on attrs
+ Add: 0005-Drop-dependency-on-attrs.patch
+ this fixes bsc#1144506
+
+-------------------------------------------------------------------
+Thu Aug 15 08:35:19 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Fix a bit the multibuild conversion
+- Remove the attrs from the deps as they are no longer needed
+
+-------------------------------------------------------------------
+Thu Aug 8 11:41:45 UTC 2019 - Dan Čermák <[email protected]>
+
+- Enable tests via _multibuild
+ Add patches from https://github.com/pypa/packaging/pull/176:
+ * 0001-Fix-test-failures-test_linux_platforms_manylinux-for.patch
+ * 0002-Fix-check-for-64-bit-OS.patch
+ * 0003-Add-additional-test-to-get-100-branch-coverage.patch
+ * 0004-Fix-test_macos_version_detection-failure-on-32-bit-L.patch
+ (these fix the tests on non-x86 platforms and can be dropped on the next
+ release)
+
+-------------------------------------------------------------------
+Thu Aug 8 10:24:07 UTC 2019 - Dan Čermák <[email protected]>
+
+- Add Requires:python-attrs as this is a new dependency
+ this fixes bsc#1144506
+
+-------------------------------------------------------------------
+Tue Aug 6 04:58:54 UTC 2019 - Thomas Bechtold <[email protected]>
+
+- update to 19.1:
+ * Add the ``packaging.tags`` module.
+ * Correctly handle two-digit versions in ``python_version``
+
+-------------------------------------------------------------------
Old:
----
packaging-19.0.tar.gz
New:
----
0001-Fix-test-failures-test_linux_platforms_manylinux-for.patch
0002-Fix-check-for-64-bit-OS.patch
0003-Add-additional-test-to-get-100-branch-coverage.patch
0004-Fix-test_macos_version_detection-failure-on-32-bit-L.patch
0005-Drop-dependency-on-attrs.patch
_multibuild
packaging-19.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-packaging.spec ++++++
--- /var/tmp/diff_new_pack.VRc75n/_old 2019-08-27 15:23:17.608783273 +0200
+++ /var/tmp/diff_new_pack.VRc75n/_new 2019-08-27 15:23:17.608783273 +0200
@@ -17,19 +17,31 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
+%global flavor @BUILD_FLAVOR@%{nil}
+%if "%{flavor}" == "test"
+%define psuffix -test
+%bcond_without test
+%else
+%define psuffix %{nil}
%bcond_with test
-Name: python-packaging
-Version: 19.0
+%endif
+Name: python-packaging%{psuffix}
+Version: 19.1
Release: 0
Summary: Core utilities for Python packages
License: Apache-2.0
Group: Development/Languages/Python
URL: https://github.com/pypa/packaging
Source:
https://pypi.io/packages/source/p/packaging/packaging-%{version}.tar.gz
+# FIXME: drop these patches on the next release after 19.1
+Patch0: 0001-Fix-test-failures-test_linux_platforms_manylinux-for.patch
+Patch1: 0002-Fix-check-for-64-bit-OS.patch
+Patch2: 0003-Add-additional-test-to-get-100-branch-coverage.patch
+Patch3: 0004-Fix-test_macos_version_detection-failure-on-32-bit-L.patch
+Patch4: 0005-Drop-dependency-on-attrs.patch
BuildRequires: %{python_module six}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
-# https://github.com/pypa/packaging/issues/91
Requires: python-pyparsing >= 2.0.2
Requires: python-six
BuildArch: noarch
@@ -49,12 +61,26 @@
%prep
%setup -q -n packaging-%{version}
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
# sdist must provide a packaging.egg-info, used below in install phase
test -d packaging.egg-info
+# FIXME: drop this on the next release after 19.1
+sed -i '/^attrs/d' packaging.egg-info/requires.txt
+
%build
%python_build
+%if %{with test}
+%check
+%pytest
+%endif # %%{with_test}
+
+%if !%{with test}
%install
%python_install
# Replace distutils generated egg-info, which varies in metadata version and
@@ -65,15 +91,12 @@
}
%python_expand %fdupes %{buildroot}%{$python_sitelib}
-%if %{with test}
-%check
-%python_exec %{_bindir}/py.test
-%endif
-
%files %{python_files}
%license LICENSE LICENSE.APACHE LICENSE.BSD
%doc CHANGELOG.rst README.rst
%{python_sitelib}/packaging
%{python_sitelib}/packaging-%{version}-py*.egg-info/
+%endif # !%%{with_test}
+
%changelog
++++++ 0001-Fix-test-failures-test_linux_platforms_manylinux-for.patch ++++++
>From ee35f4ff365c3a65872f2d2ba5320c6673a5859a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
Date: Thu, 8 Aug 2019 14:39:57 +0200
Subject: [PATCH 1/5] Fix test failures test_linux_platforms_manylinux* for non
x86_64
Theses tests are implicitly assuming that they are being run on x86_64 or i686,
but fail on ARM, PPC, etc.
---
tests/test_tags.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 0bb4fd6..1f1441e 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -511,7 +511,8 @@ def test_linux_platforms_manylinux1(monkeypatch):
if platform.system() != "Linux":
monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
platforms = tags._linux_platforms(is_32bit=False)
- assert platforms == ["manylinux1_x86_64", "linux_x86_64"]
+ arch = platform.machine()
+ assert platforms == ["manylinux1_" + arch, "linux_" + arch]
def test_linux_platforms_manylinux2010(monkeypatch):
@@ -521,7 +522,8 @@ def test_linux_platforms_manylinux2010(monkeypatch):
if platform.system() != "Linux":
monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
platforms = tags._linux_platforms(is_32bit=False)
- expected = ["manylinux2010_x86_64", "manylinux1_x86_64", "linux_x86_64"]
+ arch = platform.machine()
+ expected = ["manylinux2010_" + arch, "manylinux1_" + arch, "linux_" + arch]
assert platforms == expected
--
2.22.0
++++++ 0002-Fix-check-for-64-bit-OS.patch ++++++
>From 73c4a178654cf0ffe64d2f10155f7d7978f3622d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
Date: Thu, 8 Aug 2019 15:44:09 +0200
Subject: [PATCH 2/5] Fix check for 64 bit OS
distutils.util.get_platform() returns "linux-x86_64" on 64 bit Linux and not
"linux_86_64" as assumed by this function. Instead we use the first element
returned by platform.architecture() and move the check into a separate fixture.
Furthermore, we have to check whether the current OS is x86-based, as the
results don't match otherwise.
---
tests/test_tags.py | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 1f1441e..9ec30a4 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -11,6 +11,7 @@ except ImportError:
import distutils.util
import platform
+import re
import sys
import sysconfig
import types
@@ -26,6 +27,16 @@ def example_tag():
return tags.Tag("py3", "none", "any")
[email protected]
+def is_x86():
+ return re.match(r"(i\d86|x86_64)", platform.machine()) is not None
+
+
[email protected]
+def is_64bit_os():
+ return platform.architecture()[0] == "64bit"
+
+
def test_tag_lowercasing():
tag = tags.Tag("PY3", "None", "ANY")
assert tag.interpreter == "py3"
@@ -486,18 +497,16 @@ def test_have_compatible_glibc(monkeypatch):
assert not tags._have_compatible_glibc(2, 4)
-def test_linux_platforms_64bit_on_64bit_os(monkeypatch):
- is_64bit_os = distutils.util.get_platform().endswith("_x86_64")
- if platform.system() != "Linux" or not is_64bit_os:
+def test_linux_platforms_64bit_on_64bit_os(is_64bit_os, is_x86, monkeypatch):
+ if platform.system() != "Linux" or not is_64bit_os or not is_x86:
monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
monkeypatch.setattr(tags, "_is_manylinux_compatible", lambda *args:
False)
linux_platform = tags._linux_platforms(is_32bit=False)[-1]
assert linux_platform == "linux_x86_64"
-def test_linux_platforms_32bit_on_64bit_os(monkeypatch):
- is_64bit_os = distutils.util.get_platform().endswith("_x86_64")
- if platform.system() != "Linux" or not is_64bit_os:
+def test_linux_platforms_32bit_on_64bit_os(is_64bit_os, is_x86, monkeypatch):
+ if platform.system() != "Linux" or not is_64bit_os or not is_x86:
monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
monkeypatch.setattr(tags, "_is_manylinux_compatible", lambda *args:
False)
linux_platform = tags._linux_platforms(is_32bit=True)[-1]
--
2.22.0
++++++ 0003-Add-additional-test-to-get-100-branch-coverage.patch ++++++
>From e25b14f0ab054dbde4c2bf274f938a0f74ebb823 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
Date: Thu, 8 Aug 2019 15:45:12 +0200
Subject: [PATCH 3/5] Add additional test to get 100% branch coverage
the else: branch was not covered in tags._linux_platforms() due to the from the
previous commit
---
tests/test_tags.py | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 9ec30a4..5ffbfa5 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -513,6 +513,13 @@ def test_linux_platforms_32bit_on_64bit_os(is_64bit_os,
is_x86, monkeypatch):
assert linux_platform == "linux_i686"
+def test_linux_platforms_manylinux_unsupported(monkeypatch):
+ monkeypatch.setattr(distutils.util, "get_platform", lambda: "linux_x86_64")
+ monkeypatch.setattr(tags, "_is_manylinux_compatible", lambda *args: False)
+ linux_platform = tags._linux_platforms(is_32bit=False)
+ assert linux_platform == ["linux_x86_64"]
+
+
def test_linux_platforms_manylinux1(monkeypatch):
monkeypatch.setattr(
tags, "_is_manylinux_compatible", lambda name, _: name == "manylinux1"
--
2.22.0
++++++ 0004-Fix-test_macos_version_detection-failure-on-32-bit-L.patch ++++++
>From d691f8387975b426585bb197fc3f8d8ad6ba02c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
Date: Thu, 8 Aug 2019 15:54:48 +0200
Subject: [PATCH 4/5] Fix test_macos_version_detection failure on 32 bit Linux
tags._mac_arch always returns i386 on 32 bit Linux and thereby
tags._mac_platforms()[0] ends with "i386" even in the arch="x86_64" case
---
tests/test_tags.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 5ffbfa5..0e5b0c6 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -183,6 +183,7 @@ def test_macos_version_detection(monkeypatch):
def test_macos_arch_detection(arch, monkeypatch):
if platform.system() != "Darwin" or platform.mac_ver()[2] != arch:
monkeypatch.setattr(platform, "mac_ver", lambda: ("10.14", ("", "",
""), arch))
+ monkeypatch.setattr(tags, "_mac_arch", lambda *args: arch)
assert tags._mac_platforms((10, 14))[0].endswith(arch)
--
2.22.0
++++++ 0005-Drop-dependency-on-attrs.patch ++++++
>From 3731ce275df3061d84a6014ec732747e5ae5819e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= <[email protected]>
Date: Tue, 13 Aug 2019 11:57:09 +0200
Subject: [PATCH 5/5] Drop dependency on attrs
- replace tags.Tag with a custom implementation instead of using @attr.s
- add a sanity check for __hash__()
- drop attrs from setup.py
This fixes #178
---
packaging/tags.py | 37 ++++++++++++++++++++++++++++++-------
setup.py | 2 +-
tests/test_tags.py | 6 ++++++
3 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/packaging/tags.py b/packaging/tags.py
index c472b58..c9b5119 100644
--- a/packaging/tags.py
+++ b/packaging/tags.py
@@ -11,8 +11,6 @@ import sys
import sysconfig
import warnings
-import attr
-
INTERPRETER_SHORT_NAMES = {
"python": "py", # Generic.
@@ -26,14 +24,39 @@ INTERPRETER_SHORT_NAMES = {
_32_BIT_INTERPRETER = sys.maxsize <= 2 ** 32
[email protected](frozen=True, repr=False)
class Tag(object):
- interpreter = attr.ib(converter=str.lower)
- abi = attr.ib(converter=str.lower)
- platform = attr.ib(converter=str.lower)
+
+ __slots__ = ["_interpreter", "_abi", "_platform"]
+
+ def __init__(self, interpreter, abi, platform):
+ self._interpreter = str.lower(interpreter)
+ self._abi = str.lower(abi)
+ self._platform = str.lower(platform)
+
+ @property
+ def interpreter(self):
+ return self._interpreter
+
+ @property
+ def abi(self):
+ return self._abi
+
+ @property
+ def platform(self):
+ return self._platform
+
+ def __eq__(self, other):
+ return (
+ (self.platform == other.platform)
+ and (self.abi == other.abi)
+ and (self.interpreter == other.interpreter)
+ )
+
+ def __hash__(self):
+ return hash((self._interpreter, self._abi, self._platform))
def __str__(self):
- return "{}-{}-{}".format(self.interpreter, self.abi, self.platform)
+ return "{}-{}-{}".format(self._interpreter, self._abi, self._platform)
def __repr__(self):
return "<{self} @ {self_id}>".format(self=self, self_id=id(self))
diff --git a/setup.py b/setup.py
index 874512b..23007c7 100644
--- a/setup.py
+++ b/setup.py
@@ -48,7 +48,7 @@ setup(
author=about["__author__"],
author_email=about["__email__"],
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
- install_requires=["attrs", "pyparsing>=2.0.2", "six"], # Needed to avoid
issue #91
+ install_requires=["pyparsing>=2.0.2", "six"], # Needed to avoid issue #91
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
diff --git a/tests/test_tags.py b/tests/test_tags.py
index 0bb4fd6..a6d50f3 100644
--- a/tests/test_tags.py
+++ b/tests/test_tags.py
@@ -43,6 +43,12 @@ def test_tag_hashing(example_tag):
assert example_tag in tags
+def test_tag_hash_equality(example_tag):
+ equal_tag = tags.Tag("py3", "none", "any")
+ assert example_tag == equal_tag
+ assert example_tag.__hash__() == equal_tag.__hash__()
+
+
def test_tag_str(example_tag):
assert str(example_tag) == "py3-none-any"
--
2.22.0
++++++ _multibuild ++++++
<multibuild>
<package>test</package>
</multibuild>
++++++ packaging-19.0.tar.gz -> packaging-19.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/.coveragerc
new/packaging-19.1/.coveragerc
--- old/packaging-19.0/.coveragerc 2018-06-07 12:16:39.000000000 +0200
+++ new/packaging-19.1/.coveragerc 2019-07-20 07:03:21.000000000 +0200
@@ -4,5 +4,6 @@
[report]
exclude_lines =
+ pragma: no cover
@abc.abstractmethod
@abc.abstractproperty
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/CHANGELOG.rst
new/packaging-19.1/CHANGELOG.rst
--- old/packaging-19.0/CHANGELOG.rst 2019-01-20 12:04:06.000000000 +0100
+++ new/packaging-19.1/CHANGELOG.rst 2019-07-30 08:28:22.000000000 +0200
@@ -1,6 +1,14 @@
Changelog
---------
+19.1 - 2019-07-30
+~~~~~~~~~~~~~~~~~
+
+* Add the ``packaging.tags`` module. (:issue:`156`)
+
+* Correctly handle two-digit versions in ``python_version`` (:issue:`119`)
+
+
19.0 - 2019-01-20
~~~~~~~~~~~~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/PKG-INFO new/packaging-19.1/PKG-INFO
--- old/packaging-19.0/PKG-INFO 2019-01-20 12:04:40.000000000 +0100
+++ new/packaging-19.1/PKG-INFO 2019-07-30 08:32:32.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: packaging
-Version: 19.0
+Version: 19.1
Summary: Core utilities for Python packages
Home-page: https://github.com/pypa/packaging
Author: Donald Stufft and individual contributors
@@ -9,14 +9,29 @@
Description: packaging
=========
- Core utilities for Python packages
+ Core utilities for Python packages.
+ The ``packaging`` project includes the following: version handling,
specifiers,
+ markers, requirements, tags, utilities.
Documentation
-------------
- `documentation`_
+ The `documentation`_ provides information and the API for the
following:
+ - Version Handling
+ - Specifiers
+ - Markers
+ - Requirements
+ - Tags
+ - Utilities
+
+ Installation
+ ------------
+
+ Use ``pip`` to install these utilities::
+
+ pip install packaging
Discussion
----------
@@ -38,9 +53,35 @@
.. _PyPA Code of Conduct:
https://www.pypa.io/en/latest/code-of-conduct/
+ Contributing
+ ------------
+
+ The ``CONTRIBUTING.rst`` file outlines how to contribute to this
project as
+ well as how to report a potential security issue. The documentation
for this
+ project also covers information about `project development`_ and
`security`_.
+
+ .. _`project development`:
https://packaging.pypa.io/en/latest/development/
+ .. _`security`: https://packaging.pypa.io/en/latest/security/
+
+ Project History
+ ---------------
+
+ Please review the ``CHANGELOG.rst`` file or the `Changelog
documentation`_ for
+ recent changes and project history.
+
+ .. _`Changelog documentation`:
https://packaging.pypa.io/en/latest/changelog/
+
Changelog
---------
+ 19.1 - 2019-07-30
+ ~~~~~~~~~~~~~~~~~
+
+ * Add the ``packaging.tags`` module. (`#156
<https://github.com/pypa/packaging/issues/156>`__)
+
+ * Correctly handle two-digit versions in ``python_version`` (`#119
<https://github.com/pypa/packaging/issues/119>`__)
+
+
19.0 - 2019-01-20
~~~~~~~~~~~~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/README.rst
new/packaging-19.1/README.rst
--- old/packaging-19.0/README.rst 2018-06-07 12:16:39.000000000 +0200
+++ new/packaging-19.1/README.rst 2019-07-30 08:26:09.000000000 +0200
@@ -1,14 +1,29 @@
packaging
=========
-Core utilities for Python packages
+Core utilities for Python packages.
+The ``packaging`` project includes the following: version handling, specifiers,
+markers, requirements, tags, utilities.
Documentation
-------------
-`documentation`_
+The `documentation`_ provides information and the API for the following:
+- Version Handling
+- Specifiers
+- Markers
+- Requirements
+- Tags
+- Utilities
+
+Installation
+------------
+
+Use ``pip`` to install these utilities::
+
+ pip install packaging
Discussion
----------
@@ -29,3 +44,21 @@
rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_.
.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/
+
+Contributing
+------------
+
+The ``CONTRIBUTING.rst`` file outlines how to contribute to this project as
+well as how to report a potential security issue. The documentation for this
+project also covers information about `project development`_ and `security`_.
+
+.. _`project development`: https://packaging.pypa.io/en/latest/development/
+.. _`security`: https://packaging.pypa.io/en/latest/security/
+
+Project History
+---------------
+
+Please review the ``CHANGELOG.rst`` file or the `Changelog documentation`_ for
+recent changes and project history.
+
+.. _`Changelog documentation`: https://packaging.pypa.io/en/latest/changelog/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/docs/index.rst
new/packaging-19.1/docs/index.rst
--- old/packaging-19.0/docs/index.rst 2018-06-07 12:16:39.000000000 +0200
+++ new/packaging-19.1/docs/index.rst 2019-07-20 07:03:21.000000000 +0200
@@ -24,6 +24,7 @@
specifiers
markers
requirements
+ tags
utils
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/docs/security.rst
new/packaging-19.1/docs/security.rst
--- old/packaging-19.0/docs/security.rst 2018-06-07 12:16:39.000000000
+0200
+++ new/packaging-19.1/docs/security.rst 2019-07-30 08:26:09.000000000
+0200
@@ -1,12 +1,18 @@
Security
========
-We take the security of packaging seriously. If you believe you've
-identified a security issue in it, please report it to
-``[email protected]``. Message may be encrypted with PGP using key
-fingerprint ``7C6B 7C5D 5E2B 6356 A926 F04F 6E3C BCE9 3372 DCFA`` (this public
-key is available from most commonly-used key servers).
+We take the security of packaging seriously. If you believe you've identified a
+security issue in it, DO NOT report the issue in any public forum, including
+(but not limited to):
+
+- GitHub issue tracker
+- Official or unofficial chat channels
+- Official or unofficial mailing lists
+
+Please report your issue to ``[email protected]``. Messages may be optionally
+encrypted with GPG using key fingerprints available at the `Python Security
+page <https://www.python.org/news/security/>`_.
Once you've submitted an issue via email, you should receive an acknowledgment
within 48 hours, and depending on the action to be taken, you may receive
-further follow-up emails.
\ No newline at end of file
+further follow-up emails.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/docs/tags.rst
new/packaging-19.1/docs/tags.rst
--- old/packaging-19.0/docs/tags.rst 1970-01-01 01:00:00.000000000 +0100
+++ new/packaging-19.1/docs/tags.rst 2019-07-20 07:03:21.000000000 +0200
@@ -0,0 +1,101 @@
+Tags
+====
+
+.. currentmodule:: packaging.tags
+
+Wheels encode the Python interpreter, ABI, and platform that they support in
+their filenames using *`platform compatibility tags`_*. This module provides
+support for both parsing these tags as well as discovering what tags the
+running Python interpreter supports.
+
+Usage
+-----
+
+.. doctest::
+
+ >>> from packaging.tags import Tag, sys_tags
+ >>> import sys
+ >>> looking_for = Tag("py{major}".format(major=sys.version_info.major),
"none", "any")
+ >>> supported_tags = list(sys_tags())
+ >>> looking_for in supported_tags
+ True
+ >>> really_old = Tag("py1", "none", "any")
+ >>> wheels = {really_old, looking_for}
+ >>> best_wheel = None
+ >>> for supported_tag in supported_tags:
+ ... for wheel_tag in wheels:
+ ... if supported_tag == wheel_tag:
+ ... best_wheel = wheel_tag
+ ... break
+ >>> best_wheel == looking_for
+ True
+
+Reference
+---------
+
+.. attribute:: INTERPRETER_SHORT_NAMES
+
+ A dictionary mapping interpreter names to their `abbreviation codes`_
+ (e.g. ``"cpython"`` is ``"cp"``). All interpreter names are lower-case.
+
+.. class:: Tag(interpreter, abi, platform)
+
+ A representation of the tag triple for a wheel. Instances are considered
+ immutable and thus are hashable. Equality checking is also supported.
+
+ :param str interpreter: The interpreter name, e.g. ``"py"``
+ (see :attr:`INTERPRETER_SHORT_NAMES` for mapping
+ well-known interpreter names to their short names).
+ :param str abi: The ABI that a wheel supports, e.g. ``"cp37m"``.
+ :param str platform: The OS/platform the wheel supports,
+ e.g. ``"win_amd64"``.
+
+ .. attribute:: interpreter
+
+ The interpreter name.
+
+ .. attribute:: abi
+
+ The supported ABI.
+
+ .. attribute:: platform
+
+ The OS/platform.
+
+
+.. function:: parse_tag(tag)
+
+ Parse the provided *tag* into a set of :class:`Tag` instances.
+
+ The returning of a set is required due to the possibility that the tag is a
+ `compressed tag set`_, e.g. ``"py2.py3-none-any"``.
+
+ :param str tag: The tag to parse, e.g. ``"py3-none-any"``.
+
+
+.. function:: sys_tags()
+
+ Create an iterable of tags that the running interpreter supports.
+
+ The iterable is ordered so that the best-matching tag is first in the
+ sequence. The exact preferential order to tags is interpreter-specific, but
+ in general the tag importance is in the order of:
+
+ 1. Interpreter
+ 2. Platform
+ 3. ABI
+
+ This order is due to the fact that an ABI is inherently tied to the
+ platform, but platform-specific code is not necessarily tied to the ABI.
The
+ interpreter is the most important tag as it dictates basic support for any
+ wheel.
+
+ The function returns an iterable in order to allow for the possible
+ short-circuiting of tag generation if the entire sequence is not necessary
+ and calculating some tags happens to be expensive.
+
+
+.. _abbreviation codes: https://www.python.org/dev/peps/pep-0425/#python-tag
+.. _compressed tag set:
https://www.python.org/dev/peps/pep-0425/#compressed-tag-sets
+.. _platform compatibility tags:
https://packaging.python.org/specifications/platform-compatibility-tags/
+.. _PEP 425: https://www.python.org/dev/peps/pep-0425/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/packaging/__about__.py
new/packaging-19.1/packaging/__about__.py
--- old/packaging-19.0/packaging/__about__.py 2019-01-20 12:04:06.000000000
+0100
+++ new/packaging-19.1/packaging/__about__.py 2019-07-30 08:28:34.000000000
+0200
@@ -18,7 +18,7 @@
__summary__ = "Core utilities for Python packages"
__uri__ = "https://github.com/pypa/packaging"
-__version__ = "19.0"
+__version__ = "19.1"
__author__ = "Donald Stufft and individual contributors"
__email__ = "[email protected]"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/packaging/markers.py
new/packaging-19.1/packaging/markers.py
--- old/packaging-19.0/packaging/markers.py 2019-01-20 11:44:35.000000000
+0100
+++ new/packaging-19.1/packaging/markers.py 2019-07-30 08:26:09.000000000
+0200
@@ -259,7 +259,7 @@
"platform_version": platform.version(),
"python_full_version": platform.python_version(),
"platform_python_implementation": platform.python_implementation(),
- "python_version": platform.python_version()[:3],
+ "python_version": ".".join(platform.python_version_tuple()[:2]),
"sys_platform": sys.platform,
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/packaging/tags.py
new/packaging-19.1/packaging/tags.py
--- old/packaging-19.0/packaging/tags.py 1970-01-01 01:00:00.000000000
+0100
+++ new/packaging-19.1/packaging/tags.py 2019-07-20 07:03:21.000000000
+0200
@@ -0,0 +1,354 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+from __future__ import absolute_import
+
+import distutils.util
+import platform
+import re
+import sys
+import sysconfig
+import warnings
+
+import attr
+
+
+INTERPRETER_SHORT_NAMES = {
+ "python": "py", # Generic.
+ "cpython": "cp",
+ "pypy": "pp",
+ "ironpython": "ip",
+ "jython": "jy",
+}
+
+
+_32_BIT_INTERPRETER = sys.maxsize <= 2 ** 32
+
+
[email protected](frozen=True, repr=False)
+class Tag(object):
+ interpreter = attr.ib(converter=str.lower)
+ abi = attr.ib(converter=str.lower)
+ platform = attr.ib(converter=str.lower)
+
+ def __str__(self):
+ return "{}-{}-{}".format(self.interpreter, self.abi, self.platform)
+
+ def __repr__(self):
+ return "<{self} @ {self_id}>".format(self=self, self_id=id(self))
+
+
+def parse_tag(tag):
+ tags = set()
+ interpreters, abis, platforms = tag.split("-")
+ for interpreter in interpreters.split("."):
+ for abi in abis.split("."):
+ for platform_ in platforms.split("."):
+ tags.add(Tag(interpreter, abi, platform_))
+ return frozenset(tags)
+
+
+def _normalize_string(string):
+ return string.replace(".", "_").replace("-", "_")
+
+
+def _cpython_interpreter(py_version):
+ # TODO: Is using py_version_nodot for interpreter version critical?
+ return "cp{major}{minor}".format(major=py_version[0], minor=py_version[1])
+
+
+# TODO: This code is simpler compared to pep425tags as CPython 2.7 didn't seem
+# to need the fallbacks. Is that acceptable?
+def _cpython_abi(py_version):
+ soabi = sysconfig.get_config_var("SOABI")
+ if soabi:
+ options = soabi.split("-", 2)[1]
+ else:
+ found_options = [str(py_version[0]), str(py_version[1])]
+ if sysconfig.get_config_var("Py_DEBUG"):
+ found_options.append("d")
+ if sysconfig.get_config_var("WITH_PYMALLOC"):
+ found_options.append("m")
+ if sysconfig.get_config_var("Py_UNICODE_SIZE") == 4:
+ found_options.append("u")
+ options = "".join(found_options)
+ return "cp{options}".format(options=options)
+
+
+def _cpython_tags(py_version, interpreter, abi, platforms):
+ for tag in (Tag(interpreter, abi, platform) for platform in platforms):
+ yield tag
+ for tag in (Tag(interpreter, "abi3", platform) for platform in platforms):
+ yield tag
+ for tag in (Tag(interpreter, "none", platform) for platform in platforms):
+ yield tag
+ # PEP 384 was first implemented in Python 3.2.
+ for minor_version in range(py_version[1] - 1, 1, -1):
+ for platform_ in platforms:
+ interpreter = "cp{major}{minor}".format(
+ major=py_version[0], minor=minor_version
+ )
+ yield Tag(interpreter, "abi3", platform_)
+
+
+def _pypy_interpreter():
+ return "pp{py_major}{pypy_major}{pypy_minor}".format(
+ py_major=sys.version_info[0],
+ pypy_major=sys.pypy_version_info.major,
+ pypy_minor=sys.pypy_version_info.minor,
+ )
+
+
+def _generic_abi():
+ abi = sysconfig.get_config_var("SOABI")
+ if abi:
+ return _normalize_string(abi)
+ else:
+ return "none"
+
+
+def _pypy_tags(py_version, interpreter, abi, platforms):
+ for tag in (Tag(interpreter, abi, platform) for platform in platforms):
+ yield tag
+ for tag in (Tag(interpreter, "none", platform) for platform in platforms):
+ yield tag
+
+
+def _generic_tags(interpreter, py_version, abi, platforms):
+ for tag in (Tag(interpreter, abi, platform) for platform in platforms):
+ yield tag
+ if abi != "none":
+ tags = (Tag(interpreter, "none", platform_) for platform_ in platforms)
+ for tag in tags:
+ yield tag
+
+
+def _py_interpreter_range(py_version):
+ """
+ Yield Python versions in descending order.
+
+ After the latest version, the major-only version will be yielded, and then
+ all following versions up to 'end'.
+ """
+ yield "py{major}{minor}".format(major=py_version[0], minor=py_version[1])
+ yield "py{major}".format(major=py_version[0])
+ for minor in range(py_version[1] - 1, -1, -1):
+ yield "py{major}{minor}".format(major=py_version[0], minor=minor)
+
+
+def _independent_tags(interpreter, py_version, platforms):
+ """
+ Return the sequence of tags that are consistent across implementations.
+
+ The tags consist of:
+ - py*-none-<platform>
+ - <interpreter>-none-any
+ - py*-none-any
+ """
+ for version in _py_interpreter_range(py_version):
+ for platform_ in platforms:
+ yield Tag(version, "none", platform_)
+ yield Tag(interpreter, "none", "any")
+ for version in _py_interpreter_range(py_version):
+ yield Tag(version, "none", "any")
+
+
+def _mac_arch(arch, is_32bit=_32_BIT_INTERPRETER):
+ if is_32bit:
+ if arch.startswith("ppc"):
+ return "ppc"
+ else:
+ return "i386"
+ else:
+ return arch
+
+
+def _mac_binary_formats(version, cpu_arch):
+ formats = [cpu_arch]
+ if cpu_arch == "x86_64":
+ if version >= (10, 4):
+ formats.extend(["intel", "fat64", "fat32"])
+ else:
+ return []
+ elif cpu_arch == "i386":
+ if version >= (10, 4):
+ formats.extend(["intel", "fat32", "fat"])
+ else:
+ return []
+ elif cpu_arch == "ppc64":
+ # TODO: Need to care about 32-bit PPC for ppc64 through 10.2?
+ if version > (10, 5) or version < (10, 4):
+ return []
+ else:
+ formats.append("fat64")
+ elif cpu_arch == "ppc":
+ if version <= (10, 6):
+ formats.extend(["fat32", "fat"])
+ else:
+ return []
+
+ formats.append("universal")
+ return formats
+
+
+def _mac_platforms(version=None, arch=None):
+ version_str, _, cpu_arch = platform.mac_ver()
+ if version is None:
+ version = tuple(map(int, version_str.split(".")[:2]))
+ if arch is None:
+ arch = _mac_arch(cpu_arch)
+ platforms = []
+ for minor_version in range(version[1], -1, -1):
+ compat_version = version[0], minor_version
+ binary_formats = _mac_binary_formats(compat_version, arch)
+ for binary_format in binary_formats:
+ platforms.append(
+ "macosx_{major}_{minor}_{binary_format}".format(
+ major=compat_version[0],
+ minor=compat_version[1],
+ binary_format=binary_format,
+ )
+ )
+ return platforms
+
+
+# From PEP 513.
+def _is_manylinux_compatible(name, glibc_version):
+ # Check for presence of _manylinux module.
+ try:
+ import _manylinux
+
+ return bool(getattr(_manylinux, name + "_compatible"))
+ except (ImportError, AttributeError):
+ # Fall through to heuristic check below.
+ pass
+
+ return _have_compatible_glibc(*glibc_version)
+
+
+def _glibc_version_string():
+ # Returns glibc version string, or None if not using glibc.
+ import ctypes
+
+ # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
+ # manpage says, "If filename is NULL, then the returned handle is for the
+ # main program". This way we can let the linker do the work to figure out
+ # which libc our process is actually using.
+ process_namespace = ctypes.CDLL(None)
+ try:
+ gnu_get_libc_version = process_namespace.gnu_get_libc_version
+ except AttributeError:
+ # Symbol doesn't exist -> therefore, we are not linked to
+ # glibc.
+ return None
+
+ # Call gnu_get_libc_version, which returns a string like "2.5"
+ gnu_get_libc_version.restype = ctypes.c_char_p
+ version_str = gnu_get_libc_version()
+ # py2 / py3 compatibility:
+ if not isinstance(version_str, str):
+ version_str = version_str.decode("ascii")
+
+ return version_str
+
+
+# Separated out from have_compatible_glibc for easier unit testing.
+def _check_glibc_version(version_str, required_major, minimum_minor):
+ # Parse string and check against requested version.
+ #
+ # We use a regexp instead of str.split because we want to discard any
+ # random junk that might come after the minor version -- this might happen
+ # in patched/forked versions of glibc (e.g. Linaro's version of glibc
+ # uses version strings like "2.20-2014.11"). See gh-3588.
+ m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
+ if not m:
+ warnings.warn(
+ "Expected glibc version with 2 components major.minor,"
+ " got: %s" % version_str,
+ RuntimeWarning,
+ )
+ return False
+ return (
+ int(m.group("major")) == required_major
+ and int(m.group("minor")) >= minimum_minor
+ )
+
+
+def _have_compatible_glibc(required_major, minimum_minor):
+ version_str = _glibc_version_string()
+ if version_str is None:
+ return False
+ return _check_glibc_version(version_str, required_major, minimum_minor)
+
+
+def _linux_platforms(is_32bit=_32_BIT_INTERPRETER):
+ linux = _normalize_string(distutils.util.get_platform())
+ if linux == "linux_x86_64" and is_32bit:
+ linux = "linux_i686"
+ # manylinux1: CentOS 5 w/ glibc 2.5.
+ # manylinux2010: CentOS 6 w/ glibc 2.12.
+ manylinux_support = ("manylinux2010", (2, 12)), ("manylinux1", (2, 5))
+ manylinux_support_iter = iter(manylinux_support)
+ for name, glibc_version in manylinux_support_iter:
+ if _is_manylinux_compatible(name, glibc_version):
+ platforms = [linux.replace("linux", name)]
+ break
+ else:
+ platforms = []
+ # Support for a later manylinux implies support for an earlier version.
+ platforms += [linux.replace("linux", name) for name, _ in
manylinux_support_iter]
+ platforms.append(linux)
+ return platforms
+
+
+def _generic_platforms():
+ platform = _normalize_string(distutils.util.get_platform())
+ return [platform]
+
+
+def _interpreter_name():
+ name = platform.python_implementation().lower()
+ return INTERPRETER_SHORT_NAMES.get(name) or name
+
+
+def _generic_interpreter(name, py_version):
+ version = sysconfig.get_config_var("py_version_nodot")
+ if not version:
+ version = "".join(map(str, py_version[:2]))
+ return "{name}{version}".format(name=name, version=version)
+
+
+def sys_tags():
+ """
+ Returns the sequence of tag triples for the running interpreter.
+
+ The order of the sequence corresponds to priority order for the
+ interpreter, from most to least important.
+ """
+ py_version = sys.version_info[:2]
+ interpreter_name = _interpreter_name()
+ if platform.system() == "Darwin":
+ platforms = _mac_platforms()
+ elif platform.system() == "Linux":
+ platforms = _linux_platforms()
+ else:
+ platforms = _generic_platforms()
+
+ if interpreter_name == "cp":
+ interpreter = _cpython_interpreter(py_version)
+ abi = _cpython_abi(py_version)
+ for tag in _cpython_tags(py_version, interpreter, abi, platforms):
+ yield tag
+ elif interpreter_name == "pp":
+ interpreter = _pypy_interpreter()
+ abi = _generic_abi()
+ for tag in _pypy_tags(py_version, interpreter, abi, platforms):
+ yield tag
+ else:
+ interpreter = _generic_interpreter(interpreter_name, py_version)
+ abi = _generic_abi()
+ for tag in _generic_tags(interpreter, py_version, abi, platforms):
+ yield tag
+ for tag in _independent_tags(interpreter, py_version, platforms):
+ yield tag
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/packaging.egg-info/PKG-INFO
new/packaging-19.1/packaging.egg-info/PKG-INFO
--- old/packaging-19.0/packaging.egg-info/PKG-INFO 2019-01-20
12:04:40.000000000 +0100
+++ new/packaging-19.1/packaging.egg-info/PKG-INFO 2019-07-30
08:32:32.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.2
Name: packaging
-Version: 19.0
+Version: 19.1
Summary: Core utilities for Python packages
Home-page: https://github.com/pypa/packaging
Author: Donald Stufft and individual contributors
@@ -9,14 +9,29 @@
Description: packaging
=========
- Core utilities for Python packages
+ Core utilities for Python packages.
+ The ``packaging`` project includes the following: version handling,
specifiers,
+ markers, requirements, tags, utilities.
Documentation
-------------
- `documentation`_
+ The `documentation`_ provides information and the API for the
following:
+ - Version Handling
+ - Specifiers
+ - Markers
+ - Requirements
+ - Tags
+ - Utilities
+
+ Installation
+ ------------
+
+ Use ``pip`` to install these utilities::
+
+ pip install packaging
Discussion
----------
@@ -38,9 +53,35 @@
.. _PyPA Code of Conduct:
https://www.pypa.io/en/latest/code-of-conduct/
+ Contributing
+ ------------
+
+ The ``CONTRIBUTING.rst`` file outlines how to contribute to this
project as
+ well as how to report a potential security issue. The documentation
for this
+ project also covers information about `project development`_ and
`security`_.
+
+ .. _`project development`:
https://packaging.pypa.io/en/latest/development/
+ .. _`security`: https://packaging.pypa.io/en/latest/security/
+
+ Project History
+ ---------------
+
+ Please review the ``CHANGELOG.rst`` file or the `Changelog
documentation`_ for
+ recent changes and project history.
+
+ .. _`Changelog documentation`:
https://packaging.pypa.io/en/latest/changelog/
+
Changelog
---------
+ 19.1 - 2019-07-30
+ ~~~~~~~~~~~~~~~~~
+
+ * Add the ``packaging.tags`` module. (`#156
<https://github.com/pypa/packaging/issues/156>`__)
+
+ * Correctly handle two-digit versions in ``python_version`` (`#119
<https://github.com/pypa/packaging/issues/119>`__)
+
+
19.0 - 2019-01-20
~~~~~~~~~~~~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/packaging.egg-info/SOURCES.txt
new/packaging-19.1/packaging.egg-info/SOURCES.txt
--- old/packaging-19.0/packaging.egg-info/SOURCES.txt 2019-01-20
12:04:40.000000000 +0100
+++ new/packaging-19.1/packaging.egg-info/SOURCES.txt 2019-07-30
08:32:32.000000000 +0200
@@ -18,6 +18,7 @@
docs/requirements.rst
docs/security.rst
docs/specifiers.rst
+docs/tags.rst
docs/utils.rst
docs/version.rst
docs/_static/.empty
@@ -33,6 +34,7 @@
packaging/markers.py
packaging/requirements.py
packaging/specifiers.py
+packaging/tags.py
packaging/utils.py
packaging/version.py
packaging.egg-info/PKG-INFO
@@ -45,5 +47,6 @@
tests/test_requirements.py
tests/test_specifiers.py
tests/test_structures.py
+tests/test_tags.py
tests/test_utils.py
tests/test_version.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/packaging.egg-info/requires.txt
new/packaging-19.1/packaging.egg-info/requires.txt
--- old/packaging-19.0/packaging.egg-info/requires.txt 2019-01-20
12:04:40.000000000 +0100
+++ new/packaging-19.1/packaging.egg-info/requires.txt 2019-07-30
08:32:32.000000000 +0200
@@ -1,2 +1,3 @@
+attrs
pyparsing>=2.0.2
six
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/setup.py new/packaging-19.1/setup.py
--- old/packaging-19.0/setup.py 2019-01-20 11:44:35.000000000 +0100
+++ new/packaging-19.1/setup.py 2019-07-20 07:17:29.000000000 +0200
@@ -48,7 +48,7 @@
author=about["__author__"],
author_email=about["__email__"],
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
- install_requires=["pyparsing>=2.0.2", "six"], # Needed to avoid issue #91
+ install_requires=["attrs", "pyparsing>=2.0.2", "six"], # Needed to avoid
issue #91
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/tests/test_markers.py
new/packaging-19.1/tests/test_markers.py
--- old/packaging-19.0/tests/test_markers.py 2019-01-20 11:44:35.000000000
+0100
+++ new/packaging-19.1/tests/test_markers.py 2019-07-30 08:26:09.000000000
+0200
@@ -112,7 +112,7 @@
"platform_version": platform.version(),
"python_full_version": platform.python_version(),
"platform_python_implementation": platform.python_implementation(),
- "python_version": platform.python_version()[:3],
+ "python_version": ".".join(platform.python_version_tuple()[:2]),
"sys_platform": sys.platform,
}
@@ -134,7 +134,7 @@
"platform_version": platform.version(),
"python_full_version": platform.python_version(),
"platform_python_implementation": platform.python_implementation(),
- "python_version": platform.python_version()[:3],
+ "python_version": ".".join(platform.python_version_tuple()[:2]),
"sys_platform": sys.platform,
}
@@ -162,7 +162,7 @@
"platform_version": platform.version(),
"python_full_version": platform.python_version(),
"platform_python_implementation": platform.python_implementation(),
- "python_version": platform.python_version()[:3],
+ "python_version": ".".join(platform.python_version_tuple()[:2]),
"sys_platform": sys.platform,
}
@@ -188,10 +188,22 @@
"platform_version": platform.version(),
"python_full_version": platform.python_version(),
"platform_python_implementation": platform.python_implementation(),
- "python_version": platform.python_version()[:3],
+ "python_version": ".".join(platform.python_version_tuple()[:2]),
"sys_platform": sys.platform,
}
+ def test_multidigit_minor_version(self, monkeypatch):
+ version_info = (3, 10, 0, "final", 0)
+ monkeypatch.setattr(sys, "version_info", version_info, raising=False)
+
+ monkeypatch.setattr(platform, "python_version", lambda: "3.10.0",
raising=False)
+ monkeypatch.setattr(
+ platform, "python_version_tuple", lambda: ("3", "10", "0"),
raising=False
+ )
+
+ environment = default_environment()
+ assert environment["python_version"] == "3.10"
+
def tests_when_releaselevel_final(self):
v = FakeVersionInfo(3, 4, 2, "final", 0)
assert format_full_version(v) == "3.4.2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/tests/test_requirements.py
new/packaging-19.1/tests/test_requirements.py
--- old/packaging-19.0/tests/test_requirements.py 2019-01-20
11:44:35.000000000 +0100
+++ new/packaging-19.1/tests/test_requirements.py 2019-07-30
08:26:09.000000000 +0200
@@ -105,8 +105,8 @@
def test_invalid_url(self):
with pytest.raises(InvalidRequirement) as e:
Requirement("name @ gopher:/foo/com")
- assert "Invalid URL: " in str(e)
- assert "gopher:/foo/com" in str(e)
+ assert "Invalid URL: " in str(e.value)
+ assert "gopher:/foo/com" in str(e.value)
def test_file_url(self):
req = Requirement("name @ file:///absolute/path")
@@ -194,4 +194,4 @@
def test_parseexception_error_msg(self):
with pytest.raises(InvalidRequirement) as e:
Requirement("toto 42")
- assert "Expected stringEnd" in str(e)
+ assert "Expected stringEnd" in str(e.value)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/tests/test_tags.py
new/packaging-19.1/tests/test_tags.py
--- old/packaging-19.0/tests/test_tags.py 1970-01-01 01:00:00.000000000
+0100
+++ new/packaging-19.1/tests/test_tags.py 2019-07-20 07:03:21.000000000
+0200
@@ -0,0 +1,552 @@
+# This file is dual licensed under the terms of the Apache License, Version
+# 2.0, and the BSD License. See the LICENSE file in the root of this repository
+# for complete details.
+
+import collections
+
+try:
+ import ctypes
+except ImportError:
+ ctypes = None
+import distutils.util
+
+import platform
+import sys
+import sysconfig
+import types
+import warnings
+
+import pytest
+
+from packaging import tags
+
+
[email protected]
+def example_tag():
+ return tags.Tag("py3", "none", "any")
+
+
+def test_tag_lowercasing():
+ tag = tags.Tag("PY3", "None", "ANY")
+ assert tag.interpreter == "py3"
+ assert tag.abi == "none"
+ assert tag.platform == "any"
+
+
+def test_tag_equality():
+ args = "py3", "none", "any"
+ assert tags.Tag(*args) == tags.Tag(*args)
+
+
+def test_tag_hashing(example_tag):
+ tags = {example_tag} # Should not raise TypeError.
+ assert example_tag in tags
+
+
+def test_tag_str(example_tag):
+ assert str(example_tag) == "py3-none-any"
+
+
+def test_tag_repr(example_tag):
+ assert repr(example_tag) == "<py3-none-any @ {tag_id}>".format(
+ tag_id=id(example_tag)
+ )
+
+
+def test_tag_attribute_access(example_tag):
+ assert example_tag.interpreter == "py3"
+ assert example_tag.abi == "none"
+ assert example_tag.platform == "any"
+
+
+def test_parse_tag_simple(example_tag):
+ parsed_tags = tags.parse_tag(str(example_tag))
+ assert parsed_tags == {example_tag}
+
+
+def test_parse_tag_multi_interpreter(example_tag):
+ expected = {example_tag, tags.Tag("py2", "none", "any")}
+ given = tags.parse_tag("py2.py3-none-any")
+ assert given == expected
+
+
+def test_parse_tag_multi_platform():
+ expected = {
+ tags.Tag("cp37", "cp37m", platform)
+ for platform in (
+ "macosx_10_6_intel",
+ "macosx_10_9_intel",
+ "macosx_10_9_x86_64",
+ "macosx_10_10_intel",
+ "macosx_10_10_x86_64",
+ )
+ }
+ given = tags.parse_tag(
+ "cp37-cp37m-macosx_10_6_intel.macosx_10_9_intel.macosx_10_9_x86_64."
+ "macosx_10_10_intel.macosx_10_10_x86_64"
+ )
+ assert given == expected
+
+
[email protected](
+ "name,expected",
+ [("CPython", "cp"), ("PyPy", "pp"), ("Jython", "jy"), ("IronPython",
"ip")],
+)
+def test__interpreter_name_cpython(name, expected, monkeypatch):
+ if platform.python_implementation().lower() != name:
+ monkeypatch.setattr(platform, "python_implementation", lambda: name)
+ assert tags._interpreter_name() == expected
+
+
[email protected](
+ "arch, is_32bit, expected",
+ [
+ ("i386", True, "i386"),
+ ("ppc", True, "ppc"),
+ ("x86_64", False, "x86_64"),
+ ("x86_64", True, "i386"),
+ ("ppc64", False, "ppc64"),
+ ("ppc64", True, "ppc"),
+ ],
+)
+def test_macos_architectures(arch, is_32bit, expected):
+ assert tags._mac_arch(arch, is_32bit=is_32bit) == expected
+
+
[email protected](
+ "version,arch,expected",
+ [
+ ((10, 17), "x86_64", ["x86_64", "intel", "fat64", "fat32",
"universal"]),
+ ((10, 4), "x86_64", ["x86_64", "intel", "fat64", "fat32",
"universal"]),
+ ((10, 3), "x86_64", []),
+ ((10, 17), "i386", ["i386", "intel", "fat32", "fat", "universal"]),
+ ((10, 4), "i386", ["i386", "intel", "fat32", "fat", "universal"]),
+ ((10, 3), "i386", []),
+ ((10, 17), "ppc64", []),
+ ((10, 6), "ppc64", []),
+ ((10, 5), "ppc64", ["ppc64", "fat64", "universal"]),
+ ((10, 3), "ppc64", []),
+ ((10, 17), "ppc", []),
+ ((10, 7), "ppc", []),
+ ((10, 6), "ppc", ["ppc", "fat32", "fat", "universal"]),
+ ((10, 0), "ppc", ["ppc", "fat32", "fat", "universal"]),
+ ((11, 0), "riscv", ["riscv", "universal"]),
+ ],
+)
+def test_macos_binary_formats(version, arch, expected):
+ assert tags._mac_binary_formats(version, arch) == expected
+
+
+def test_mac_platforms():
+ platforms = tags._mac_platforms((10, 5), "x86_64")
+ assert platforms == [
+ "macosx_10_5_x86_64",
+ "macosx_10_5_intel",
+ "macosx_10_5_fat64",
+ "macosx_10_5_fat32",
+ "macosx_10_5_universal",
+ "macosx_10_4_x86_64",
+ "macosx_10_4_intel",
+ "macosx_10_4_fat64",
+ "macosx_10_4_fat32",
+ "macosx_10_4_universal",
+ ]
+
+ assert len(tags._mac_platforms((10, 17), "x86_64")) == 14 * 5
+
+ assert not tags._mac_platforms((10, 0), "x86_64")
+
+
+def test_macos_version_detection(monkeypatch):
+ if platform.system() != "Darwin":
+ monkeypatch.setattr(
+ 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])
+ platforms = tags._mac_platforms(arch="x86_64")
+ assert platforms[0].startswith(expected)
+
+
[email protected]("arch", ["x86_64", "i386"])
+def test_macos_arch_detection(arch, monkeypatch):
+ if platform.system() != "Darwin" or platform.mac_ver()[2] != arch:
+ monkeypatch.setattr(platform, "mac_ver", lambda: ("10.14", ("", "",
""), arch))
+ assert tags._mac_platforms((10, 14))[0].endswith(arch)
+
+
+def test_cpython_abi_py3(monkeypatch):
+ has_soabi = bool(sysconfig.get_config_var("SOABI"))
+ if platform.python_implementation() != "CPython" or not has_soabi:
+ monkeypatch.setattr(
+ sysconfig, "get_config_var", lambda key: "'cpython-37m-darwin'"
+ )
+ soabi = sysconfig.get_config_var("SOABI").split("-", 2)[1]
+ result = tags._cpython_abi(sys.version_info[:2])
+ assert result == "cp{soabi}".format(soabi=soabi)
+
+
[email protected](
+ "debug,pymalloc,unicode_width",
+ [
+ (False, False, 2),
+ (True, False, 2),
+ (False, True, 2),
+ (False, False, 4),
+ (True, True, 2),
+ (False, True, 4),
+ (True, True, 4),
+ ],
+)
+def test_cpython_abi_py2(debug, pymalloc, unicode_width, monkeypatch):
+ has_soabi = sysconfig.get_config_var("SOABI")
+ if platform.python_implementation() != "CPython" or has_soabi:
+ diff_debug = debug != sysconfig.get_config_var("Py_DEBUG")
+ diff_malloc = pymalloc != sysconfig.get_config_var("WITH_PYMALLOC")
+ unicode_size = sysconfig.get_config_var("Py_UNICODE_SIZE")
+ diff_unicode_size = unicode_size != unicode_width
+ if diff_debug or diff_malloc or diff_unicode_size:
+ config_vars = {
+ "SOABI": None,
+ "Py_DEBUG": int(debug),
+ "WITH_PYMALLOC": int(pymalloc),
+ "Py_UNICODE_SIZE": unicode_width,
+ }
+ monkeypatch.setattr(sysconfig, "get_config_var",
config_vars.__getitem__)
+ else:
+ config_vars = {
+ "SOABI": None,
+ "Py_DEBUG": int(debug),
+ "WITH_PYMALLOC": int(pymalloc),
+ "Py_UNICODE_SIZE": unicode_width,
+ }
+ monkeypatch.setattr(sysconfig, "get_config_var",
config_vars.__getitem__)
+ options = ""
+ if debug:
+ options += "d"
+ if pymalloc:
+ options += "m"
+ if unicode_width == 4:
+ options += "u"
+ assert "cp33{}".format(options) == tags._cpython_abi((3, 3))
+
+
+def test_independent_tags():
+ result = list(tags._independent_tags("cp33", (3, 3), ["plat1", "plat2"]))
+ assert result == [
+ tags.Tag("py33", "none", "plat1"),
+ tags.Tag("py33", "none", "plat2"),
+ tags.Tag("py3", "none", "plat1"),
+ tags.Tag("py3", "none", "plat2"),
+ tags.Tag("py32", "none", "plat1"),
+ tags.Tag("py32", "none", "plat2"),
+ tags.Tag("py31", "none", "plat1"),
+ tags.Tag("py31", "none", "plat2"),
+ tags.Tag("py30", "none", "plat1"),
+ tags.Tag("py30", "none", "plat2"),
+ tags.Tag("cp33", "none", "any"),
+ tags.Tag("py33", "none", "any"),
+ tags.Tag("py3", "none", "any"),
+ tags.Tag("py32", "none", "any"),
+ tags.Tag("py31", "none", "any"),
+ tags.Tag("py30", "none", "any"),
+ ]
+
+
+def test_cpython_tags():
+ result = list(tags._cpython_tags((3, 3), "cp33", "cp33m", ["plat1",
"plat2"]))
+ assert result == [
+ tags.Tag("cp33", "cp33m", "plat1"),
+ tags.Tag("cp33", "cp33m", "plat2"),
+ tags.Tag("cp33", "abi3", "plat1"),
+ tags.Tag("cp33", "abi3", "plat2"),
+ tags.Tag("cp33", "none", "plat1"),
+ tags.Tag("cp33", "none", "plat2"),
+ tags.Tag("cp32", "abi3", "plat1"),
+ tags.Tag("cp32", "abi3", "plat2"),
+ ]
+
+
+def test_sys_tags_on_mac_cpython(monkeypatch):
+ if platform.python_implementation() != "CPython":
+ monkeypatch.setattr(platform, "python_implementation", lambda:
"CPython")
+ monkeypatch.setattr(tags, "_cpython_abi", lambda py_version: "cp33m")
+ if platform.system() != "Darwin":
+ monkeypatch.setattr(platform, "system", lambda: "Darwin")
+ monkeypatch.setattr(tags, "_mac_platforms", lambda:
["macosx_10_5_x86_64"])
+ abi = tags._cpython_abi(sys.version_info[:2])
+ platforms = tags._mac_platforms()
+ result = list(tags.sys_tags())
+ assert result[0] == tags.Tag(
+ "cp{major}{minor}".format(major=sys.version_info[0],
minor=sys.version_info[1]),
+ abi,
+ platforms[0],
+ )
+ assert result[-1] == tags.Tag("py{}0".format(sys.version_info[0]), "none",
"any")
+
+
+def test_generic_abi(monkeypatch):
+ abi = sysconfig.get_config_var("SOABI")
+ if abi:
+ abi = abi.replace(".", "_").replace("-", "_")
+ else:
+ abi = "none"
+ assert abi == tags._generic_abi()
+
+ monkeypatch.setattr(sysconfig, "get_config_var", lambda key:
"cpython-37m-darwin")
+ assert tags._generic_abi() == "cpython_37m_darwin"
+
+ monkeypatch.setattr(sysconfig, "get_config_var", lambda key: None)
+ assert tags._generic_abi() == "none"
+
+
+def test_pypy_interpreter(monkeypatch):
+ if hasattr(sys, "pypy_version_info"):
+ major, minor = sys.pypy_version_info[:2]
+ else:
+ attributes = ["major", "minor", "micro", "releaselevel", "serial"]
+ PyPyVersion = collections.namedtuple("version_info", attributes)
+ major, minor = 6, 0
+ pypy_version = PyPyVersion(
+ major=major, minor=minor, micro=1, releaselevel="final", serial=0
+ )
+ monkeypatch.setattr(sys, "pypy_version_info", pypy_version,
raising=False)
+ expected = "pp{}{}{}".format(sys.version_info[0], major, minor)
+ assert expected == tags._pypy_interpreter()
+
+
+def test_pypy_tags(monkeypatch):
+ if platform.python_implementation() != "PyPy":
+ monkeypatch.setattr(platform, "python_implementation", lambda: "PyPy")
+ monkeypatch.setattr(tags, "_pypy_interpreter", lambda: "pp360")
+ interpreter = tags._pypy_interpreter()
+ result = list(tags._pypy_tags((3, 3), interpreter, "pypy3_60", ["plat1",
"plat2"]))
+ assert result == [
+ tags.Tag(interpreter, "pypy3_60", "plat1"),
+ tags.Tag(interpreter, "pypy3_60", "plat2"),
+ tags.Tag(interpreter, "none", "plat1"),
+ tags.Tag(interpreter, "none", "plat2"),
+ ]
+
+
+def test_sys_tags_on_mac_pypy(monkeypatch):
+ if platform.python_implementation() != "PyPy":
+ monkeypatch.setattr(platform, "python_implementation", lambda: "PyPy")
+ monkeypatch.setattr(tags, "_pypy_interpreter", lambda: "pp360")
+ if platform.system() != "Darwin":
+ monkeypatch.setattr(platform, "system", lambda: "Darwin")
+ monkeypatch.setattr(tags, "_mac_platforms", lambda:
["macosx_10_5_x86_64"])
+ interpreter = tags._pypy_interpreter()
+ abi = tags._generic_abi()
+ platforms = tags._mac_platforms()
+ result = list(tags.sys_tags())
+ assert result[0] == tags.Tag(interpreter, abi, platforms[0])
+ assert result[-1] == tags.Tag("py{}0".format(sys.version_info[0]), "none",
"any")
+
+
+def test_generic_interpreter():
+ version = sysconfig.get_config_var("py_version_nodot")
+ if not version:
+ version = "".join(sys.version_info[:2])
+ result = tags._generic_interpreter("sillywalk", sys.version_info[:2])
+ assert result == "sillywalk{version}".format(version=version)
+
+
+def test_generic_interpreter_no_config_var(monkeypatch):
+ monkeypatch.setattr(sysconfig, "get_config_var", lambda _: None)
+ assert tags._generic_interpreter("sillywalk", (3, 6)) == "sillywalk36"
+
+
+def test_generic_platforms():
+ platform = distutils.util.get_platform().replace("-", "_")
+ platform = platform.replace(".", "_")
+ assert tags._generic_platforms() == [platform]
+
+
+def test_generic_tags():
+ result = list(tags._generic_tags("sillywalk33", (3, 3), "abi", ["plat1",
"plat2"]))
+ assert result == [
+ tags.Tag("sillywalk33", "abi", "plat1"),
+ tags.Tag("sillywalk33", "abi", "plat2"),
+ tags.Tag("sillywalk33", "none", "plat1"),
+ tags.Tag("sillywalk33", "none", "plat2"),
+ ]
+
+ no_abi = tags._generic_tags("sillywalk34", (3, 4), "none", ["plat1",
"plat2"])
+ assert list(no_abi) == [
+ tags.Tag("sillywalk34", "none", "plat1"),
+ tags.Tag("sillywalk34", "none", "plat2"),
+ ]
+
+
+def test_sys_tags_on_windows_cpython(monkeypatch):
+ if platform.python_implementation() != "CPython":
+ monkeypatch.setattr(platform, "python_implementation", lambda:
"CPython")
+ monkeypatch.setattr(tags, "_cpython_abi", lambda py_version: "cp33m")
+ if platform.system() != "Windows":
+ monkeypatch.setattr(platform, "system", lambda: "Windows")
+ monkeypatch.setattr(tags, "_generic_platforms", lambda: ["win_amd64"])
+ abi = tags._cpython_abi(sys.version_info[:2])
+ platforms = tags._generic_platforms()
+ result = list(tags.sys_tags())
+ interpreter = "cp{major}{minor}".format(
+ major=sys.version_info[0], minor=sys.version_info[1]
+ )
+ expected = tags.Tag(interpreter, abi, platforms[0])
+ assert result[0] == expected
+ expected = tags.Tag("py{}0".format(sys.version_info[0]), "none", "any")
+ assert result[-1] == expected
+
+
+def test_is_manylinux_compatible_module_support(monkeypatch):
+ monkeypatch.setattr(tags, "_have_compatible_glibc", lambda *args: False)
+ module_name = "_manylinux"
+ module = types.ModuleType(module_name)
+ module.manylinux1_compatible = True
+ monkeypatch.setitem(sys.modules, module_name, module)
+ assert tags._is_manylinux_compatible("manylinux1", (2, 5))
+ module.manylinux1_compatible = False
+ assert not tags._is_manylinux_compatible("manylinux1", (2, 5))
+ del module.manylinux1_compatible
+ assert not tags._is_manylinux_compatible("manylinux1", (2, 5))
+ monkeypatch.setitem(sys.modules, module_name, None)
+ assert not tags._is_manylinux_compatible("manylinux1", (2, 5))
+
+
+def test_is_manylinux_compatible_glibc_support(monkeypatch):
+ monkeypatch.setitem(sys.modules, "_manylinux", None)
+ monkeypatch.setattr(
+ tags, "_have_compatible_glibc", lambda major, minor: (major, minor) <=
(2, 5)
+ )
+ assert tags._is_manylinux_compatible("manylinux1", (2, 0))
+ assert tags._is_manylinux_compatible("manylinux1", (2, 5))
+ assert not tags._is_manylinux_compatible("manylinux1", (2, 10))
+
+
[email protected](
+ "version_str,major,minor,expected",
+ [
+ ("2.4", 2, 4, True),
+ ("2.4", 2, 5, False),
+ ("2.4", 2, 3, True),
+ ("3.4", 2, 4, False),
+ ],
+)
+def test_check_glibc_version(version_str, major, minor, expected):
+ assert expected == tags._check_glibc_version(version_str, major, minor)
+
+
[email protected]("version_str", ["glibc-2.4.5", "2"])
+def test_check_glibc_version_warning(version_str):
+ with warnings.catch_warnings(record=True) as w:
+ tags._check_glibc_version(version_str, 2, 4)
+ assert len(w) == 1
+ assert issubclass(w[0].category, RuntimeWarning)
+
+
[email protected](not ctypes, reason="requires ctypes")
[email protected](
+ "version_str,expected",
+ [
+ # Be very explicit about bytes and Unicode for Python 2 testing.
+ (b"2.4", "2.4"),
+ (u"2.4", "2.4"),
+ ],
+)
+def test_glibc_version_string(version_str, expected, monkeypatch):
+ class LibcVersion:
+ def __init__(self, version_str):
+ self.version_str = version_str
+
+ def __call__(self):
+ return version_str
+
+ class ProcessNamespace:
+ def __init__(self, libc_version):
+ self.gnu_get_libc_version = libc_version
+
+ process_namespace = ProcessNamespace(LibcVersion(version_str))
+ monkeypatch.setattr(ctypes, "CDLL", lambda _: process_namespace)
+
+ assert tags._glibc_version_string() == expected
+
+ del process_namespace.gnu_get_libc_version
+ assert tags._glibc_version_string() is None
+
+
+def test_have_compatible_glibc(monkeypatch):
+ if platform.system() == "Linux":
+ # Assuming no one is running this test with a version of glibc
released in
+ # 1997.
+ assert tags._have_compatible_glibc(2, 0)
+ else:
+ monkeypatch.setattr(tags, "_glibc_version_string", lambda: "2.4")
+ assert tags._have_compatible_glibc(2, 4)
+ monkeypatch.setattr(tags, "_glibc_version_string", lambda: None)
+ assert not tags._have_compatible_glibc(2, 4)
+
+
+def test_linux_platforms_64bit_on_64bit_os(monkeypatch):
+ is_64bit_os = distutils.util.get_platform().endswith("_x86_64")
+ if platform.system() != "Linux" or not is_64bit_os:
+ monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
+ monkeypatch.setattr(tags, "_is_manylinux_compatible", lambda *args:
False)
+ linux_platform = tags._linux_platforms(is_32bit=False)[-1]
+ assert linux_platform == "linux_x86_64"
+
+
+def test_linux_platforms_32bit_on_64bit_os(monkeypatch):
+ is_64bit_os = distutils.util.get_platform().endswith("_x86_64")
+ if platform.system() != "Linux" or not is_64bit_os:
+ monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
+ monkeypatch.setattr(tags, "_is_manylinux_compatible", lambda *args:
False)
+ linux_platform = tags._linux_platforms(is_32bit=True)[-1]
+ assert linux_platform == "linux_i686"
+
+
+def test_linux_platforms_manylinux1(monkeypatch):
+ monkeypatch.setattr(
+ tags, "_is_manylinux_compatible", lambda name, _: name == "manylinux1"
+ )
+ if platform.system() != "Linux":
+ monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
+ platforms = tags._linux_platforms(is_32bit=False)
+ assert platforms == ["manylinux1_x86_64", "linux_x86_64"]
+
+
+def test_linux_platforms_manylinux2010(monkeypatch):
+ monkeypatch.setattr(
+ tags, "_is_manylinux_compatible", lambda name, _: name ==
"manylinux2010"
+ )
+ if platform.system() != "Linux":
+ monkeypatch.setattr(distutils.util, "get_platform", lambda:
"linux_x86_64")
+ platforms = tags._linux_platforms(is_32bit=False)
+ expected = ["manylinux2010_x86_64", "manylinux1_x86_64", "linux_x86_64"]
+ assert platforms == expected
+
+
+def test_sys_tags_linux_cpython(monkeypatch):
+ if platform.python_implementation() != "CPython":
+ monkeypatch.setattr(platform, "python_implementation", lambda:
"CPython")
+ monkeypatch.setattr(tags, "_cpython_abi", lambda py_version: "cp33m")
+ if platform.system() != "Linux":
+ monkeypatch.setattr(platform, "system", lambda: "Linux")
+ monkeypatch.setattr(tags, "_linux_platforms", lambda: ["linux_x86_64"])
+ abi = tags._cpython_abi(sys.version_info[:2])
+ platforms = tags._linux_platforms()
+ result = list(tags.sys_tags())
+ expected_interpreter = "cp{major}{minor}".format(
+ major=sys.version_info[0], minor=sys.version_info[1]
+ )
+ assert result[0] == tags.Tag(expected_interpreter, abi, platforms[0])
+ expected = tags.Tag("py{}0".format(sys.version_info[0]), "none", "any")
+ assert result[-1] == expected
+
+
+def test_generic_sys_tags(monkeypatch):
+ monkeypatch.setattr(platform, "system", lambda: "Generic")
+ monkeypatch.setattr(tags, "_interpreter_name", lambda: "generic")
+
+ result = list(tags.sys_tags())
+ expected = tags.Tag("py{}0".format(sys.version_info[0]), "none", "any")
+ assert result[-1] == expected
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/packaging-19.0/tox.ini new/packaging-19.1/tox.ini
--- old/packaging-19.0/tox.ini 2019-01-20 11:44:35.000000000 +0100
+++ new/packaging-19.1/tox.ini 2019-07-30 08:26:09.000000000 +0200
@@ -15,6 +15,10 @@
commands =
py.test --capture=no --strict {posargs}
+[testenv:pypy3]
+commands =
+ py.test --capture=no --strict {posargs}
+
[testenv:docs]
basepython = python3
deps =