Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 6669ba0

Browse filesBrowse files
committed
Integrate better doctest integration into pytest
* Fix typos in `README.rst`. * Move `coerce()` function into separate file; this was needed so it can be both included into the documentation and inside `conftest.py`. * In `docs/usage.rst`: - Fix typos - Add missing semver module name as prefix - Slightly rewrite some doctests which involves dicts (unfortunately, order matters still in Python2) * In `setup.cfg`: - Add `--doctest-glob` option to look for all `*.rst` files. - Add `testpaths` key to restrict testing paths to current dir and `docs`. * Update `CHANGELOG.rst`
1 parent 6878916 commit 6669ba0
Copy full SHA for 6669ba0

File tree

Expand file treeCollapse file tree

7 files changed

+80
-64
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+80
-64
lines changed

‎CHANGELOG.rst

Copy file name to clipboardExpand all lines: CHANGELOG.rst
+7-2Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@ Features
1818
Bug Fixes
1919
---------
2020

21-
* :gh:`224` (:pr:`226`): Replaced in class ``clean``, ``super(CleanCommand, self).run()`` with
22-
``CleanCommand.run(self)``
21+
* :gh:`224` (:pr:`226`): In ``setup.py``, replaced in class ``clean``,
22+
``super(CleanCommand, self).run()`` with ``CleanCommand.run(self)``
2323

2424

25+
Additions
26+
---------
27+
28+
* :pr:`228`: Added better doctest integration
29+
2530
Removals
2631
--------
2732

‎README.rst

Copy file name to clipboardExpand all lines: README.rst
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ different parts, use the `semver.parse` function:
6868
>>> ver['prerelease']
6969
'pre.2'
7070
>>> ver['build']
71-
'build.5'
71+
'build.4'
7272
7373
To raise parts of a version, there are a couple of functions available for
7474
you. The `semver.parse_version_info` function converts a version string
@@ -87,7 +87,7 @@ It is allowed to concatenate different "bump functions":
8787
.. code-block:: python
8888
8989
>>> ver.bump_major().bump_minor()
90-
VersionInfo(major=4, minor=0, patch=1, prerelease=None, build=None)
90+
VersionInfo(major=4, minor=1, patch=0, prerelease=None, build=None)
9191
9292
To compare two versions, semver provides the `semver.compare` function.
9393
The return value indicates the relationship between the first and second

‎conftest.py

Copy file name to clipboard
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import pytest
22
import semver
3+
import sys
4+
5+
sys.path.insert(0, "docs")
6+
7+
from coerce import coerce # noqa:E402
38

49

510
@pytest.fixture(autouse=True)
611
def add_semver(doctest_namespace):
712
doctest_namespace["semver"] = semver
13+
doctest_namespace["coerce"] = coerce

‎docs/coerce.py

Copy file name to clipboard
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import re
2+
import semver
3+
4+
BASEVERSION = re.compile(
5+
r"""[vV]?
6+
(?P<major>0|[1-9]\d*)
7+
(\.
8+
(?P<minor>0|[1-9]\d*)
9+
(\.
10+
(?P<patch>0|[1-9]\d*)
11+
)?
12+
)?
13+
""",
14+
re.VERBOSE,
15+
)
16+
17+
18+
def coerce(version):
19+
"""
20+
Convert an incomplete version string into a semver-compatible VersionInfo
21+
object
22+
23+
* Tries to detect a "basic" version string (``major.minor.patch``).
24+
* If not enough components can be found, missing components are
25+
set to zero to obtain a valid semver version.
26+
27+
:param str version: the version string to convert
28+
:return: a tuple with a :class:`VersionInfo` instance (or ``None``
29+
if it's not a version) and the rest of the string which doesn't
30+
belong to a basic version.
31+
:rtype: tuple(:class:`VersionInfo` | None, str)
32+
"""
33+
match = BASEVERSION.search(version)
34+
if not match:
35+
return (None, version)
36+
37+
ver = {
38+
key: 0 if value is None else value for key, value in match.groupdict().items()
39+
}
40+
ver = semver.VersionInfo(**ver)
41+
rest = match.string[match.end() :] # noqa:E203
42+
return ver, rest

