Hello community,

here is the log from the commit of package python-semver for openSUSE:Factory 
checked in at 2020-11-06 23:45:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-semver (Old)
 and      /work/SRC/openSUSE:Factory/.python-semver.new.11331 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-semver"

Fri Nov  6 23:45:13 2020 rev:14 rq:846445 version:2.13.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-semver/python-semver.changes      
2020-07-20 21:01:32.209102987 +0200
+++ /work/SRC/openSUSE:Factory/.python-semver.new.11331/python-semver.changes   
2020-11-06 23:46:12.483135840 +0100
@@ -1,0 +2,22 @@
+Fri Oct 30 11:22:16 UTC 2020 - Sebastian Wagner <sebix+novell....@sebix.at>
+
+- update to version 2.13.0:
+ - Features:
+  - :pr:`287`: Document how to create subclass from ``VersionInfo``
+ - Bug Fixes:
+  - :pr:`283`: Ensure equal versions have equal hashes.
+    Version equality means for semver, that ``major``,
+    ``minor``, ``patch``, and ``prerelease`` parts are
+    equal in both versions you compare. The ``build`` part
+    is ignored.
+- update to version 2.12.0:
+ - Bug Fixes:
+  - :gh:`291` (:pr:`292`): Disallow negative numbers of
+    major, minor, and patch for ``semver.VersionInfo``
+- update to version 2.11.0:
+ - Bug Fixes:
+  - :gh:`276` (:pr:`277`): VersionInfo.parse should be a class method
+     Also add authors and update changelog in :gh:`286`
+  - :gh:`274` (:pr:`275`): Py2 vs. Py3 incompatibility TypeError
+
+-------------------------------------------------------------------

Old:
----
  semver-2.10.2.tar.gz

New:
----
  semver-2.13.0.tar.gz

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

Other differences:
------------------
++++++ python-semver.spec ++++++
--- /var/tmp/diff_new_pack.vUqq8V/_old  2020-11-06 23:46:13.143134572 +0100
+++ /var/tmp/diff_new_pack.vUqq8V/_new  2020-11-06 23:46:13.147134564 +0100
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without test
 Name:           python-semver
-Version:        2.10.2
+Version:        2.13.0
 Release:        0
 Summary:        Python helper for Semantic Versioning
 License:        BSD-3-Clause

++++++ semver-2.10.2.tar.gz -> semver-2.13.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/CHANGELOG.rst 
new/semver-2.13.0/CHANGELOG.rst
--- old/semver-2.10.2/CHANGELOG.rst     2020-06-15 20:33:06.000000000 +0200
+++ new/semver-2.13.0/CHANGELOG.rst     2020-10-20 22:09:30.000000000 +0200
@@ -6,6 +6,90 @@
 All notable changes to this code base will be documented in this file,
 in every released version.
 
+Version 2.13.0
+==============
+
+:Released: 2020-10-20
+:Maintainer: Tom Schraitle
+
+Features
+--------
+
+* :pr:`287`: Document how to create subclass from ``VersionInfo``
+
+
+Bug Fixes
+---------
+
+* :pr:`283`: Ensure equal versions have equal hashes.
+  Version equality means for semver, that ``major``,
+  ``minor``, ``patch``, and ``prerelease`` parts are
+  equal in both versions you compare. The ``build`` part
+  is ignored.
+
+
+Version 2.12.0
+==============
+
+:Released: 2020-10-19
+:Maintainer: Tom Schraitle
+
+Features
+--------
+
+n/a
+
+
+Bug Fixes
+---------
+
+* :gh:`291` (:pr:`292`): Disallow negative numbers of
+  major, minor, and patch for ``semver.VersionInfo``
+
+
+Additions
+---------
+
+n/a
+
+
+Deprecations
+------------
+
+n/a
+
+
+Version 2.11.0
+==============
+
+:Released: 2020-10-17
+:Maintainer: Tom Schraitle
+
+Features
+--------
+
+n/a
+
+
+Bug Fixes
+---------
+
+* :gh:`276` (:pr:`277`): VersionInfo.parse should be a class method
+   Also add authors and update changelog in :gh:`286`
+* :gh:`274` (:pr:`275`): Py2 vs. Py3 incompatibility TypeError
+
+
+Additions
+---------
+
+n/a
+
+
+Deprecations
+------------
+
+n/a
+
 
 Version 2.10.2
 ==============
