Skip to content

Commit 4b30940

Browse files
committed
Fix #344 Allow empty string for bump method
The methods .bump_prerelease('') and .bump_build('') generates a prerelease and build part without the token.
1 parent bf8757a commit 4b30940

File tree

3 files changed

+84
-11
lines changed

3 files changed

+84
-11
lines changed

docs/usage/raise-parts-of-a-version.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,28 @@ a version:
2828
'3.4.5-pre.2+build.5'
2929
3030
Likewise the module level functions :func:`semver.bump_major`.
31+
32+
For the functions :func:`Version.bump_prerelease <semver.version.Version.bump_prerelease>` and :func:`Version.bump_build <semver.version.Version.bump_build>` it's possible to pass an empty string or ``None``. However,
33+
it gives different results::
34+
35+
.. code-block:: python
36+
37+
>>> str(Version.parse("3.4.5").bump_prerelease(''))
38+
'3.4.5-1'
39+
>>> str(Version.parse("3.4.5").bump_prerelease(None))
40+
'3.4.5-rc.1'
41+
42+
An empty string removes any prefix whereas ``None`` is the same as calling
43+
the method without any argument.
44+
45+
If you already have a prerelease, the argument for the method
46+
is not taken into account:
47+
48+
.. code-block:: python
49+
50+
>>> str(Version.parse("3.4.5-rc.1").bump_prerelease(None))
51+
'3.4.5-rc.2'
52+
>>> str(Version.parse("3.4.5-rc.1").bump_prerelease(''))
53+
'3.4.5-rc.2'
54+
55+

src/semver/version.py

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -297,38 +297,62 @@ def bump_patch(self) -> "Version":
297297
cls = type(self)
298298
return cls(self._major, self._minor, self._patch + 1)
299299

300-
def bump_prerelease(self, token: str = "rc") -> "Version":
300+
def bump_prerelease(self, token: Optional[str] = "rc") -> "Version":
301301
"""
302302
Raise the prerelease part of the version, return a new object but leave
303303
self untouched.
304304
305-
:param token: defaults to ``rc``
306-
:return: new object with the raised prerelease part
305+
:param token: defaults to ``'rc'``
306+
:return: new :class:`Version` object with the raised prerelease part.
307+
The original object is not modified.
307308
308309
>>> ver = semver.parse("3.4.5")
309-
>>> ver.bump_prerelease()
310-
Version(major=3, minor=4, patch=5, prerelease='rc.2', \
311-
build=None)
310+
>>> ver.bump_prerelease().prerelease
311+
'rc.2'
312+
>>> ver.bump_prerelease('').prerelease
313+
'1'
312314
"""
313315
cls = type(self)
314-
prerelease = cls._increment_string(self._prerelease or (token or "rc") + ".0")
316+
if self._prerelease is not None:
317+
prerelease = self._prerelease
318+
elif token == "":
319+
prerelease = "0"
320+
elif token is None:
321+
prerelease = "rc.0"
322+
else:
323+
prerelease = str(token) + ".0"
324+
325+
# self._prerelease or (token or "rc") + ".0"
326+
prerelease = cls._increment_string(prerelease)
315327
return cls(self._major, self._minor, self._patch, prerelease)
316328

317-
def bump_build(self, token: str = "build") -> "Version":
329+
# VersionPart = Union[int, Optional[str]]
330+
def bump_build(self, token: Optional[str] = "build") -> "Version":
318331
"""
319332
Raise the build part of the version, return a new object but leave self
320333
untouched.
321334
322-
:param token: defaults to ``build``
323-
:return: new object with the raised build part
335+
:param token: defaults to ``'build'``
336+
:return: new :class:`Version` object with the raised build part.
337+
The original object is not modified.
324338
325339
>>> ver = semver.parse("3.4.5-rc.1+build.9")
326340
>>> ver.bump_build()
327341
Version(major=3, minor=4, patch=5, prerelease='rc.1', \
328342
build='build.10')
329343
"""
330344
cls = type(self)
331-
build = cls._increment_string(self._build or (token or "build") + ".0")
345+
if self._build is not None:
346+
build = self._build
347+
elif token == "":
348+
build = "0"
349+
elif token is None:
350+
build = "build.0"
351+
else:
352+
build = str(token) + ".0"
353+
354+
# self._build or (token or "build") + ".0"
355+
build = cls._increment_string(build)
332356
return cls(self._major, self._minor, self._patch, self._prerelease, build)
333357

334358
def compare(self, other: Comparable) -> int:

tests/test_bump.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,30 @@ def test_should_versioninfo_bump_multiple():
6666
assert v.bump_prerelease().bump_build().bump_build().bump_prerelease() == expected
6767

6868

69+
def test_should_versioninfo_bump_prerelease_with_empty_str():
70+
v = parse_version_info("3.4.5")
71+
expected = parse_version_info("3.4.5-1")
72+
assert v.bump_prerelease("") == expected
73+
74+
75+
def test_should_versioninfo_bump_prerelease_with_none():
76+
v = parse_version_info("3.4.5")
77+
expected = parse_version_info("3.4.5-rc.1")
78+
assert v.bump_prerelease(None) == expected
79+
80+
81+
def test_should_versioninfo_bump_build_with_empty_str():
82+
v = parse_version_info("3.4.5")
83+
expected = parse_version_info("3.4.5+1")
84+
assert v.bump_build("") == expected
85+
86+
87+
def test_should_versioninfo_bump_build_with_none():
88+
v = parse_version_info("3.4.5")
89+
expected = parse_version_info("3.4.5+build.1")
90+
assert v.bump_build(None) == expected
91+
92+
6993
def test_should_ignore_extensions_for_bump():
7094
assert bump_patch("3.4.5-rc1+build4") == "3.4.6"
7195

0 commit comments

Comments
 (0)