Repository: python-semver/python-semver (python)

Issue:
VersionInfo.next_version() returns Union[VersionInfo, str]
`VersionInfo.next_version()` return type is uncertain because at line 463 of semver.py `return version.replace(prerelease=None, build=None)` returns a VersionInfo object, whereas in line 466 it is explicitly converted to `str` and at line 470, `version.bump_prerelease()` is documented with `rtype: str`.  
This is problematic because if you call this on a version that has a prerelease or build number, you get a `VersionInfo` object, and otherwise you get a `str`, and these two types must be handled quite differently.

Personally, I would expect `VersionInfo.next_version()` to return a `VersionInfo` object in all cases, but I think the main problem here is the ambiguity of the return type.

Pull request description:
Fix #251: Correct return type for next_version()
@tomschr if you could take a look that would be appreciated.

Patch:
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 94564c7..028e7fe 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -6,6 +6,32 @@ Change Log
 All notable changes to this code base will be documented in this file,
 in every released version.
 
+Version 2.10.1 (WIP)
+====================
+
+:Released: 2020-0x-0y
+:Maintainer:
+
+
+Features
+--------
+
+
+Bug Fixes
+---------
+
+* :gh:`251` (:pr:`254`): Fixed return type of ``semver.VersionInfo.next_version``
+  to always return a ``VersionInfo`` instance.
+
+
+Additions
+---------
+
+
+Removals
+--------
+
+
 Version 2.10.0
 ==============
 
diff --git a/semver.py b/semver.py
index c2697dd..cf53535 100644
--- a/semver.py
+++ b/semver.py
@@ -471,7 +471,8 @@ build='build.10')
 
         :param part: One of "major", "minor", "patch", or "prerelease"
         :param prerelease_token: prefix string of prerelease, defaults to 'rc'
-        :return:
+        :return: new object with the appropriate part raised
+        :rtype: :class:`VersionInfo`
         """
         validparts = {
             "major",
@@ -495,7 +496,7 @@ build='build.10')
             return version.replace(prerelease=None, build=None)
 
         if part in ("major", "minor", "patch"):
-            return str(getattr(version, "bump_" + part)())
+            return getattr(version, "bump_" + part)()
 
         if not version.prerelease:
             version = version.bump_patch()


Test patch:
diff --git a/test_semver.py b/test_semver.py
index db0c7f4..8ecc81f 100644
--- a/test_semver.py
+++ b/test_semver.py
@@ -1050,4 +1050,6 @@ def test_next_version_with_invalid_parts():
 )
 def test_next_version_with_versioninfo(version, part, expected):
     ver = VersionInfo.parse(version)
-    assert str(ver.next_version(part)) == expected
+    next_version = ver.next_version(part)
+    assert isinstance(next_version, VersionInfo)
+    assert str(next_version) == expected