@@ -22,8 +106,8 @@
 Bug Fixes
 ---------
 
-:gh:`260` (:pr:`261`): Fixed ``__getitem__`` returning None on wrong parts
-:pr:`263`: Doc: Add missing "install" subcommand for openSUSE
+* :gh:`260` (:pr:`261`): Fixed ``__getitem__`` returning None on wrong parts
+* :pr:`263`: Doc: Add missing "install" subcommand for openSUSE
 
 
 Additions
@@ -32,7 +116,7 @@
 n/a
 
 Deprecations
---------
+------------
 
 * :gh:`160` (:pr:`264`):
     * :func:`semver.max_ver`
@@ -92,7 +176,7 @@
 
 
 Deprecations
---------
+------------
 * :gh:`225` (:pr:`229`): Output a DeprecationWarning for the following 
functions:
 
   - ``semver.parse``
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/CONTRIBUTORS 
new/semver-2.13.0/CONTRIBUTORS
--- old/semver-2.10.2/CONTRIBUTORS      2020-05-10 17:18:24.000000000 +0200
+++ new/semver-2.13.0/CONTRIBUTORS      2020-10-20 22:09:30.000000000 +0200
@@ -27,12 +27,15 @@
 * Ben Finney <ben+pyt...@benfinney.id.au>
 * Carles Barrobés <car...@barrobes.com>
 * Craig Blaszczyk <masterja...@gmail.com>
+* Damien Nadé <an...@users.noreply.github.com>
+* Eli Bishop <eli-dar...@users.noreply.github.com>
 * George Sakkis <gsak...@users.noreply.github.com>
 * Jan Pieter Waagmeester <jie...@jieter.nl>
 * Jelo Agnasin <j...@icannhas.com>
 * Karol Werner <karol.wer...@ppkt.eu>
 * Peter Bittner <dja...@bittner.it>
 * robi-wan <robi-...@suyu.de>
+* sbrudenell <sbruden...@users.noreply.github.com>
 * T. Jameson Little <t.jameson.lit...@gmail.com>
 * Tom Schraitle <tom_s...@web.de>
 * Thomas Laferriere <tlaferri...@users.noreply.github.com>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/PKG-INFO new/semver-2.13.0/PKG-INFO
