Hello community,

here is the log from the commit of package python-packaging for 
openSUSE:Factory checked in at 2020-06-05 19:59:50
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-packaging (Old)
 and      /work/SRC/openSUSE:Factory/.python-packaging.new.3606 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-packaging"

Fri Jun  5 19:59:50 2020 rev:17 rq:810910 version:20.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-packaging/python-packaging.changes        
2020-05-07 15:06:03.463779208 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-packaging.new.3606/python-packaging.changes  
    2020-06-05 19:59:59.155891303 +0200
@@ -1,0 +2,10 @@
+Tue Jun  2 16:35:59 UTC 2020 - Dirk Mueller <[email protected]>
+
+- update to 20.4:
+  * Canonicalize version before comparing specifiers. (:issue:`282`)
+  * Change type hint for ``canonicalize_name`` to return
+  ``packaging.utils.NormalizedName``.
+  This enables the use of static typing tools (like mypy) to detect mixing of
+  normalized and un-normalized names.
+
+-------------------------------------------------------------------

Old:
----
  packaging-20.3.tar.gz

New:
----
  packaging-20.4.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-packaging.spec ++++++
--- /var/tmp/diff_new_pack.lb1cjb/_old  2020-06-05 20:00:00.447895772 +0200
+++ /var/tmp/diff_new_pack.lb1cjb/_new  2020-06-05 20:00:00.451895786 +0200
@@ -26,7 +26,7 @@
 %bcond_with test
 %endif
 Name:           python-packaging%{psuffix}
-Version:        20.3
+Version:        20.4
 Release:        0
 Summary:        Core utilities for Python packages
 License:        Apache-2.0

++++++ packaging-20.3.tar.gz -> packaging-20.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/.pre-commit-config.yaml 
new/packaging-20.4/.pre-commit-config.yaml
--- old/packaging-20.3/.pre-commit-config.yaml  2020-01-28 08:07:37.000000000 
+0100
+++ new/packaging-20.4/.pre-commit-config.yaml  2020-04-15 17:43:30.000000000 
+0200
@@ -8,7 +8,7 @@
   - id: trailing-whitespace
 
 - repo: https://github.com/pre-commit/mirrors-mypy
-  rev: v0.750
+  rev: v0.770
   hooks:
   - id: mypy
     exclude: '^(docs|tasks|tests)|setup\.py'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/CHANGELOG.rst 
new/packaging-20.4/CHANGELOG.rst
--- old/packaging-20.3/CHANGELOG.rst    2020-03-05 08:48:02.000000000 +0100
+++ new/packaging-20.4/CHANGELOG.rst    2020-05-19 08:29:48.000000000 +0200
@@ -1,6 +1,15 @@
 Changelog
 ---------
 
+20.4 - 2020-05-19
+~~~~~~~~~~~~~~~~~
+
+* Canonicalize version before comparing specifiers. (:issue:`282`)
+* Change type hint for ``canonicalize_name`` to return
+  ``packaging.utils.NormalizedName``.
+  This enables the use of static typing tools (like mypy) to detect mixing of
+  normalized and un-normalized names.
+
 20.3 - 2020-03-05
 ~~~~~~~~~~~~~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/PKG-INFO new/packaging-20.4/PKG-INFO
--- old/packaging-20.3/PKG-INFO 2020-03-05 08:48:09.689097600 +0100
+++ new/packaging-20.4/PKG-INFO 2020-05-19 08:29:49.759008200 +0200
@@ -1,11 +1,11 @@
 Metadata-Version: 2.1
 Name: packaging
-Version: 20.3
+Version: 20.4
 Summary: Core utilities for Python packages
 Home-page: https://github.com/pypa/packaging
 Author: Donald Stufft and individual contributors
 Author-email: [email protected]
-License: BSD or Apache License, Version 2.0
+License: BSD-2-Clause or Apache-2.0
 Description: packaging
         =========
         
@@ -74,6 +74,15 @@
         Changelog
         ---------
         
