pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/rbarrois/python-semanticversion/commit/a5cc0fb509b2c515ae73c85f9a4d426a3f9100e3

rossorigen="anonymous" media="all" rel="stylesheet" href="https://github.githubassets.com/assets/global-b40ec823a1a6a1af.css" /> Allow Version(major=1, ...). · rbarrois/python-semanticversion@a5cc0fb · GitHub
Skip to content

Commit a5cc0fb

Browse files
committed
Allow Version(major=1, ...).
Eases the creation of version objects from existing versions. We still validate the type and structure of each component.
1 parent fdef1e9 commit a5cc0fb

5 files changed

Lines changed: 98 additions & 2 deletions

File tree

ChangeLog

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
ChangeLog
22
=========
33

4+
2.7.0 (unreleased)
5+
------------------
6+
7+
*New:*
8+
9+
* Allow creation of a ``Version`` directly from parsed components, as keyword arguments
10+
(``Version(major=1, minor=2, patch=3)``)
11+
412

513
2.6.0 (2016-09-25)
614
------------------

README.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ It is also possible to check whether a given string is a proper semantic version
149149
False
150150
151151
152+
Finally, one may create a :class:`Version` with named components instead:
153+
154+
.. code-block:: pycon
155+
156+
>>> semantic_version.Version(major=0, minor=1, patch=2)
157+
Version('0.1.2')
158+
159+
In that case, ``major``, ``minor`` and ``patch`` are mandatory, and must be integers.
160+
``prerelease`` and ``patch``, if provided, must be tuples of strings:
161+
162+
.. code-block:: pycon
163+
164+
>>> semantic_version.Version(major=0, minor=1, patch=2, prerelease=('alpha', '2'))
165+
Version('0.1.2-alpha.2')
166+
167+
152168
Requirement specification
153169
-------------------------
154170

docs/reference.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ Representing a version (the Version class)
7676
>>> str(Version('1.1.1'))
7777
'1.1.1'
7878

79+
.. class:: Version(major: int, minor: int, patch: int, prereleases: tuple, build: tuple[, partial=False])
80+
81+
Constructed from named components:
82+
83+
.. code-block:: pycon
84+
85+
>>> Version(major=1, minor=2, patch=3)
86+
Version('1.2.3')
87+
88+
7989
8090
.. rubric:: Attributes
8191

semantic_version/base.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,30 @@ class Version(object):
7373
version_re = re.compile(r'^(\d+)\.(\d+)\.(\d+)(?:-([0-9a-zA-Z.-]+))?(?:\+([0-9a-zA-Z.-]+))?$')
7474
partial_version_re = re.compile(r'^(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:-([0-9a-zA-Z.-]*))?(?:\+([0-9a-zA-Z.-]*))?$')
7575

76-
def __init__(self, version_string, partial=False):
77-
major, minor, patch, prerelease, build = self.parse(version_string, partial)
76+
def __init__(
77+
self,
78+
version_string=None,
79+
*,
80+
major=None,
81+
minor=None,
82+
patch=None,
83+
prerelease=None,
84+
build=None,
85+
partial=False,
86+
):
87+
has_text = version_string is not None
88+
has_parts = not (major is minor is patch is prerelease is build is None)
89+
if not has_text ^ has_parts:
90+
raise ValueError("Call either Version('1.2.3') or Version(major=1, ...).")
91+
92+
if has_text:
93+
major, minor, patch, prerelease, build = self.parse(version_string, partial)
94+
else:
95+
# Convenience: allow to omit prerelease/build.
96+
if not partial:
97+
prerelease = prerelease or ()
98+
build = build or ()
99+
self._validate_kwargs(major, minor, patch, prerelease, build, partial)
78100

79101
self.major = major
80102
self.minor = minor
@@ -254,6 +276,25 @@ def _validate_identifiers(cls, identifiers, allow_leading_zeroes=False):
254276
if item[0] == '0' and item.isdigit() and item != '0' and not allow_leading_zeroes:
255277
raise ValueError("Invalid leading zero in identifier %r" % item)
256278

279+
@classmethod
280+
def _validate_kwargs(cls, major, minor, patch, prerelease, build, partial):
281+
if (
282+
major != int(major)
283+
or minor != cls._coerce(minor, partial)
284+
or patch != cls._coerce(patch, partial)
285+
or prerelease is None and not partial
286+
or build is None and not partial
287+
):
288+
raise ValueError(
289+
"Invalid kwargs to Version(major=%r, minor=%r, patch=%r, "
290+
"prerelease=%r, build=%r, partial=%r" % (
291+
major, minor, patch, prerelease, build, partial
292+
))
293+
if prerelease is not None:
294+
cls._validate_identifiers(prerelease, allow_leading_zeroes=False)
295+
if build is not None:
296+
cls._validate_identifiers(build, allow_leading_zeroes=True)
297+
257298
def __iter__(self):
258299
return iter((self.major, self.minor, self.patch, self.prerelease, self.build))
259300

tests/test_parsing.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ class ParsingTestCase(unittest.TestCase):
2828
'0.1.2-rc1.3-14.15+build.2012-01-01.11h34',
2929
]
3030

31+
valid_fields = [
32+
('0.1.1', [0, 1, 1, (), ()]),
33+
('0.1.1', [0, 1, 1, None, None]),
34+
('0.1.2-rc1', [0, 1, 2, ('rc1',), ()]),
35+
('0.1.2-rc1.3.4', [0, 1, 2, ('rc1', '3', '4'), ()]),
36+
('0.1.2+build42-12.2012-01-01.12h23', [0, 1, 2, (), ('build42-12', '2012-01-01', '12h23')]),
37+
('0.1.2-rc1.3-14.15+build.2012-01-01.11h34', [0, 1, 2, ('rc1', '3-14', '15'), ('build', '2012-01-01', '11h34')]),
38+
]
39+
3140
def test_invalid(self):
3241
for invalid in self.invalids:
3342
self.assertRaises(ValueError, semantic_version.Version, invalid)
@@ -37,6 +46,18 @@ def test_simple(self):
3746
version = semantic_version.Version(valid)
3847
self.assertEqual(valid, str(version))
3948

49+
def test_kwargs(self):
50+
for text, fields in self.valid_fields:
51+
major, minor, patch, prerelease, build = fields
52+
version = semantic_version.Version(
53+
major=major,
54+
minor=minor,
55+
patch=patch,
56+
prerelease=prerelease,
57+
build=build,
58+
)
59+
self.assertEqual(text, str(version))
60+
4061

4162
class ComparisonTestCase(unittest.TestCase):
4263
order = [

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

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