--- old/semver-2.10.2/PKG-INFO  2020-06-15 20:33:56.000000000 +0200
+++ new/semver-2.13.0/PKG-INFO  2020-10-20 22:12:30.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: semver
-Version: 2.10.2
+Version: 2.13.0
 Summary: Python helper for Semantic Versioning (http://semver.org/)
 Home-page: https://github.com/python-semver/python-semver
 Author: Kostiantyn Rybnikov
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/conftest.py 
new/semver-2.13.0/conftest.py
--- old/semver-2.10.2/conftest.py       2020-04-26 10:46:39.000000000 +0200
+++ new/semver-2.13.0/conftest.py       2020-10-20 20:00:05.000000000 +0200
@@ -5,9 +5,11 @@
 sys.path.insert(0, "docs")
 
 from coerce import coerce  # noqa:E402
+from semverwithvprefix import SemVerWithVPrefix
 
 
 @pytest.fixture(autouse=True)
 def add_semver(doctest_namespace):
     doctest_namespace["semver"] = semver
     doctest_namespace["coerce"] = coerce
+    doctest_namespace["SemVerWithVPrefix"] = SemVerWithVPrefix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/docs/development.rst 
new/semver-2.13.0/docs/development.rst
--- old/semver-2.10.2/docs/development.rst      2020-04-26 10:46:39.000000000 
+0200
+++ new/semver-2.13.0/docs/development.rst      2020-10-16 14:18:45.000000000 
+0200
@@ -154,8 +154,9 @@
 
   * **A docstring**
 
-    Each docstring contains a summary line, a linebreak, the description
-    of its arguments in `Sphinx style`_, and an optional doctest.
+    Each docstring contains a summary line, a linebreak, an optional
+    directive (see next item), the description of its arguments in
+    `Sphinx style`_, and an optional doctest.
     The docstring is extracted and reused in the :ref:`api` section.
     An appropriate docstring should look like this::
 
@@ -177,6 +178,43 @@
 
             """
 
+  * **An optional directive**
+
+    If you introduce a new feature, change a function/method, or remove 
something,
+    it is a good practice to introduce Sphinx directives into the docstring.
+    This gives the reader an idea what version is affected by this change.
+
+    The first required argument, ``VERSION``, defines the version when this 
change
+    was introduced. You can choose from:
+
+    * ``.. versionadded:: VERSION``
+
+      Use this directive to describe a new feature.
+
+    * ``.. versionchanged:: VERSION``
+
+      Use this directive to describe when something has changed, for example,
+      new parameters were added, changed side effects, different return 
values, etc.
+
+    * ``.. deprecated:: VERSION``
+
+      Use this directive when a feature is deprecated. Describe what should
+      be used instead, if appropriate.
+
+
+    Add such a directive *after* the summary line, if needed.
+    An appropriate directive could look like this::
+
+        def to_tuple(self):
+            """
+            Convert the VersionInfo object to a tuple.
+
+            .. versionadded:: 2.10.0
+               Renamed ``VersionInfo._astuple`` to ``VersionInfo.to_tuple`` to
+               make this function available in the public API.
+            [...]
+            """
+
   * **The documentation**
 
     A docstring is good, but in most cases it's too dense. Describe how
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/docs/semverwithvprefix.py 
new/semver-2.13.0/docs/semverwithvprefix.py
--- old/semver-2.10.2/docs/semverwithvprefix.py 1970-01-01 01:00:00.000000000 
+0100
+++ new/semver-2.13.0/docs/semverwithvprefix.py 2020-10-20 20:00:05.000000000 
+0200
@@ -0,0 +1,31 @@
+from semver import VersionInfo
+
+
+class SemVerWithVPrefix(VersionInfo):
+    """
+    A subclass of VersionInfo which allows a "v" prefix
+    """
+
+    @classmethod
+    def parse(cls, version):
+        """
+        Parse version string to a VersionInfo instance.
+
+        :param version: version string with "v" or "V" prefix
+        :type version: str
+        :raises ValueError: when version does not start with "v" or "V"
+        :return: a new instance
+        :rtype: :class:`SemVerWithVPrefix`
+        """
+        if not version[0] in ("v", "V"):
+            raise ValueError(
+                "{v!r}: not a valid semantic version tag. Must start with 'v' 
or 'V'".format(
+                    v=version
+                )
+            )
+        self = super(SemVerWithVPrefix, cls).parse(version[1:])
+        return self
+
+    def __str__(self):
+        # Reconstruct the tag
+        return "v" + super(SemVerWithVPrefix, self).__str__()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/docs/usage.rst 
new/semver-2.13.0/docs/usage.rst
--- old/semver-2.10.2/docs/usage.rst    2020-06-15 17:33:05.000000000 +0200
+++ new/semver-2.13.0/docs/usage.rst    2020-10-20 20:00:05.000000000 +0200
@@ -45,10 +45,17 @@
 
 A :class:`semver.VersionInfo` instance can be created in different ways:
 
-* From a string::
+* From a string (a Unicode string in Python 2)::
 
     >>> semver.VersionInfo.parse("3.4.5-pre.2+build.4")
     VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
+    >>> semver.VersionInfo.parse(u"5.3.1")
+    VersionInfo(major=5, minor=3, patch=1, prerelease=None, build=None)
+
+* From a byte string::
+
+    >>> semver.VersionInfo.parse(b"2.3.4")
+    VersionInfo(major=2, minor=3, patch=4, prerelease=None, build=None)
 
 * From individual parts by a dictionary::
 
@@ -56,6 +63,14 @@
     >>> semver.VersionInfo(**d)
     VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
 
+  Keep in mind, the ``major``, ``minor``, ``patch`` parts has to
+  be positive.
+
+    >>> semver.VersionInfo(-1)
+    Traceback (most recent call last):
+    ...
+    ValueError: 'major' is negative. A version can only be positive.
+
   As a minimum requirement, your dictionary needs at least the ``major``
   key, others can be omitted. You get a ``TypeError`` if your
   dictionary contains invalid keys.
@@ -452,6 +467,32 @@
 (for examples, see :ref:`sec_max_min`) and :func:`sorted`.
 
 
+Determining Version Equality
+----------------------------
+
+Version equality means for semver, that major, minor, patch, and prerelease
+parts are equal in both versions you compare. The build part is ignored.
+For example::
+
+    >>> v = semver.VersionInfo.parse("1.2.3-rc4+1e4664d")
+    >>> v == "1.2.3-rc4+dedbeef"
+    True
+
+This also applies when a :class:`semver.VersionInfo` is a member of a set, or a
+dictionary key::
+
+    >>> d = {}
+    >>> v1 = semver.VersionInfo.parse("1.2.3-rc4+1e4664d")
+    >>> v2 = semver.VersionInfo.parse("1.2.3-rc4+dedbeef")
+    >>> d[v1] = 1
+    >>> d[v2]
+    1
+    >>> s = set()
+    >>> s.add(v1)
+    >>> v2 in s
+    True
+
+
 
 Comparing Versions through an Expression
 ----------------------------------------
@@ -530,6 +571,8 @@
     '1.0.0'
 
 
+.. _sec_dealing_with_invalid_versions:
+
 Dealing with Invalid Versions
 -----------------------------
 
@@ -708,3 +751,39 @@
    For further details, see the section
    `Overriding the default filter 
<https://docs.python.org/3/library/warnings.html#overriding-the-default-filter>`_
    of the Python documentation.
+
+
+.. _sec_creating_subclasses_from_versioninfo:
+
+Creating Subclasses from VersionInfo
+------------------------------------
+
+If you do not like creating functions to modify the behavior of semver
+(as shown in section :ref:`sec_dealing_with_invalid_versions`), you can
+also create a subclass of the :class:`VersionInfo` class.
+
+For example, if you want to output a "v" prefix before a version,
+but the other behavior is the same, use the following code:
+
+.. literalinclude:: semverwithvprefix.py
+   :language: python
+   :lines: 4-
+
+
+The derived class :class:`SemVerWithVPrefix` can be used like
+the original class:
+
+.. code-block:: python
+
+     >>> v1 = SemVerWithVPrefix.parse("v1.2.3")
+     >>> assert str(v1) == "v1.2.3"
+     >>> print(v1)
+     v1.2.3
+     >>> v2 = SemVerWithVPrefix.parse("v2.3.4")
+     >>> v2 > v1
+     True
+     >>> bad = SemVerWithVPrefix.parse("1.2.4")
+     Traceback (most recent call last):
+     ...
+     ValueError: '1.2.4': not a valid semantic version tag. Must start with 
'v' or 'V'
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/semver.egg-info/PKG-INFO 
new/semver-2.13.0/semver.egg-info/PKG-INFO
--- old/semver-2.10.2/semver.egg-info/PKG-INFO  2020-06-15 20:33:56.000000000 
+0200
+++ new/semver-2.13.0/semver.egg-info/PKG-INFO  2020-10-20 22:12:30.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: semver
-Version: 2.10.2
+Version: 2.13.0
 Summary: Python helper for Semantic Versioning (http://semver.org/)
 Home-page: https://github.com/python-semver/python-semver
 Author: Kostiantyn Rybnikov
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/semver.egg-info/SOURCES.txt 
new/semver-2.13.0/semver.egg-info/SOURCES.txt
--- old/semver-2.10.2/semver.egg-info/SOURCES.txt       2020-06-15 
20:33:56.000000000 +0200
+++ new/semver-2.13.0/semver.egg-info/SOURCES.txt       2020-10-20 
22:12:30.000000000 +0200
@@ -13,6 +13,7 @@
 setup.cfg
 setup.py
 test_semver.py
+test_typeerror-274.py
 tox.ini
 docs/Makefile
 docs/api.rst
@@ -27,6 +28,7 @@
 docs/pysemver.rst
 docs/readme.rst
 docs/requirements.txt
+docs/semverwithvprefix.py
 docs/usage.rst
 docs/_static/css/default.css
 semver.egg-info/PKG-INFO
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/semver.py new/semver-2.13.0/semver.py
--- old/semver-2.10.2/semver.py 2020-06-15 18:41:10.000000000 +0200
+++ new/semver-2.13.0/semver.py 2020-10-20 22:09:30.000000000 +0200
@@ -10,7 +10,11 @@
 import warnings
 
 
-__version__ = "2.10.2"
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+
+
+__version__ = "2.13.0"
 __author__ = "Kostiantyn Rybnikov"
 __author_email__ = "k...@k-bx.com"
 __maintainer__ = ["Sebastien Celles", "Tom Schraitle"]
@@ -60,6 +64,53 @@
         return (a > b) - (a < b)
 
 
+if PY3:  # pragma: no cover
+    string_types = str, bytes
+    text_type = str
+    binary_type = bytes
+
+    def b(s):
+        return s.encode("latin-1")
+
+    def u(s):
+        return s
+
+
+else:  # pragma: no cover
+    string_types = unicode, str
+    text_type = unicode
+    binary_type = str
+
+    def b(s):
+        return s
+
+    # Workaround for standalone backslash
+    def u(s):
+        return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape")
+
+
+def ensure_str(s, encoding="utf-8", errors="strict"):
+    # Taken from six project
+    """
+    Coerce *s* to `str`.
+
+    For Python 2:
+      - `unicode` -> encoded to `str`
+      - `str` -> `str`
+
+    For Python 3:
+      - `str` -> `str`
+      - `bytes` -> decoded to `str`
+    """
+    if not isinstance(s, (text_type, binary_type)):
+        raise TypeError("not expecting type '%s'" % type(s))
+    if PY2 and isinstance(s, text_type):
+        s = s.encode(encoding, errors)
+    elif PY3 and isinstance(s, binary_type):
+        s = s.decode(encoding, errors)
+    return s
+
+
 def deprecated(func=None, replace=None, version=None, 
category=DeprecationWarning):
     """
     Decorates a function to output a deprecation warning.
@@ -144,7 +195,7 @@
 
     @wraps(operator)
     def wrapper(self, other):
-        comparable_types = (VersionInfo, dict, tuple, list, str)
+        comparable_types = (VersionInfo, dict, tuple, list, text_type, 
binary_type)
         if not isinstance(other, comparable_types):
             raise TypeError(
                 "other type %r must be in %r" % (type(other), comparable_types)
@@ -192,9 +243,24 @@
     )
 
     def __init__(self, major, minor=0, patch=0, prerelease=None, build=None):
-        self._major = int(major)
-        self._minor = int(minor)
-        self._patch = int(patch)
+        # Build a dictionary of the arguments except prerelease and build
+        version_parts = {
+            "major": major,
+            "minor": minor,
+            "patch": patch,
+        }
+
+        for name, value in version_parts.items():
+            value = int(value)
+            version_parts[name] = value
+            if value < 0:
+                raise ValueError(
+                    "{!r} is negative. A version can only be 
positive.".format(name)
+                )
+
+        self._major = version_parts["major"]
+        self._minor = version_parts["minor"]
+        self._patch = version_parts["patch"]
         self._prerelease = None if prerelease is None else str(prerelease)
         self._build = None if build is None else str(build)
 
@@ -423,7 +489,7 @@
         0
         """
         cls = type(self)
-        if isinstance(other, str):
+        if isinstance(other, string_types):
             other = cls.parse(other)
         elif isinstance(other, dict):
             other = cls(**other)
@@ -575,7 +641,7 @@
         return version
 
     def __hash__(self):
-        return hash(self.to_tuple())
+        return hash(self.to_tuple()[:4])
 
     def finalize_version(self):
         """
@@ -637,8 +703,8 @@
 
         return cmp_res in possibilities
 
-    @staticmethod
-    def parse(version):
+    @classmethod
+    def parse(cls, version):
         """
         Parse version string to a VersionInfo instance.
 
@@ -647,11 +713,15 @@
         :raises: :class:`ValueError`
         :rtype: :class:`VersionInfo`
 
+        .. versionchanged:: 2.11.0
+           Changed method from static to classmethod to
+           allow subclasses.
+
         >>> semver.VersionInfo.parse('3.4.5-pre.2+build.4')
         VersionInfo(major=3, minor=4, patch=5, \
 prerelease='pre.2', build='build.4')
         """
-        match = VersionInfo._REGEX.match(version)
+        match = cls._REGEX.match(ensure_str(version))
         if match is None:
             raise ValueError("%s is not valid SemVer string" % version)
 
@@ -661,7 +731,7 @@
         version_parts["minor"] = int(version_parts["minor"])
         version_parts["patch"] = int(version_parts["patch"])
 
-        return VersionInfo(**version_parts)
+        return cls(**version_parts)
 
     def replace(self, **parts):
         """
@@ -825,7 +895,7 @@
     >>> semver.max_ver("1.0.0", "2.0.0")
     '2.0.0'
     """
-    if isinstance(ver1, str):
+    if isinstance(ver1, string_types):
         ver1 = VersionInfo.parse(ver1)
     elif not isinstance(ver1, VersionInfo):
         raise TypeError()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/setup.cfg new/semver-2.13.0/setup.cfg
--- old/semver-2.10.2/setup.cfg 2020-06-15 20:33:56.000000000 +0200
+++ new/semver-2.13.0/setup.cfg 2020-10-20 22:12:30.000000000 +0200
@@ -13,6 +13,7 @@
 
 [flake8]
 max-line-length = 88
+ignore = F821,W503
 exclude = 
        .env,
        .eggs,
@@ -21,6 +22,8 @@
        __pycache__,
        build,
        dist
+       docs
+       conftest.py
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/test_semver.py 
new/semver-2.13.0/test_semver.py
--- old/semver-2.10.2/test_semver.py    2020-06-15 17:33:05.000000000 +0200
+++ new/semver-2.13.0/test_semver.py    2020-10-20 20:00:05.000000000 +0200
@@ -74,6 +74,20 @@
 
 
 @pytest.mark.parametrize(
+    "ver",
+    [
+        {"major": -1},
+        {"major": 1, "minor": -2},
+        {"major": 1, "minor": 2, "patch": -3},
+        {"major": 1, "minor": -2, "patch": 3},
+    ],
+)
+def test_should_not_allow_negative_numbers(ver):
+    with pytest.raises(ValueError, match=".* is negative. .*"):
+        VersionInfo(**ver)
+
+
+@pytest.mark.parametrize(
     "version,expected",
     [
         # no. 1
@@ -679,6 +693,20 @@
     d[v] = ""  # to ensure that VersionInfo are hashable
 
 
+def test_equal_versions_have_equal_hashes():
+    v1 = parse_version_info("1.2.3-alpha.1.2+build.11.e0f985a")
+    v2 = parse_version_info("1.2.3-alpha.1.2+build.22.a589f0e")
+    assert v1 == v2
+    assert hash(v1) == hash(v2)
+    d = {}
+    d[v1] = 1
+    d[v2] = 2
+    assert d[v1] == 2
+    s = set()
+    s.add(v1)
+    assert v2 in s
+
+
 def test_parse_method_for_version_info():
     s_version = "1.2.3-alpha.1.2+build.11.e0f985a"
     v = VersionInfo.parse(s_version)
@@ -1128,3 +1156,21 @@
 )
 def test_repr(version, expected):
     assert repr(version) == expected
+
+
+def test_subclass_from_versioninfo():
+    class SemVerWithVPrefix(VersionInfo):
+        @classmethod
+        def parse(cls, version):
+            if not version[0] in ("v", "V"):
+                raise ValueError(
+                    "{v!r}: version must start with 'v' or 
'V'".format(v=version)
+                )
+            return super(SemVerWithVPrefix, cls).parse(version[1:])
+
+        def __str__(self):
+            # Reconstruct the tag.
+            return "v" + super(SemVerWithVPrefix, self).__str__()
+
+    v = SemVerWithVPrefix.parse("v1.2.3")
+    assert str(v) == "v1.2.3"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/semver-2.10.2/test_typeerror-274.py 
new/semver-2.13.0/test_typeerror-274.py
--- old/semver-2.10.2/test_typeerror-274.py     1970-01-01 01:00:00.000000000 
+0100
+++ new/semver-2.13.0/test_typeerror-274.py     2020-10-17 13:50:57.000000000 
+0200
@@ -0,0 +1,102 @@
+import pytest
+import sys
+
+import semver
+
+
+PY2 = sys.version_info[0] == 2
+PY3 = sys.version_info[0] == 3
+
+
+def ensure_binary(s, encoding="utf-8", errors="strict"):
+    """Coerce **s** to six.binary_type.
+
+    For Python 2:
+      - `unicode` -> encoded to `str`
+      - `str` -> `str`
+
+    For Python 3:
+      - `str` -> encoded to `bytes`
+      - `bytes` -> `bytes`
+    """
+    if isinstance(s, semver.text_type):
+        return s.encode(encoding, errors)
+    elif isinstance(s, semver.binary_type):
+        return s
+    else:
+        raise TypeError("not expecting type '%s'" % type(s))
+
+
+def test_should_work_with_string_and_unicode():
+    result = semver.compare(semver.u("1.1.0"), semver.b("1.2.2"))
+    assert result == -1
+    result = semver.compare(semver.b("1.1.0"), semver.u("1.2.2"))
+    assert result == -1
+
+
+class TestEnsure:
+    # From six project
+    # grinning face emoji
+    UNICODE_EMOJI = semver.u("\U0001F600")
+    BINARY_EMOJI = b"\xf0\x9f\x98\x80"
+
+    def test_ensure_binary_raise_type_error(self):
+        with pytest.raises(TypeError):
+            semver.ensure_str(8)
+
+    def test_errors_and_encoding(self):
+        ensure_binary(self.UNICODE_EMOJI, encoding="latin-1", errors="ignore")
+        with pytest.raises(UnicodeEncodeError):
+            ensure_binary(self.UNICODE_EMOJI, encoding="latin-1", 
errors="strict")
+
+    def test_ensure_binary_raise(self):
+        converted_unicode = ensure_binary(
+            self.UNICODE_EMOJI, encoding="utf-8", errors="strict"
+        )
+        converted_binary = ensure_binary(
+            self.BINARY_EMOJI, encoding="utf-8", errors="strict"
+        )
+        if semver.PY2:
+            # PY2: unicode -> str
+            assert converted_unicode == self.BINARY_EMOJI and isinstance(
+                converted_unicode, str
+            )
+            # PY2: str -> str
+            assert converted_binary == self.BINARY_EMOJI and isinstance(
+                converted_binary, str
+            )
+        else:
+            # PY3: str -> bytes
+            assert converted_unicode == self.BINARY_EMOJI and isinstance(
+                converted_unicode, bytes
+            )
+            # PY3: bytes -> bytes
+            assert converted_binary == self.BINARY_EMOJI and isinstance(
+                converted_binary, bytes
+            )
+
+    def test_ensure_str(self):
+        converted_unicode = semver.ensure_str(
+            self.UNICODE_EMOJI, encoding="utf-8", errors="strict"
+        )
+        converted_binary = semver.ensure_str(
+            self.BINARY_EMOJI, encoding="utf-8", errors="strict"
+        )
+        if PY2:
+            # PY2: unicode -> str
+            assert converted_unicode == self.BINARY_EMOJI and isinstance(
+                converted_unicode, str
+            )
+            # PY2: str -> str
+            assert converted_binary == self.BINARY_EMOJI and isinstance(
+                converted_binary, str
+            )
+        else:
+            # PY3: str -> str
+            assert converted_unicode == self.UNICODE_EMOJI and isinstance(
+                converted_unicode, str
+            )
+            # PY3: bytes -> str
+            assert converted_binary == self.UNICODE_EMOJI and isinstance(
+                converted_unicode, str
+            )


Reply via email to