Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-looseversion for 
openSUSE:Factory checked in at 2023-12-09 22:49:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-looseversion (Old)
 and      /work/SRC/openSUSE:Factory/.python-looseversion.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-looseversion"

Sat Dec  9 22:49:04 2023 rev:2 rq:1131738 version:1.3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-looseversion/python-looseversion.changes  
2023-03-21 17:44:26.486666333 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-looseversion.new.25432/python-looseversion.changes
       2023-12-09 22:49:09.518644002 +0100
@@ -1,0 +2,10 @@
+Thu Dec  7 22:42:07 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 1.3.0:
+  * Restore Python 3 semantics for `LooseVersion`, creating
+    `LooseVersion2` to restore Python 2 semantics.
+  * Test on Python 3.12
+  * Enable installation on Python 2+
+  * Ensure consistent semantics between Python 2 and 3
+
+-------------------------------------------------------------------

Old:
----
  1.1.2.tar.gz

New:
----
  1.3.0.tar.gz

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

Other differences:
------------------
++++++ python-looseversion.spec ++++++
--- /var/tmp/diff_new_pack.1JHPHk/_old  2023-12-09 22:49:10.686686172 +0100
+++ /var/tmp/diff_new_pack.1JHPHk/_new  2023-12-09 22:49:10.690686316 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-looseversion
 #
-# Copyright (c) 2023 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,17 +12,17 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           python-looseversion
-Version:        1.1.2 
+Version:        1.3.0
 Release:        0
 Summary:        A backwards/forwards-compatible fork of 
distutils.version.LooseVersion
 License:        PSF-2.0 
 Group:          Development/Languages/Python 
-Url:            https://github.com/effigies/looseversion
+URL:            https://github.com/effigies/looseversion
 Source:         
https://github.com/effigies/looseversion/archive/refs/tags/%{version}.tar.gz
 BuildRequires:  %{python_module base > 3}
 BuildRequires:  %{python_module hatchling}

++++++ 1.1.2.tar.gz -> 1.3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/looseversion-1.1.2/.github/workflows/package.yml 
new/looseversion-1.3.0/.github/workflows/package.yml
--- old/looseversion-1.1.2/.github/workflows/package.yml        2023-02-22 
14:55:05.000000000 +0100
+++ new/looseversion-1.3.0/.github/workflows/package.yml        2023-07-05 
18:05:41.000000000 +0200
@@ -20,12 +20,10 @@
       uses: actions/setup-python@v4
       with:
         python-version: ${{ matrix.python }}
-    - name: Install dev tools
-      run: pip install --upgrade build twine
     - name: Build package
-      run: python -m build
+      run: pipx run build
     - name: Check package metadata
