Skip to content

Commit 6e8231c

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 5600d1e commit 6e8231c

File tree

4 files changed

+131
-12
lines changed

4 files changed

+131
-12
lines changed

CHANGELOG.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,51 @@ in our repository.
1616

1717
.. towncrier release notes start
1818
19+
Version 3.0.0-dev.3
20+
===================
21+
22+
:Released: 2022-10-04
23+
:Maintainer:
24+
25+
26+
Features
27+
--------
28+
29+
* :pr:`359`: Add optional parameter ``optional_minor_and_patch`` in :meth:`.Version.parse` to allow optional
30+
minor and patch parts.
31+
32+
* :pr:`362`: Make :meth:`.Version.match` accept a bare version string as match expression, defaulting to
33+
equality testing.
34+
35+
* :gh:`364`: Enhance :file:`pyproject.toml` to make it possible to use the
36+
:command:`pyproject-build` command from the build module.
37+
For more information, see :ref:`build-semver`.
38+
39+
40+
41+
Improved Documentation
42+
----------------------
43+
44+
* :gh:`335`: Add new section "Converting versions between PyPI and semver" the limitations
45+
and possible use cases to convert from one into the other versioning scheme.
46+
47+
* :gh:`340`: Describe how to get version from a file
48+
49+
* :gh:`343`: Describe combining Pydantic with semver in the "Advanced topic"
50+
section.
51+
52+
* :gh:`350`: Restructure usage section. Create subdirectory "usage/" and splitted
53+
all section into different files.
54+
55+
* :gh:`351`: Introduce new topics for:
56+
57+
* "Migration to semver3"
58+
* "Advanced topics"
59+
60+
61+
62+
----
63+
1964

2065
Version 3.0.0-dev.3
2166
===================

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: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -298,39 +298,64 @@ def bump_patch(self) -> "Version":
298298
cls = type(self)
299299
return cls(self._major, self._minor, self._patch + 1)
300300

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

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

335360
def compare(self, other: Comparable) -> int:
336361
"""

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy