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 <[email protected]>
+
+- 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 = "[email protected]"}]
-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)
[email protected]("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
[email protected]("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)
[email protected](
+ "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),
+ ],
+)
[email protected]("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
[email protected]('vstring,version',
[email protected](
+ "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):
[email protected]("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__':
[email protected](
+ "v1,v2,result",
+ [
+ ("[email protected]", "[email protected]", 1),
+ ("[email protected]", "[email protected]", -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