Skip to content

Commit 90bf1be

Browse files
authored
Document how to create subclass from VersionInfo (#287)
Related to issue #276
1 parent db55f27 commit 90bf1be

File tree

5 files changed

+75
-2
lines changed

5 files changed

+75
-2
lines changed

conftest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
sys.path.insert(0, "docs")
66

77
from coerce import coerce # noqa:E402
8+
from semverwithvprefix import SemVerWithVPrefix
89

910

1011
@pytest.fixture(autouse=True)
1112
def add_semver(doctest_namespace):
1213
doctest_namespace["semver"] = semver
1314
doctest_namespace["coerce"] = coerce
15+
doctest_namespace["SemVerWithVPrefix"] = SemVerWithVPrefix

docs/semverwithvprefix.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from semver import VersionInfo
2+
3+
4+
class SemVerWithVPrefix(VersionInfo):
5+
"""
6+
A subclass of VersionInfo which allows a "v" prefix
7+
"""
8+
9+
@classmethod
10+
def parse(cls, version):
11+
"""
12+
Parse version string to a VersionInfo instance.
13+
14+
:param version: version string with "v" or "V" prefix
15+
:type version: str
16+
:raises ValueError: when version does not start with "v" or "V"
17+
:return: a new instance
18+
:rtype: :class:`SemVerWithVPrefix`
19+
"""
20+
if not version[0] in ("v", "V"):
21+
raise ValueError(
22+
"{v!r}: not a valid semantic version tag. Must start with 'v' or 'V'".format(
23+
v=version
24+
)
25+
)
26+
self = super(SemVerWithVPrefix, cls).parse(version[1:])
27+
return self
28+
29+
def __str__(self):
30+
# Reconstruct the tag
31+
return "v" + super(SemVerWithVPrefix, self).__str__()

docs/usage.rst

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,8 @@ The "old way" with :func:`semver.max_ver` or :func:`semver.min_ver` is still ava
571571
'1.0.0'
572572
573573
574+
.. _sec_dealing_with_invalid_versions:
575+
574576
Dealing with Invalid Versions
575577
-----------------------------
576578

@@ -749,3 +751,39 @@ the following methods:
749751
For further details, see the section
750752
`Overriding the default filter <https://docs.python.org/3/library/warnings.html#overriding-the-default-filter>`_
751753
of the Python documentation.
754+
755+
756+
.. _sec_creating_subclasses_from_versioninfo:
757+
758+
Creating Subclasses from VersionInfo
759+
------------------------------------
760+
761+
If you do not like creating functions to modify the behavior of semver
762+
(as shown in section :ref:`sec_dealing_with_invalid_versions`), you can
763+
also create a subclass of the :class:`VersionInfo` class.
764+
765+
For example, if you want to output a "v" prefix before a version,
766+
but the other behavior is the same, use the following code:
767+
768+
.. literalinclude:: semverwithvprefix.py
769+
:language: python
770+
:lines: 4-
771+
772+
773+
The derived class :class:`SemVerWithVPrefix` can be used like
774+
the original class:
775+
776+
.. code-block:: python
777+
778+
>>> v1 = SemVerWithVPrefix.parse("v1.2.3")
779+
>>> assert str(v1) == "v1.2.3"
780+
>>> print(v1)
781+
v1.2.3
782+
>>> v2 = SemVerWithVPrefix.parse("v2.3.4")
783+
>>> v2 > v1
784+
True
785+
>>> bad = SemVerWithVPrefix.parse("1.2.4")
786+
Traceback (most recent call last):
787+
...
788+
ValueError: '1.2.4': not a valid semantic version tag. Must start with 'v' or 'V'
789+

setup.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ exclude =
2222
__pycache__,
2323
build,
2424
dist
25+
docs
26+
conftest.py

test_semver.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,9 +1162,9 @@ def test_subclass_from_versioninfo():
11621162
class SemVerWithVPrefix(VersionInfo):
11631163
@classmethod
11641164
def parse(cls, version):
1165-
if not version.startswith("v"):
1165+
if not version[0] in ("v", "V"):
11661166
raise ValueError(
1167-
"{v}: not a valid semantic version tag".format(v=version)
1167+
"{v!r}: version must start with 'v' or 'V'".format(v=version)
11681168
)
11691169
return super(SemVerWithVPrefix, cls).parse(version[1:])
11701170

0 commit comments

Comments
 (0)