+        20.4 - 2020-05-19
+        ~~~~~~~~~~~~~~~~~
+        
+        * Canonicalize version before comparing specifiers. (`#282 
<https://github.com/pypa/packaging/issues/282>`__)
+        * Change type hint for ``canonicalize_name`` to return
+          ``packaging.utils.NormalizedName``.
+          This enables the use of static typing tools (like mypy) to detect 
mixing of
+          normalized and un-normalized names.
+        
         20.3 - 2020-03-05
         ~~~~~~~~~~~~~~~~~
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/docs/version.rst 
new/packaging-20.4/docs/version.rst
--- old/packaging-20.3/docs/version.rst 2018-06-07 12:17:11.000000000 +0200
+++ new/packaging-20.4/docs/version.rst 2020-05-19 08:29:11.000000000 +0200
@@ -86,6 +86,18 @@
         version number, including trailing zeroes but not including the epoch
         or any prerelease/development/postrelease suffixes
 
+    .. attribute:: major
+
+        An integer representing the first item of :attr:`release` or ``0`` if 
unavailable.
+
+    .. attribute:: minor
+
+        An integer representing the second item of :attr:`release` or ``0`` if 
unavailable.
+
+    .. attribute:: micro
+
+        An integer representing the third item of :attr:`release` or ``0`` if 
unavailable.
+
     .. attribute:: local
 
         A string representing the local version portion of this ``Version()``
@@ -139,6 +151,52 @@
     :param str version: The string representation of a version which will be
                         used as is.
 
+    .. note::
+
+        :class:`LegacyVersion` instances are always ordered lower than 
:class:`Version` instances.
+
+        >>> from packaging.version import Version, LegacyVersion
+        >>> v1 = Version("1.0")
+        >>> v2 = LegacyVersion("1.0")
+        >>> v1 > v2
+        True
+        >>> v3 = LegacyVersion("1.3")
+        >>> v1 > v3
+        True
+
+        Also note that some strings are still valid PEP 440 strings 
(:class:`Version`), even if they look very similar to
+        other versions that are not (:class:`LegacyVersion`). Examples include 
versions with `Pre-release spelling`_ and
+        `Post-release spelling`_.
+
+        >>> from packaging.version import parse
+        >>> v1 = parse('0.9.8a')
+        >>> v2 = parse('0.9.8beta')
+        >>> v3 = parse('0.9.8r')
+        >>> v4 = parse('0.9.8rev')
+        >>> v5 = parse('0.9.8t')
+        >>> v1
+        <Version('0.9.8a0')>
+        >>> v1.is_prerelease
+        True
+        >>> v2
+        <Version('0.9.8b0')>
+        >>> v2.is_prerelease
+        True
+        >>> v3
+        <Version('0.9.8.post0')>
+        >>> v3.is_postrelease
+        True
+        >>> v4
+        <Version('0.9.8.post0')>
+        >>> v4.is_postrelease
+        True
+        >>> v5
+        <LegacyVersion('0.9.8t')>
+        >>> v5.is_prerelease
+        False
+        >>> v5.is_postrelease
+        False
+
     .. attribute:: public
 
         A string representing the public version portion of this
@@ -225,4 +283,6 @@
     ``re.VERBOSE`` and ``re.IGNORECASE`` flags set.
 
 
-.. _`PEP 440`: https://www.python.org/dev/peps/pep-0440/
+.. _PEP 440: https://www.python.org/dev/peps/pep-0440/
+.. _Pre-release spelling : 
https://www.python.org/dev/peps/pep-0440/#pre-release-spelling
+.. _Post-release spelling : 
https://www.python.org/dev/peps/pep-0440/#post-release-spelling
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/__about__.py 
new/packaging-20.4/packaging/__about__.py
--- old/packaging-20.3/packaging/__about__.py   2020-03-05 08:48:02.000000000 
+0100
+++ new/packaging-20.4/packaging/__about__.py   2020-05-19 08:29:48.000000000 
+0200
@@ -18,10 +18,10 @@
 __summary__ = "Core utilities for Python packages"
 __uri__ = "https://github.com/pypa/packaging";
 
-__version__ = "20.3"
+__version__ = "20.4"
 
 __author__ = "Donald Stufft and individual contributors"
 __email__ = "[email protected]"
 
-__license__ = "BSD or Apache License, Version 2.0"
+__license__ = "BSD-2-Clause or Apache-2.0"
 __copyright__ = "Copyright 2014-2019 %s" % __author__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/_compat.py 
new/packaging-20.4/packaging/_compat.py
--- old/packaging-20.3/packaging/_compat.py     2019-12-11 10:08:40.000000000 
+0100
+++ new/packaging-20.4/packaging/_compat.py     2020-04-15 17:43:30.000000000 
+0200
@@ -5,9 +5,9 @@
 
 import sys
 
