Skip to content

Commit

Permalink
Fix python-semver#303: Fix Version.__init__ method
Browse files Browse the repository at this point in the history
* Allow different variants to call Version
* Adapt the documentation and README
* Adapt and amend tests
* Add changelog entries
* Add function "remove_noqa" in conf.py to remove any
  "# noqa" lines for flake8 issues like overly long lines
* Introduce a (private) _ensure_str class method
  • Loading branch information
tomschr committed Nov 12, 2020
1 parent 1562008 commit 6f64b71
Show file tree
Hide file tree
Showing 8 changed files with 303 additions and 87 deletions.
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ different parts, use the ``semver.Version.parse`` function:

.. code-block:: python
>>> ver = semver.Version.parse('1.2.3-pre.2+build.4')
>>> ver = semver.Version('1.2.3-pre.2+build.4')
>>> ver.major
1
>>> ver.minor
Expand All @@ -68,7 +68,7 @@ returns a new ``semver.Version`` instance with the raised major part:

.. code-block:: python
>>> ver = semver.Version.parse("3.4.5")
>>> ver = semver.Version("3.4.5")
>>> ver.bump_major()
Version(major=4, minor=0, patch=0, prerelease=None, build=None)
Expand Down
2 changes: 2 additions & 0 deletions changelog.d/303.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Prefer :meth:`Version.__init__` over :meth:`Version.parse`
and change examples accordingly.
3 changes: 3 additions & 0 deletions changelog.d/303.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Extend :meth:`Version.__init__` initializer. It allows
now to have positional and keyword arguments. The keyword
arguments overwrites any positional arguments.
16 changes: 16 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,19 @@ def find_version(*file_paths):
"Miscellaneous",
)
]

# ----------------
# Setup for Sphinx


def remove_noqa(app, what, name, obj, options, lines):
"""Remove any 'noqa' parts in a docstring"""
noqa_pattern = re.compile(r"\s+# noqa:.*$")
# Remove any "# noqa" parts in a line
for idx, line in enumerate(lines):
lines[idx] = noqa_pattern.sub("", line, count=1)


def setup(app):
"""Set up the Sphinx app."""
app.connect("autodoc-process-docstring", remove_noqa)
55 changes: 37 additions & 18 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,20 @@ The preferred way to create a new version is with the class

A :class:`~semver.version.Version` instance can be created in different ways:

* From a Unicode string::
* Without any arguments::

>>> from semver.version import Version
>>> Version.parse("3.4.5-pre.2+build.4")
>>> Version()
Version(major=0, minor=0, patch=0, prerelease=None, build=None)

* From a Unicode string::

>>> Version("3.4.5-pre.2+build.4")
Version(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
>>> Version.parse(u"5.3.1")
Version(major=5, minor=3, patch=1, prerelease=None, build=None)

* From a byte string::

>>> Version.parse(b"2.3.4")
>>> Version(b"2.3.4")
Version(major=2, minor=3, patch=4, prerelease=None, build=None)

* From individual parts by a dictionary::
Expand Down Expand Up @@ -100,6 +103,32 @@ A :class:`~semver.version.Version` instance can be created in different ways:
>>> Version("3", "5", 6)
Version(major=3, minor=5, patch=6, prerelease=None, build=None)

It is possible to combine, positional and keyword arguments. In
some use cases you have a fixed version string, but would like to
replace parts of them. For example::

>>> Version(1, 2, 3, major=2, build="b2")
Version(major=2, minor=2, patch=3, prerelease=None, build='b2')

It is also possible to use a version string and replace specific
parts::

>>> Version("1.2.3", major=2, build="b2")
Version(major=2, minor=2, patch=3, prerelease=None, build='b2')

However, it is not possible to use a string and additional positional
arguments:

>>> Version("1.2.3", 4)
Traceback (most recent call last):
...
ValueError: You cannot pass a string and additional positional arguments



Using Deprecated Functions to Create a Version
----------------------------------------------

The old, deprecated module level functions are still available but
using them are discoraged. They are available to convert old code
to semver3.
Expand Down Expand Up @@ -130,17 +159,7 @@ Depending on your use case, the following methods are available:
>>> semver.parse("1.2")
Traceback (most recent call last):
...
ValueError: 1.2 is not valid SemVer string


Parsing a Version String
------------------------

"Parsing" in this context means to identify the different parts in a string.
Use the function :func:`Version.parse <semver.version.Version.parse>`::

>>> Version.parse("3.4.5-pre.2+build.4")
Version(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
ValueError: '1.2' is not valid SemVer string


Checking for a Valid Semver Version
Expand All @@ -167,7 +186,7 @@ parts of a version:

.. code-block:: python
>>> v = Version.parse("3.4.5-pre.2+build.4")
>>> v = Version("3.4.5-pre.2+build.4")
>>> v.major
3
>>> v.minor
Expand Down Expand Up @@ -436,7 +455,7 @@ To compare two versions depends on your type:
>>> v > "1.0"
Traceback (most recent call last):
...
ValueError: 1.0 is not valid SemVer string
ValueError: '1.0' is not valid SemVer string

* **A** :class:`Version <semver.version.Version>` **type and a** :func:`dict`

Expand Down
1 change: 1 addition & 0 deletions src/semver/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
VersionDict = Dict[str, VersionPart]
VersionIterator = Iterable[VersionPart]
String = Union[str, bytes]
StringOrInt = Union[String, int]
F = TypeVar("F", bound=Callable)

0 comments on commit 6f64b71

Please sign in to comment.