Skip to content

Commit dcdcd2a

Browse files
committed
Fix #310: Correct API documentation
* Remove all automatic generation and use a more "semi-manual" approach (gives more control) * Improve docstrings in semver module * Remove docstrings in some dunder methods; Sphinx and autodoc uses the docstring from the parent class * Remove sphinx-apidoc command from :file:`tox.ini`
1 parent 02418ce commit dcdcd2a

File tree

11 files changed

+119
-53
lines changed

11 files changed

+119
-53
lines changed

changelog.d/310.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Rework API documentation.
2+
Follow a more "semi-manual" attempt and add auto directives
3+
into :file:`docs/api.rst`.

docs/_api/semver.__about__.rst

Lines changed: 0 additions & 5 deletions
This file was deleted.

docs/_static/css/custom.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ div.related.top nav {
3535
font-weight: 700;
3636
}
3737

38+
.py.class {
39+
margin-top: 1.5em;
40+
}
41+
3842
.py.method {
3943
padding-top: 0.25em;
4044
padding-bottom: 1.25em;

docs/api.rst

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,63 @@
11
.. _api:
22

3-
###
4-
API
5-
###
3+
API Reference
4+
=============
65

7-
.. toctree::
8-
:maxdepth: 4
6+
.. currentmodule:: semver
97

10-
_api/semver
8+
9+
Metadata :mod:`semver.__about__`
10+
--------------------------------
11+
12+
.. automodule:: semver.__about__
13+
14+
15+
Deprecated Functions in :mod:`semver._deprecated`
16+
-------------------------------------------------
17+
18+
.. automodule:: semver._deprecated
19+
20+
.. autofunction:: semver._deprecated.deprecated
21+
22+
23+
CLI Parsing :mod:`semver.cli`
24+
-----------------------------
25+
26+
.. automodule:: semver.cli
27+
28+
.. autofunction:: semver.cli.cmd_bump
29+
30+
.. autofunction:: semver.cli.cmd_check
31+
32+
.. autofunction:: semver.cli.cmd_compare
33+
34+
.. autofunction:: semver.cli.createparser
35+
36+
.. autofunction:: semver.cli.main
37+
38+
.. autofunction:: semver.cli.process
39+
40+
41+
Entry point :mod:`semver.__main__`
42+
----------------------------------
43+
44+
.. automodule:: semver.__main__
45+
46+
47+
48+
Version Handling :mod:`semver.version`
49+
--------------------------------------
50+
51+
.. automodule:: semver.version
52+
53+
.. autofunction:: semver.version.cmp
54+
55+
.. autofunction:: semver.version.ensure_str
56+
57+
.. autofunction:: semver.version.comparator
58+
59+
.. autoclass:: semver.version.VersionInfo
60+
61+
.. autoclass:: semver.version.Version
62+
:members:
63+
:special-members: __iter__, __eq__, __ne__, __lt__, __le__, __gt__, __ge__, __getitem__, __hash__, __repr__, __str__

docs/conf.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
import re
2222
import sys
2323

24-
sys.path.insert(0, os.path.abspath("../src/"))
24+
SRC_DIR = os.path.abspath("../src/")
25+
sys.path.insert(0, SRC_DIR)
2526
# from semver import __version__ # noqa: E402
2627

2728

@@ -58,15 +59,16 @@ def find_version(*file_paths):
5859
# ones.
5960
extensions = [
6061
"sphinx.ext.autodoc",
61-
"sphinx.ext.autosummary",
6262
"sphinx_autodoc_typehints",
6363
"sphinx.ext.intersphinx",
6464
"sphinx.ext.extlinks",
6565
]
6666

67+
# Autodoc configuration
6768
autoclass_content = "class"
68-
autodoc_default_options = {}
69-
69+
autodoc_typehints = "signature"
70+
autodoc_member_order = "alphabetical"
71+
add_function_parentheses = True
7072

7173
# Add any paths that contain templates here, relative to this directory.
7274
templates_path = ["_templates"]

src/semver/__about__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44
Contains information about semver's version, the implemented version
55
of the semver specifictation, author, maintainers, and description.
66
7+
.. autodata:: __author__
8+
9+
.. autodata:: __description__
10+
11+
.. autodata:: __maintainer__
12+
713
.. autodata:: __version__
14+
15+
.. autodata:: SEMVER_SPEC_VERSION
816
"""
917

1018
#: Semver version

src/semver/_types.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Typing for semver."""
2+
13
from typing import Union, Optional, Tuple, Dict, Iterable, Callable, TypeVar
24

35
VersionPart = Union[int, Optional[str]]

src/semver/cli.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
"""CLI parsing for :command:`pysemver` command."""
1+
"""
2+
CLI parsing for :command:`pysemver` command.
3+
4+
Each command in :command:`pysemver` is mapped to a ``cmd_`` function.
5+
The :func:`main <semver.cli.main>` function calls
6+
:func:`createparser <semver.cli.createparser>` and
7+
:func:`process <semver.cli.process>` to parse and process
8+
all the commandline options.
9+
10+
The result of each command is printed on stdout.
11+
"""
212

313
import argparse
414
import sys

src/semver/version.py

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,14 @@ def ensure_str(s: String, encoding="utf-8", errors="strict") -> str:
4343
* `bytes` -> decoded to `str`
4444
4545
:param s: the string to convert
46-
:type s: str | bytes
4746
:param encoding: the encoding to apply, defaults to "utf-8"
48-
:type encoding: str
4947
:param errors: set a different error handling scheme,
5048
defaults to "strict".
5149
Other possible values are `ignore`, `replace`, and
5250
`xmlcharrefreplace` as well as any other name
5351
registered with :func:`codecs.register_error`.
54-
:type errors: str
5552
:raises TypeError: if ``s`` is not str or bytes type
5653
:return: the converted string
57-
:rtype: str
5854
"""
5955
if isinstance(s, bytes):
6056
s = s.decode(encoding, errors)
@@ -218,7 +214,7 @@ def build(self, value):
218214

219215
def to_tuple(self) -> VersionTuple:
220216
"""
221-
Convert the VersionInfo object to a tuple.
217+
Convert the Version object to a tuple.
222218
223219
.. versionadded:: 2.10.0
224220
Renamed ``VersionInfo._astuple`` to ``VersionInfo.to_tuple`` to
@@ -233,7 +229,7 @@ def to_tuple(self) -> VersionTuple:
233229

234230
def to_dict(self) -> VersionDict:
235231
"""
236-
Convert the VersionInfo object to an OrderedDict.
232+
Convert the Version object to an OrderedDict.
237233
238234
.. versionadded:: 2.10.0
239235
Renamed ``VersionInfo._asdict`` to ``VersionInfo.to_dict`` to
@@ -257,7 +253,7 @@ def to_dict(self) -> VersionDict:
257253
)
258254

259255
def __iter__(self) -> VersionIterator:
260-
"""Implement iter(self)."""
256+
"""Return iter(self)."""
261257
yield from self.to_tuple()
262258

263259
@staticmethod
@@ -300,7 +296,6 @@ def bump_minor(self) -> "Version":
300296
301297
:return: new object with the raised minor part
302298
303-
304299
>>> ver = semver.parse("3.4.5")
305300
>>> ver.bump_minor()
306301
Version(major=3, minor=5, patch=0, prerelease=None, build=None)
@@ -313,8 +308,7 @@ def bump_patch(self) -> "Version":
313308
Raise the patch part of the version, return a new object but leave self
314309
untouched.
315310
316-
:return: new object with the raised patch part
317-
311+
:return: new object with the raised patch part
318312
319313
>>> ver = semver.parse("3.4.5")
320314
>>> ver.bump_patch()
@@ -328,7 +322,7 @@ def bump_prerelease(self, token: str = "rc") -> "Version":
328322
Raise the prerelease part of the version, return a new object but leave
329323
self untouched.
330324
331-
:param token: defaults to 'rc'
325+
:param token: defaults to ``rc``
332326
:return: new object with the raised prerelease part
333327
334328
>>> ver = semver.parse("3.4.5")
@@ -345,7 +339,7 @@ def bump_build(self, token: str = "build") -> "Version":
345339
Raise the build part of the version, return a new object but leave self
346340
untouched.
347341
348-
:param token: defaults to 'build'
342+
:param token: defaults to ``build``
349343
:return: new object with the raised build part
350344
351345
>>> ver = semver.parse("3.4.5-rc.1+build.9")
@@ -365,7 +359,6 @@ def compare(self, other: Comparable) -> int:
365359
:return: The return value is negative if ver1 < ver2,
366360
zero if ver1 == ver2 and strictly positive if ver1 > ver2
367361
368-
369362
>>> semver.compare("2.0.0")
370363
-1
371364
>>> semver.compare("1.0.0")
@@ -481,14 +474,17 @@ def __getitem__(
481474
self, index: Union[int, slice]
482475
) -> Union[int, Optional[str], Tuple[Union[int, str], ...]]:
483476
"""
484-
self.__getitem__(index) <==> self[index] Implement getitem. If the part
485-
requested is undefined, or a part of the range requested is undefined,
486-
it will throw an index error. Negative indices are not supported.
477+
self.__getitem__(index) <==> self[index] Implement getitem.
478+
479+
If the part requested is undefined, or a part of the range requested
480+
is undefined, it will throw an index error.
481+
Negative indices are not supported.
487482
488483
:param Union[int, slice] index: a positive integer indicating the
489484
offset or a :func:`slice` object
490485
:raises IndexError: if index is beyond the range or a part is None
491486
:return: the requested part of the version at position index
487+
492488
>>> ver = semver.Version.parse("3.4.5")
493489
>>> ver[0], ver[1], ver[2]
494490
(3, 4, 5)
@@ -519,7 +515,6 @@ def __repr__(self) -> str:
519515
return "%s(%s)" % (type(self).__name__, s)
520516

521517
def __str__(self) -> str:
522-
"""str(self)"""
523518
version = "%d.%d.%d" % (self.major, self.minor, self.patch)
524519
if self.prerelease:
525520
version += "-%s" % self.prerelease
@@ -533,7 +528,9 @@ def __hash__(self) -> int:
533528
def finalize_version(self) -> "Version":
534529
"""
535530
Remove any prerelease and build metadata from the version.
531+
536532
:return: a new instance with the finalized version string
533+
537534
>>> str(semver.Version.parse('1.2.3-rc.5').finalize_version())
538535
'1.2.3'
539536
"""
@@ -545,12 +542,12 @@ def match(self, match_expr: str) -> bool:
545542
Compare self to match a match expression.
546543
547544
:param match_expr: operator and version; valid operators are
548-
< smaller than
549-
> greater than
550-
>= greator or equal than
551-
<= smaller or equal than
552-
== equal
553-
!= not equal
545+
``<``` smaller than
546+
``>`` greater than
547+
``>=`` greator or equal than
548+
``<=`` smaller or equal than
549+
``==`` equal
550+
``!=`` not equal
554551
:return: True if the expression matches the version, otherwise False
555552
556553
>>> semver.Version.parse("2.0.0").match(">=1.0.0")
@@ -589,18 +586,18 @@ def match(self, match_expr: str) -> bool:
589586
@classmethod
590587
def parse(cls, version: String) -> "Version":
591588
"""
592-
Parse version string to a VersionInfo instance.
589+
Parse version string to a Version instance.
593590
594591
.. versionchanged:: 2.11.0
595592
Changed method from static to classmethod to
596593
allow subclasses.
597594
598595
:param version: version string
599-
:return: a :class:`VersionInfo` instance
596+
:return: a new :class:`Version` instance
600597
:raises ValueError: if version is invalid
601598
602599
>>> semver.Version.parse('3.4.5-pre.2+build.4')
603-
VersionInfo(major=3, minor=4, patch=5, \
600+
Version(major=3, minor=4, patch=5, \
604601
prerelease='pre.2', build='build.4')
605602
"""
606603
version_str = ensure_str(version)
@@ -624,15 +621,15 @@ def replace(self, **parts: Union[int, Optional[str]]) -> "Version":
624621
``major``, ``minor``, ``patch``, ``prerelease``, or ``build``
625622
:return: the new :class:`Version` object with the changed
626623
parts
627-
:raises TypeError: if ``parts`` contains invalid keys
624+
:raises TypeError: if ``parts`` contain invalid keys
628625
"""
629626
version = self.to_dict()
630627
version.update(parts)
631628
try:
632629
return Version(**version) # type: ignore
633630
except TypeError:
634631
unknownkeys = set(parts) - set(self.to_dict())
635-
error = "replace() got %d unexpected keyword " "argument(s): %s" % (
632+
error = "replace() got %d unexpected keyword argument(s): %s" % (
636633
len(unknownkeys),
637634
", ".join(unknownkeys),
638635
)

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
@pytest.fixture(autouse=True)
1414
def add_semver(doctest_namespace):
15-
doctest_namespace["Version"] = semver.Version
15+
doctest_namespace["Version"] = semver.version.Version
1616
doctest_namespace["semver"] = semver
1717
doctest_namespace["coerce"] = coerce
1818
doctest_namespace["SemVerWithVPrefix"] = SemVerWithVPrefix

0 commit comments

Comments
 (0)