Skip to content

Add better doctest integration into pytest #228

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,15 @@ Features
Bug Fixes
---------

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


Additions
---------

* :pr:`228`: Added better doctest integration

Removals
--------

Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ different parts, use the `semver.parse` function:
>>> ver['prerelease']
'pre.2'
>>> ver['build']
'build.5'
'build.4'

To raise parts of a version, there are a couple of functions available for
you. The `semver.parse_version_info` function converts a version string
Expand All @@ -87,7 +87,7 @@ It is allowed to concatenate different "bump functions":
.. code-block:: python

>>> ver.bump_major().bump_minor()
VersionInfo(major=4, minor=0, patch=1, prerelease=None, build=None)
VersionInfo(major=4, minor=1, patch=0, prerelease=None, build=None)

To compare two versions, semver provides the `semver.compare` function.
The return value indicates the relationship between the first and second
Expand Down
6 changes: 6 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import pytest
import semver
import sys

sys.path.insert(0, "docs")

from coerce import coerce # noqa:E402


@pytest.fixture(autouse=True)
def add_semver(doctest_namespace):
doctest_namespace["semver"] = semver
doctest_namespace["coerce"] = coerce
42 changes: 42 additions & 0 deletions docs/coerce.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import re
import semver

BASEVERSION = re.compile(
r"""[vV]?
(?P<major>0|[1-9]\d*)
(\.
(?P<minor>0|[1-9]\d*)
(\.
(?P<patch>0|[1-9]\d*)
)?
)?
""",
re.VERBOSE,
)


def coerce(version):
"""
Convert an incomplete version string into a semver-compatible VersionInfo
object

* Tries to detect a "basic" version string (``major.minor.patch``).
* If not enough components can be found, missing components are
set to zero to obtain a valid semver version.

:param str version: the version string to convert
:return: a tuple with a :class:`VersionInfo` instance (or ``None``
if it's not a version) and the rest of the string which doesn't
belong to a basic version.
:rtype: tuple(:class:`VersionInfo` | None, str)
"""
match = BASEVERSION.search(version)
if not match:
return (None, version)

ver = {
key: 0 if value is None else value for key, value in match.groupdict().items()
}
ver = semver.VersionInfo(**ver)
rest = match.string[match.end() :] # noqa:E203
return ver, rest
1 change: 1 addition & 0 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ documentation includes:
1
>>> semver.compare("2.0.0", "2.0.0")
0

"""

* **The documentation**
Expand Down
77 changes: 19 additions & 58 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ A version can be created in different ways:
integers::

>>> semver.VersionInfo(1, 2, 3, 4, 5)
VersionInfo(major=1, minor=2, patch=3, prerelease=4, build=5)
VersionInfo(major=1, minor=2, patch=3, prerelease='4', build='5')

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

>>> semver.parse("1.2")
Traceback (most recent call last)
Traceback (most recent call last):
...
ValueError: 1.2 is not valid SemVer string

Expand All @@ -80,8 +80,8 @@ Parsing a Version String

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

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


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

.. code-block:: python

>>> VersionInfo.isvalid("1.0.0")
>>> semver.VersionInfo.isvalid("1.0.0")
True
>>> VersionInfo.isvalid("invalid")
>>> semver.VersionInfo.isvalid("invalid")
False


Expand All @@ -106,7 +106,7 @@ parts of a version:

.. code-block:: python

>>> v = VersionInfo.parse("3.4.5-pre.2+build.4")
>>> v = semver.VersionInfo.parse("3.4.5-pre.2+build.4")
>>> v.major
3
>>> v.minor
Expand All @@ -122,20 +122,20 @@ However, the attributes are read-only. You cannot change an attribute.
If you do, you get an ``AttributeError``::

>>> v.minor = 5
Traceback (most recent call last)
Traceback (most recent call last):
...
AttributeError: attribute 'minor' is readonly

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

>>> for item in VersionInfo.parse("3.4.5-pre.2+build.4"):
>>> for item in semver.VersionInfo.parse("3.4.5-pre.2+build.4"):
... print(item)
3
4
5
pre.2
build.4
>>> list(VersionInfo.parse("3.4.5-pre.2+build.4"))
>>> list(semver.VersionInfo.parse("3.4.5-pre.2+build.4"))
[3, 4, 5, 'pre.2', 'build.4']


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

>>> semver.replace("1.2.3", invalidkey=2)
Traceback (most recent call last)
Traceback (most recent call last):
...
TypeError: replace() got 1 unexpected keyword argument(s): invalidkey
>>> version = semver.VersionInfo.parse("1.4.5-pre.1+build.6")
>>> version.replace(invalidkey=2)
Traceback (most recent call last)
Traceback (most recent call last):
...
TypeError: replace() got 1 unexpected keyword argument(s): invalidkey

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

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


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

>>> v1 = VersionInfo.parse("3.4.5")
>>> v2 = VersionInfo.parse("3.5.1")
>>> v1 = semver.VersionInfo.parse("3.4.5")
>>> v2 = semver.VersionInfo.parse("3.5.1")
>>> v1 < v2
True
>>> v1 > v2
Expand All @@ -278,7 +278,7 @@ To compare two versions depends on your type:

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

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

.. code-block:: python
.. literalinclude:: coerce.py
:language: python

import re

BASEVERSION = re.compile(
r"""[vV]?
(?P<major>0|[1-9]\d*)
(\.
(?P<minor>0|[1-9]\d*)
(\.
(?P<patch>0|[1-9]\d*)
)?
)?
""",
re.VERBOSE,
)
def coerce(version):
"""
Convert an incomplete version string into a semver-compatible VersionInfo
object

* Tries to detect a "basic" version string (``major.minor.patch``).
* If not enough components can be found, missing components are
set to zero to obtain a valid semver version.

:param str version: the version string to convert
:return: a tuple with a :class:`VersionInfo` instance (or ``None``
if it's not a version) and the rest of the string which doesn't
belong to a basic version.
:rtype: tuple(:class:`VersionInfo` | None, str)
"""
match = BASEVERSION.search(version)
if not match:
return (None, version)

ver = {
key: 0 if value is None else value
for key, value in match.groupdict().items()
}
ver = semver.VersionInfo(**ver)
rest = match.string[match.end() :]
return ver, rest

The function returns a *tuple*, containing a :class:`VersionInfo`
instance or None as the first element and the rest as the second element.
Expand Down
5 changes: 3 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
[tool:pytest]
norecursedirs = .git build .env/ env/ .pyenv/ .tmp/ .eggs/
testpaths = . docs
addopts =
--ignore=.eggs/
--no-cov-on-fail
--cov=semver
--cov-report=term-missing
--doctest-glob='*.rst'
--doctest-modules
--doctest-report ndiff

Expand All @@ -17,4 +18,4 @@ exclude =
.git,
__pycache__,
build,
dist
dist
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