‎docs/development.rst

Copy file name to clipboardExpand all lines: docs/development.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ documentation includes:
174174
1
175175
>>> semver.compare("2.0.0", "2.0.0")
176176
0
177+
177178
"""
178179

179180
* **The documentation**

‎docs/usage.rst

Copy file name to clipboardExpand all lines: docs/usage.rst
+19-58Lines changed: 19 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ A version can be created in different ways:
5151
integers::
5252

5353
>>> semver.VersionInfo(1, 2, 3, 4, 5)
54-
VersionInfo(major=1, minor=2, patch=3, prerelease=4, build=5)
54+
VersionInfo(major=1, minor=2, patch=3, prerelease='4', build='5')
5555

5656
If you pass an invalid version string you will get a ``ValueError``::
5757

5858
>>> semver.parse("1.2")
59-
Traceback (most recent call last)
59+
Traceback (most recent call last):
6060
...
6161
ValueError: 1.2 is not valid SemVer string
6262

@@ -80,8 +80,8 @@ Parsing a Version String
8080

8181
* With :func:`semver.parse`::
8282

83-
>>> semver.parse("3.4.5-pre.2+build.4")
84-
{'major': 3, 'minor': 4, 'patch': 5, 'prerelease': 'pre.2', 'build': 'build.4'}
83+
>>> semver.parse("3.4.5-pre.2+build.4") == {'major': 3, 'minor': 4, 'patch': 5, 'prerelease': 'pre.2', 'build': 'build.4'}
84+
True
8585

8686

8787
Checking for a Valid Semver Version
@@ -92,9 +92,9 @@ classmethod :func:`semver.VersionInfo.isvalid`:
9292

9393
.. code-block:: python
9494
95-
>>> VersionInfo.isvalid("1.0.0")
95+
>>> semver.VersionInfo.isvalid("1.0.0")
9696
True
97-
>>> VersionInfo.isvalid("invalid")
97+
>>> semver.VersionInfo.isvalid("invalid")
9898
False
9999
100100
@@ -106,7 +106,7 @@ parts of a version:
106106

107107
.. code-block:: python
108108
109-
>>> v = VersionInfo.parse("3.4.5-pre.2+build.4")
109+
>>> v = semver.VersionInfo.parse("3.4.5-pre.2+build.4")
110110
>>> v.major
111111
3
112112
>>> v.minor
@@ -122,20 +122,20 @@ However, the attributes are read-only. You cannot change an attribute.
122122
If you do, you get an ``AttributeError``::
123123

124124
>>> v.minor = 5
125-
Traceback (most recent call last)
125+
Traceback (most recent call last):
126126
...
127127
AttributeError: attribute 'minor' is readonly
128128

129129
In case you need the different parts of a version stepwise, iterate over the :class:`semver.VersionInfo` instance::
130130

131-
>>> for item in VersionInfo.parse("3.4.5-pre.2+build.4"):
131+
>>> for item in semver.VersionInfo.parse("3.4.5-pre.2+build.4"):
132132
... print(item)
133133
3
134134
4
135135
5
136136
pre.2
137137
build.4
138-
>>> list(VersionInfo.parse("3.4.5-pre.2+build.4"))
138+
>>> list(semver.VersionInfo.parse("3.4.5-pre.2+build.4"))
139139
[3, 4, 5, 'pre.2', 'build.4']
140140

141141

@@ -160,12 +160,12 @@ unmodified, use one of the functions :func:`semver.replace` or
160160
If you pass invalid keys you get an exception::
161161

162162
>>> semver.replace("1.2.3", invalidkey=2)
163-
Traceback (most recent call last)
163+
Traceback (most recent call last):
164164
...
165165
TypeError: replace() got 1 unexpected keyword argument(s): invalidkey
166166
>>> version = semver.VersionInfo.parse("1.4.5-pre.1+build.6")
167167
>>> version.replace(invalidkey=2)
168-
Traceback (most recent call last)
168+
Traceback (most recent call last):
169169
...
170170
TypeError: replace() got 1 unexpected keyword argument(s): invalidkey
171171

@@ -209,8 +209,8 @@ Depending which function you call, you get different types
209209
* From a :class:`semver.VersionInfo` into a dictionary::
210210

211211
>>> v = semver.VersionInfo(major=3, minor=4, patch=5)
212-
>>> semver.parse(str(v))
213-
{'major': 3, 'minor': 4, 'patch': 5, 'prerelease': None, 'build': None}
212+
>>> semver.parse(str(v)) == {'major': 3, 'minor': 4, 'patch': 5, 'prerelease': None, 'build': None}
213+
True
214214

215215

216216
Increasing Parts of a Version
@@ -267,8 +267,8 @@ To compare two versions depends on your type:
267267
Use the specific operator. Currently, the operators ``<``,
268268
``<=``, ``>``, ``>=``, ``==``, and ``!=`` are supported::
269269

270-
>>> v1 = VersionInfo.parse("3.4.5")
271-
>>> v2 = VersionInfo.parse("3.5.1")
270+
>>> v1 = semver.VersionInfo.parse("3.4.5")
271+
>>> v2 = semver.VersionInfo.parse("3.5.1")
272272
>>> v1 < v2
273273
True
274274
>>> v1 > v2
@@ -278,7 +278,7 @@ To compare two versions depends on your type:
278278

279279
Use the operator as with two :class:`semver.VersionInfo` types::
280280

281-
>>> v = VersionInfo.parse("3.4.5")
281+
>>> v = semver.VersionInfo.parse("3.4.5")
282282
>>> v > (1, 0)
283283
True
284284
>>> v < (3, 5)
@@ -350,48 +350,9 @@ However, "basic" version strings consisting of major, minor,
350350
and patch part, can be easy to convert. The following function extract this
351351
information and returns a tuple with two items:
352352

353-
.. code-block:: python
353+
.. literalinclude:: coerce.py
354+
:language: python
354355

355-
import re
356-
357-
BASEVERSION = re.compile(
358-
r"""[vV]?
359-
(?P<major>0|[1-9]\d*)
360-
(\.
361-
(?P<minor>0|[1-9]\d*)
362-
(\.
363-
(?P<patch>0|[1-9]\d*)
364-
)?
365-
)?
366-
""",
367-
re.VERBOSE,
368-
)
369-
def coerce(version):
370-
"""
371-
Convert an incomplete version string into a semver-compatible VersionInfo
372-
object
373-
374-
* Tries to detect a "basic" version string (``major.minor.patch``).
375-
* If not enough components can be found, missing components are
376-
set to zero to obtain a valid semver version.
377-
378-
:param str version: the version string to convert
379-
:return: a tuple with a :class:`VersionInfo` instance (or ``None``
380-
if it's not a version) and the rest of the string which doesn't
381-
belong to a basic version.
382-
:rtype: tuple(:class:`VersionInfo` | None, str)
383-
"""
384-
match = BASEVERSION.search(version)
385-
if not match:
386-
return (None, version)
387-
388-
ver = {
389-
key: 0 if value is None else value
390-
for key, value in match.groupdict().items()
391-
}
392-
ver = semver.VersionInfo(**ver)
393-
rest = match.string[match.end() :]
394-
return ver, rest
395356

396357
The function returns a *tuple*, containing a :class:`VersionInfo`
397358
instance or None as the first element and the rest as the second element.

‎setup.cfg

Copy file name to clipboardExpand all lines: setup.cfg
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
[tool:pytest]
22
norecursedirs = .git build .env/ env/ .pyenv/ .tmp/ .eggs/
3+
testpaths = . docs
34
addopts =
4-
--ignore=.eggs/
55
--no-cov-on-fail
66
--cov=semver
77
--cov-report=term-missing
8+
--doctest-glob='*.rst'
89
--doctest-modules
910
--doctest-report ndiff
1011

@@ -17,4 +18,4 @@ exclude =
1718
.git,
1819
__pycache__,
1920
build,
20-
dist
21+
dist

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.