-from ._typing import MYPY_CHECK_RUNNING
+from ._typing import TYPE_CHECKING
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
+if TYPE_CHECKING:  # pragma: no cover
     from typing import Any, Dict, Tuple, Type
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/_typing.py 
new/packaging-20.4/packaging/_typing.py
--- old/packaging-20.3/packaging/_typing.py     2019-12-11 10:08:40.000000000 
+0100
+++ new/packaging-20.4/packaging/_typing.py     2020-04-15 17:43:30.000000000 
+0200
@@ -18,22 +18,31 @@
 
 In packaging, all static-typing related imports should be guarded as follows:
 
-    from packaging._typing import MYPY_CHECK_RUNNING
+    from packaging._typing import TYPE_CHECKING
 
-    if MYPY_CHECK_RUNNING:
+    if TYPE_CHECKING:
         from typing import ...
 
 Ref: https://github.com/python/mypy/issues/3216
 """
 
-MYPY_CHECK_RUNNING = False
+__all__ = ["TYPE_CHECKING", "cast"]
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
-    import typing
+# The TYPE_CHECKING constant defined by the typing module is False at runtime
+# but True while type checking.
+if False:  # pragma: no cover
+    from typing import TYPE_CHECKING
+else:
+    TYPE_CHECKING = False
 
-    cast = typing.cast
+# typing's cast syntax requires calling typing.cast at runtime, but we don't
+# want to import typing at runtime. Here, we inform the type checkers that
+# we're importing `typing.cast` as `cast` and re-implement typing.cast's
+# runtime behavior in a block that is ignored by type checkers.
+if TYPE_CHECKING:  # pragma: no cover
+    # not executed at runtime
+    from typing import cast
 else:
-    # typing's cast() is needed at runtime, but we don't want to import typing.
-    # Thus, we use a dummy no-op version, which we tell mypy to ignore.
-    def cast(type_, value):  # type: ignore
+    # executed at runtime
+    def cast(type_, value):  # noqa
         return value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/markers.py 
new/packaging-20.4/packaging/markers.py
--- old/packaging-20.3/packaging/markers.py     2019-12-11 10:08:40.000000000 
+0100
+++ new/packaging-20.4/packaging/markers.py     2020-04-15 17:43:30.000000000 
+0200
@@ -13,10 +13,10 @@
 from pyparsing import Literal as L  # noqa
 
 from ._compat import string_types
-from ._typing import MYPY_CHECK_RUNNING
+from ._typing import TYPE_CHECKING
 from .specifiers import Specifier, InvalidSpecifier
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
+if TYPE_CHECKING:  # pragma: no cover
     from typing import Any, Callable, Dict, List, Optional, Tuple, Union
 
     Operator = Callable[[str, str], bool]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/requirements.py 
new/packaging-20.4/packaging/requirements.py
--- old/packaging-20.3/packaging/requirements.py        2019-12-11 
10:08:40.000000000 +0100
+++ new/packaging-20.4/packaging/requirements.py        2020-04-15 
17:43:30.000000000 +0200
@@ -11,11 +11,11 @@
 from pyparsing import Literal as L  # noqa
 from six.moves.urllib import parse as urlparse
 
-from ._typing import MYPY_CHECK_RUNNING
+from ._typing import TYPE_CHECKING
 from .markers import MARKER_EXPR, Marker
 from .specifiers import LegacySpecifier, Specifier, SpecifierSet
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
+if TYPE_CHECKING:  # pragma: no cover
     from typing import List
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/specifiers.py 
new/packaging-20.4/packaging/specifiers.py
--- old/packaging-20.3/packaging/specifiers.py  2019-12-11 10:08:40.000000000 
+0100
+++ new/packaging-20.4/packaging/specifiers.py  2020-05-19 08:29:11.000000000 
+0200
@@ -9,10 +9,11 @@
 import re
 
 from ._compat import string_types, with_metaclass
-from ._typing import MYPY_CHECK_RUNNING
+from ._typing import TYPE_CHECKING
+from .utils import canonicalize_version
 from .version import Version, LegacyVersion, parse
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
+if TYPE_CHECKING:  # pragma: no cover
     from typing import (
         List,
         Dict,
@@ -132,9 +133,14 @@
         # type: () -> str
         return "{0}{1}".format(*self._spec)
 
+    @property
+    def _canonical_spec(self):
+        # type: () -> Tuple[str, Union[Version, str]]
+        return self._spec[0], canonicalize_version(self._spec[1])
+
     def __hash__(self):
         # type: () -> int
-        return hash(self._spec)
+        return hash(self._canonical_spec)
 
     def __eq__(self, other):
         # type: (object) -> bool
@@ -146,7 +152,7 @@
         elif not isinstance(other, self.__class__):
             return NotImplemented
 
-        return self._spec == other._spec
+        return self._canonical_spec == other._canonical_spec
 
     def __ne__(self, other):
         # type: (object) -> bool
@@ -510,12 +516,20 @@
     @_require_version_compare
     def _compare_less_than_equal(self, prospective, spec):
         # type: (ParsedVersion, str) -> bool
-        return prospective <= Version(spec)
+
+        # NB: Local version identifiers are NOT permitted in the version
+        # specifier, so local version labels can be universally removed from
+        # the prospective version.
+        return Version(prospective.public) <= Version(spec)
 
     @_require_version_compare
     def _compare_greater_than_equal(self, prospective, spec):
         # type: (ParsedVersion, str) -> bool
-        return prospective >= Version(spec)
+
+        # NB: Local version identifiers are NOT permitted in the version
+        # specifier, so local version labels can be universally removed from
+        # the prospective version.
+        return Version(prospective.public) >= Version(spec)
 
     @_require_version_compare
     def _compare_less_than(self, prospective, spec_str):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/tags.py 
new/packaging-20.4/packaging/tags.py
--- old/packaging-20.3/packaging/tags.py        2020-02-10 11:39:55.000000000 
+0100
+++ new/packaging-20.4/packaging/tags.py        2020-04-15 17:43:30.000000000 
+0200
@@ -22,9 +22,9 @@
 import sysconfig
 import warnings
 
-from ._typing import MYPY_CHECK_RUNNING, cast
+from ._typing import TYPE_CHECKING, cast
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
+if TYPE_CHECKING:  # pragma: no cover
     from typing import (
         Dict,
         FrozenSet,
@@ -58,6 +58,12 @@
 
 
 class Tag(object):
+    """
+    A representation of the tag triple for a wheel.
+
+    Instances are considered immutable and thus are hashable. Equality checking
+    is also supported.
+    """
 
     __slots__ = ["_interpreter", "_abi", "_platform"]
 
@@ -108,6 +114,12 @@
 
 def parse_tag(tag):
     # type: (str) -> FrozenSet[Tag]
+    """
+    Parses the provided tag (e.g. `py3-none-any`) into a frozenset of Tag 
instances.
+
+    Returning a set is required due to the possibility that the tag is a
+    compressed tag set.
+    """
     tags = set()
     interpreters, abis, platforms = tag.split("-")
     for interpreter in interpreters.split("."):
@@ -541,7 +553,7 @@
         def unpack(fmt):
             # type: (str) -> int
             try:
-                result, = struct.unpack(
+                (result,) = struct.unpack(
                     fmt, file.read(struct.calcsize(fmt))
                 )  # type: (int, )
             except struct.error:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/utils.py 
new/packaging-20.4/packaging/utils.py
--- old/packaging-20.3/packaging/utils.py       2019-12-11 10:08:40.000000000 
+0100
+++ new/packaging-20.4/packaging/utils.py       2020-04-15 17:43:30.000000000 
+0200
@@ -5,19 +5,22 @@
 
 import re
 
-from ._typing import MYPY_CHECK_RUNNING
+from ._typing import TYPE_CHECKING, cast
 from .version import InvalidVersion, Version
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
-    from typing import Union
+if TYPE_CHECKING:  # pragma: no cover
+    from typing import NewType, Union
+
+    NormalizedName = NewType("NormalizedName", str)
 
 _canonicalize_regex = re.compile(r"[-_.]+")
 
 
 def canonicalize_name(name):
-    # type: (str) -> str
+    # type: (str) -> NormalizedName
     # This is taken from PEP 503.
-    return _canonicalize_regex.sub("-", name).lower()
+    value = _canonicalize_regex.sub("-", name).lower()
+    return cast("NormalizedName", value)
 
 
 def canonicalize_version(_version):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging/version.py 
new/packaging-20.4/packaging/version.py
--- old/packaging-20.3/packaging/version.py     2019-12-11 10:08:40.000000000 
+0100
+++ new/packaging-20.4/packaging/version.py     2020-04-15 17:43:30.000000000 
+0200
@@ -8,9 +8,9 @@
 import re
 
 from ._structures import Infinity, NegativeInfinity
-from ._typing import MYPY_CHECK_RUNNING
+from ._typing import TYPE_CHECKING
 
-if MYPY_CHECK_RUNNING:  # pragma: no cover
+if TYPE_CHECKING:  # pragma: no cover
     from typing import Callable, Iterator, List, Optional, SupportsInt, Tuple, 
Union
 
     from ._structures import InfinityType, NegativeInfinityType
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/packaging.egg-info/PKG-INFO 
new/packaging-20.4/packaging.egg-info/PKG-INFO
--- old/packaging-20.3/packaging.egg-info/PKG-INFO      2020-03-05 
08:48:09.000000000 +0100
+++ new/packaging-20.4/packaging.egg-info/PKG-INFO      2020-05-19 
08:29:49.000000000 +0200
@@ -1,11 +1,11 @@
 Metadata-Version: 2.1
 Name: packaging
-Version: 20.3
+Version: 20.4
 Summary: Core utilities for Python packages
 Home-page: https://github.com/pypa/packaging
 Author: Donald Stufft and individual contributors
 Author-email: [email protected]
-License: BSD or Apache License, Version 2.0
+License: BSD-2-Clause or Apache-2.0
 Description: packaging
         =========
         
@@ -74,6 +74,15 @@
         Changelog
         ---------
         
+        20.4 - 2020-05-19
+        ~~~~~~~~~~~~~~~~~
+        
+        * Canonicalize version before comparing specifiers. (`#282 
<https://github.com/pypa/packaging/issues/282>`__)
+        * Change type hint for ``canonicalize_name`` to return
+          ``packaging.utils.NormalizedName``.
+          This enables the use of static typing tools (like mypy) to detect 
mixing of
+          normalized and un-normalized names.
+        
         20.3 - 2020-03-05
         ~~~~~~~~~~~~~~~~~
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/packaging-20.3/tests/test_specifiers.py 
new/packaging-20.4/tests/test_specifiers.py
--- old/packaging-20.3/tests/test_specifiers.py 2019-07-30 10:17:08.000000000 
+0200
+++ new/packaging-20.4/tests/test_specifiers.py 2020-05-19 08:29:11.000000000 
+0200
@@ -253,6 +253,12 @@
         assert op(left, Specifier(right))
         assert op(Specifier(left), right)
 
+    @pytest.mark.parametrize(("left", "right"), [("==2.8.0", "==2.8")])
+    def test_comparison_canonicalizes(self, left, right):
+        assert Specifier(left) == Specifier(right)
+        assert left == Specifier(right)
+        assert Specifier(left) == right
+
     @pytest.mark.parametrize(
         ("left", "right", "op"),
         itertools.chain(
@@ -961,6 +967,26 @@
         assert not op(left, SpecifierSet(right))
         assert not op(SpecifierSet(left), right)
 
+    @pytest.mark.parametrize(("left", "right"), [("==2.8.0", "==2.8")])
+    def test_comparison_canonicalizes(self, left, right):
+        assert SpecifierSet(left) == SpecifierSet(right)
+        assert left == SpecifierSet(right)
+        assert SpecifierSet(left) == right
+
     def test_comparison_non_specifier(self):
         assert SpecifierSet("==1.0") != 12
         assert not SpecifierSet("==1.0") == 12
+
+    @pytest.mark.parametrize(
+        ("version", "specifier", "expected"),
+        [
+            ("1.0.0+local", "==1.0.0", True),
+            ("1.0.0+local", "!=1.0.0", False),
+            ("1.0.0+local", "<=1.0.0", True),
+            ("1.0.0+local", ">=1.0.0", True),
+            ("1.0.0+local", "<1.0.0", False),
+            ("1.0.0+local", ">1.0.0", False),
+        ],
+    )
+    def test_comparison_ignores_local(self, version, specifier, expected):
+        assert (Version(version) in SpecifierSet(specifier)) == expected


Reply via email to