-      run: twine check dist/*
+      run: pipx run twine check dist/*
     - name: Save packages
       uses: actions/upload-artifact@v3
       with:
@@ -36,13 +34,21 @@
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python: [3.7, 3.8, 3.9, "3.10", "3.11", "pypy-3.7"]
+        python:
+          - "3.7"
+          - "3.8"
+          - "3.9"
+          - "3.10"
+          - "3.11"
+          - "3.12"
+          - "pypy-3.7"
     steps:
     - uses: actions/checkout@v3
     - name: Set up Python ${{ matrix.python }}
       uses: actions/setup-python@v4
       with:
         python-version: ${{ matrix.python }}
+        allow-prereleases: true
     - name: Install tox
       run: pip install --upgrade pip tox tox-gh-actions
     - name: Test
@@ -51,31 +57,20 @@
   deploy:
     needs: [build, test]
     runs-on: ubuntu-latest
+    permissions:
+      # IMPORTANT: this permission is mandatory for trusted publishing
+      id-token: write
     steps:
     - name: Load packages
       uses: actions/download-artifact@v3
       with:
         name: dist
         path: dist/
-    - name: Check for PyPI tokens
-      id: deployable
-      env:
-        TEST_PYPI_API_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
-        PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
-      run: |
-        if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> 
$GITHUB_OUTPUT; fi
-        if [ -n "$TEST_PYPI_API_TOKEN" ]; then echo "TEST_DEPLOY=true" >> 
$GITHUB_OUTPUT; fi
     - name: Test PyPI upload
-      if: steps.deployable.outputs.TEST_DEPLOY
       uses: pypa/gh-action-pypi-publish@release/v1
       with:
-        user: __token__
-        password: ${{ secrets.TEST_PYPI_API_TOKEN }}
         repository_url: https://test.pypi.org/legacy/
         skip_existing: true
     - name: Upload to PyPI (on tags)
-      if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') 
&& steps.deployable.outputs.DEPLOY
+      if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
       uses: pypa/gh-action-pypi-publish@release/v1
-      with:
-        user: __token__
-        password: ${{ secrets.PYPI_API_TOKEN }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/looseversion-1.1.2/CHANGES.md 
new/looseversion-1.3.0/CHANGES.md
--- old/looseversion-1.1.2/CHANGES.md   2023-02-22 14:55:05.000000000 +0100
+++ new/looseversion-1.3.0/CHANGES.md   2023-07-05 18:05:41.000000000 +0200
@@ -2,6 +2,19 @@
 
 ## Releases
 
+### 1.3.0 (5 Jul 2023)
+
+- 2023.07.05
+  - Restore Python 3 semantics for `LooseVersion`, creating `LooseVersion2`
+    to restore Python 2 semantics.
+
+### 1.2.0 (25 May 2023)
+
+- 2023.05.25
+  - Test on Python 3.12
+  - Enable installation on Python 2+
+  - Ensure consistent semantics between Python 2 and 3
+
 ### 1.1.2 (22 Feb 2023)
 
 - 2023.02.22
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/looseversion-1.1.2/pyproject.toml 
new/looseversion-1.3.0/pyproject.toml
--- old/looseversion-1.1.2/pyproject.toml       2023-02-22 14:55:05.000000000 
+0100
+++ new/looseversion-1.3.0/pyproject.toml       2023-07-05 18:05:41.000000000 
+0200
@@ -5,7 +5,7 @@
 [project]
 name = "looseversion"
 maintainers = [{name = "Chris Markiewicz", email = "effig...@gmail.com"}]
-version = "1.1.2"
+version = "1.3.0"
 description = "Version numbering for anarchists and software realists"
 readme = "README.md"
 license = {file = "LICENSE"}
@@ -15,7 +15,6 @@
     "License :: OSI Approved :: Python Software Foundation License",
 ]
 urls = {Homepage = "https://github.com/effigies/looseversion"}
-requires-python = ">=3"
 
 [tool.hatch.build]
 exclude = [".github"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/looseversion-1.1.2/src/looseversion/__init__.py 
new/looseversion-1.3.0/src/looseversion/__init__.py
--- old/looseversion-1.1.2/src/looseversion/__init__.py 2023-02-22 
14:55:05.000000000 +0100
+++ new/looseversion-1.3.0/src/looseversion/__init__.py 2023-07-05 
18:05:41.000000000 +0200
@@ -16,8 +16,6 @@
     of the same class or a string (which will be parsed to an instance
     of the same class, thus must follow the same rules)
 """
-from __future__ import annotations
-
 import re
 import sys
 
@@ -86,8 +84,26 @@
 # have a conception that matches common notions about version numbers.
 
 
-class LooseVersion:
+if sys.version_info >= (3,):
+
+    class _Py2Int(int):
+        """Integer object that compares < any string"""
+
+        def __gt__(self, other):
+            if isinstance(other, str):
+                return False
+            return super().__gt__(other)
+
+        def __lt__(self, other):
+            if isinstance(other, str):
+                return True
+            return super().__lt__(other)
+
+else:
+    _Py2Int = int
 
+
+class LooseVersion(object):
     """Version numbering for anarchists and software realists.
     Implements the standard interface for version number classes as
     described above.  A version number consists of a series of numbers,
@@ -119,52 +135,48 @@
     of "want").
     """
 
-    component_re: re.Pattern[str] = re.compile(r"(\d+ | [a-z]+ | \.)", 
re.VERBOSE)
-    vstring: str
-    version: list[int | str]
+    component_re = re.compile(r"(\d+ | [a-z]+ | \.)", re.VERBOSE)
 
-    def __init__(self, vstring: str | None = None):
+    def __init__(self, vstring=None):
         if vstring:
             self.parse(vstring)
 
-    def __eq__(self, other: object) -> bool:
+    def __eq__(self, other):
         c = self._cmp(other)
         if c is NotImplemented:
             return NotImplemented
         return c == 0
 
-    def __lt__(self, other: object) -> bool:
+    def __lt__(self, other):
         c = self._cmp(other)
         if c is NotImplemented:
             return NotImplemented
         return c < 0
 
-    def __le__(self, other: object) -> bool:
+    def __le__(self, other):
         c = self._cmp(other)
         if c is NotImplemented:
             return NotImplemented
         return c <= 0
 
-    def __gt__(self, other: object) -> bool:
+    def __gt__(self, other):
         c = self._cmp(other)
         if c is NotImplemented:
             return NotImplemented
         return c > 0
 
-    def __ge__(self, other: object) -> bool:
+    def __ge__(self, other):
         c = self._cmp(other)
         if c is NotImplemented:
             return NotImplemented
         return c >= 0
 
-    def parse(self, vstring: str) -> None:
+    def parse(self, vstring):
         # I've given up on thinking I can reconstruct the version string
         # from the parsed tuple -- so I just store the string here for
         # use by __str__
         self.vstring = vstring
-        components: list[str | int] = [
-            x for x in self.component_re.split(vstring) if x and x != "."
-        ]
+        components = [x for x in self.component_re.split(vstring) if x and x 
!= "."]
         for i, obj in enumerate(components):
             try:
                 components[i] = int(obj)
@@ -173,13 +185,13 @@
 
         self.version = components
 
-    def __str__(self) -> str:
+    def __str__(self):
         return self.vstring
 
-    def __repr__(self) -> str:
+    def __repr__(self):
         return "LooseVersion ('%s')" % str(self)
 
-    def _cmp(self, other: object) -> int:
+    def _cmp(self, other):
         other = self._coerce(other)
         if other is NotImplemented:
             return NotImplemented
@@ -192,12 +204,12 @@
             return 1
         return NotImplemented
 
-    @staticmethod
-    def _coerce(other: object) -> LooseVersion:
-        if isinstance(other, LooseVersion):
+    @classmethod
+    def _coerce(cls, other):
+        if isinstance(other, cls):
             return other
         elif isinstance(other, str):
-            return LooseVersion(other)
+            return cls(other)
         elif "distutils" in sys.modules:
             # Using this check to avoid importing distutils and suppressing 
the warning
             try:
@@ -205,5 +217,27 @@
             except ImportError:
                 return NotImplemented
             if isinstance(other, deprecated):
-                return LooseVersion(str(other))
+                return cls(str(other))
         return NotImplemented
+
+
+class LooseVersion2(LooseVersion):
+    """LooseVersion variant that restores Python 2 semantics
+
+    In Python 2, comparing LooseVersions where paired components could be 
string
+    and int always resulted in the string being "greater". In Python 3, this 
produced
+    a TypeError.
+    """
+    def parse(self, vstring):
+        # I've given up on thinking I can reconstruct the version string
+        # from the parsed tuple -- so I just store the string here for
+        # use by __str__
+        self.vstring = vstring
+        components = [x for x in self.component_re.split(vstring) if x and x 
!= "."]
+        for i, obj in enumerate(components):
+            try:
+                components[i] = _Py2Int(obj)
+            except ValueError:
+                pass
+
+        self.version = components
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/looseversion-1.1.2/src/looseversion/__init__.pyi 
new/looseversion-1.3.0/src/looseversion/__init__.pyi
--- old/looseversion-1.1.2/src/looseversion/__init__.pyi        2023-02-22 
14:55:05.000000000 +0100
+++ new/looseversion-1.3.0/src/looseversion/__init__.pyi        2023-07-05 
18:05:41.000000000 +0200
@@ -1,10 +1,10 @@
 from re import Pattern
-from typing import Union
+from typing import List, Union
 
 class LooseVersion:
     component_re: Pattern[str]
     vstring: str
-    version: Union[str, int]
+    version: List[Union[str, int]]
     def __init__(self, vstring: Union[str, None] = ...) -> None: ...
     def __eq__(self, other: object) -> bool: ...
     def __lt__(self, other: object) -> bool: ...
@@ -12,3 +12,5 @@
     def __gt__(self, other: object) -> bool: ...
     def __ge__(self, other: object) -> bool: ...
     def parse(self, vstring: str) -> None: ...
+
+class LooseVersion2(LooseVersion): ...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/looseversion-1.1.2/tests.py 
new/looseversion-1.3.0/tests.py
--- old/looseversion-1.1.2/tests.py     2023-02-22 14:55:05.000000000 +0100
+++ new/looseversion-1.3.0/tests.py     2023-07-05 18:05:41.000000000 +0200
@@ -16,8 +16,9 @@
 
 @pytest.mark.skipif(not have_distutils, reason="Needs distutils")
 @pytest.mark.parametrize("v1, v2", [("0.0.0", "0.0.0"), ("0.0.0", "1.0.0")])
-def test_LooseVersion_compat(v1, v2):
-    vend1, vend2 = lv.LooseVersion(v1), lv.LooseVersion(v2)
+@pytest.mark.parametrize("lvtype", [lv.LooseVersion, lv.LooseVersion2])
+def test_LooseVersion_compat(v1, v2, lvtype):
+    vend1, vend2 = lvtype(v1), lvtype(v2)
     with warnings.catch_warnings():
         warnings.simplefilter("ignore")
         orig1, orig2 = dv.LooseVersion(v1), dv.LooseVersion(v2)
@@ -39,18 +40,23 @@
 
 
 # Adapted from Cpython:Lib/distutils/tests/test_version.py
-@pytest.mark.parametrize("v1,v2,result",
-    [('1.5.1', '1.5.2b2', -1),
-     ('161', '3.10a', 1),
-     ('8.02', '8.02', 0),
-     ('3.4j', '1996.07.12', -1),
-     ('3.2.pl0', '3.1.1.6', 1),
-     ('2g6', '11g', -1),
-     ('0.960923', '2.2beta29', -1),
-     ('1.13++', '5.5.kw', -1)])
-def test_cmp(v1, v2, result):
-    loosev1 = lv.LooseVersion(v1)
-    loosev2 = lv.LooseVersion(v2)
+@pytest.mark.parametrize(
+    "v1,v2,result",
+    [
+        ("1.5.1", "1.5.2b2", -1),
+        ("161", "3.10a", 1),
+        ("8.02", "8.02", 0),
+        ("3.4j", "1996.07.12", -1),
+        ("3.2.pl0", "3.1.1.6", 1),
+        ("2g6", "11g", -1),
+        ("0.960923", "2.2beta29", -1),
+        ("1.13++", "5.5.kw", -1),
+    ],
+)
+@pytest.mark.parametrize("lvtype", [lv.LooseVersion, lv.LooseVersion2])
+def test_cmp(v1, v2, result, lvtype):
+    loosev1 = lvtype(v1)
+    loosev2 = lvtype(v2)
     assert loosev1._cmp(loosev2) == result
     assert loosev1._cmp(v2) == result
     assert loosev2._cmp(loosev1) == -result
@@ -59,22 +65,45 @@
     assert loosev2._cmp(object()) == NotImplemented
 
 
-@pytest.mark.parametrize('vstring,version',
+@pytest.mark.parametrize(
+    "vstring,version",
     [
-        ('1.5.1', [1, 5, 1]),
-        ('1.5.2b2', [1, 5, 2, 'b', 2]),
-        ('161', [161]),
-        ('3.10a', [3, 10, 'a']),
-        ('1.13++', [1, 13, '++']),
+        ("1.5.1", [1, 5, 1]),
+        ("1.5.2b2", [1, 5, 2, "b", 2]),
+        ("161", [161]),
+        ("3.10a", [3, 10, "a"]),
+        ("1.13++", [1, 13, "++"]),
     ],
 )
-def test_split(vstring, version):
+@pytest.mark.parametrize("lvtype", [lv.LooseVersion, lv.LooseVersion2])
+def test_split(vstring, version, lvtype):
     # Regression test to ensure we don't accidentally break parsing (again)
     # This can be changed if the version representation changes
-    v = lv.LooseVersion(vstring)
+    v = lvtype(vstring)
     assert v.vstring == vstring
     assert v.version == version
 
 
-if __name__ == '__main__':
+@pytest.mark.parametrize(
+    "v1,v2,result",
+    [
+        ("0.3@v0.3", "0.3.1@v0.3.1", 1),
+        ("0.3.1@v0.3.1", "0.3@v0.3", -1),
+        ("13.0-beta3", "13.0.1", 1),
+        ("13.0.1", "13.0-beta3", -1),
+    ],
+)
+def test_py2_rules(v1, v2, result):
+    """Python 2 did allow strings and numbers to be compared.
+    Verify consistent, generally unintuitive behavior.
+    """
+    loosev1 = lv.LooseVersion2(v1)
+    loosev2 = lv.LooseVersion2(v2)
+    assert loosev1._cmp(loosev2) == result
+    assert loosev1._cmp(v2) == result
+    assert loosev2._cmp(loosev1) == -result
+    assert loosev2._cmp(v1) == -result
+
+
+if __name__ == "__main__":
     sys.exit(pytest.main([__file__] + sys.argv[1:]))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/looseversion-1.1.2/tox.ini 
new/looseversion-1.3.0/tox.ini
--- old/looseversion-1.1.2/tox.ini      2023-02-22 14:55:05.000000000 +0100
+++ new/looseversion-1.3.0/tox.ini      2023-07-05 18:05:41.000000000 +0200
@@ -1,6 +1,6 @@
 [tox]
 isolated_build = true
-envlist = py{36,37,38,39,310,311,py3}, type
+envlist = py{36,37,38,39,310,311,312,py3}, type
 skip_missing_interpreters = True
 
 [testenv]
@@ -25,4 +25,5 @@
   3.9: py39
   3.10: py310
   3.11: py311, type
+  3.12: py312
   pypy-3.7: pypy3

Reply via email to