Skip to content

Commit 85d85bf

Browse files
authored
Add linting of code examples in docstrings (frequenz-floss#115)
Also prepare for the v0.5.0 release. - Update repo-config version - Add support for linting code examples in docstrings - Add support for the `part:pytest` label - mkdocs: Ignore the top-level `conftest` module - Lint docstrings examples - Skip examples linting for `__init__.py` files - cookiecutter: Add a `pytest` hook to lint docstring examples - Add summary to release notes Fixes frequenz-floss#27.
2 parents e86859d + c5241c6 commit 85d85bf

File tree

34 files changed

+503
-49
lines changed

34 files changed

+503
-49
lines changed

.github/ISSUE_TEMPLATE/bug.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ body:
6161
- Tools to configure nox (part:nox)
6262
- Tools to configure protobufs (part:protobuf)
6363
- Tools to configure the CI (part:ci)
64+
- Tools to configure pytest (part:pytest)
6465
validations:
6566
required: true
6667
- type: textarea

.github/keylabeler.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ labelMappings:
2727
"part:model-only": "part:model-only"
2828
"part:nox": "part:nox"
2929
"part:protobuf": "part:protobuf"
30+
"part:pytest": "part:pytest"

.github/labeler.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,9 @@
6969
- "src/frequenz/repo/config/protobuf*"
7070
all:
7171
- "!tests*/**"
72+
73+
"part:pytest":
74+
- any:
75+
- "src/frequenz/repo/config/pytest"
76+
all:
77+
- "!tests*/**"

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ exclude CODEOWNERS
66
exclude CONTRIBUTING.md
77
exclude mkdocs.yml
88
exclude noxfile.py
9+
exclude src/conftest.py
910
recursive-exclude .github *
1011
recursive-exclude cookiecutter *
1112
recursive-exclude docs *

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ directory will be created with the generated project name. For example:
4242
cd ~/devel
4343
cookiecutter gh:frequenz-floss/frequenz-repo-config-python \
4444
--directory=cookiecutter \
45-
--checkout v0.4.0
45+
--checkout v0.5.0
4646
```
4747

4848
This command will prompt you for the project type, name, and other

RELEASE_NOTES.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Summary
44

5-
<!-- Here goes a general summary of what this release is about -->
5+
This release adds linting of code examples in *docstrings*, a workflow to check if PRs have updated the release notes and an [editorconfig](https://editorconfig.org/) file, as well as a bunch of bug fixes.
66

77
## Upgrading
88

@@ -38,6 +38,12 @@
3838

3939
## New Features
4040

41+
- Add support for linting code examples found in *docstrings*.
42+
43+
A new module `frequenz.repo.config.pytest.examples` is added with an utility function to be able to easily collect and lint code examples in *docstrings*.
44+
45+
There is also a new optional dependency `extra-lint-examples` to easily pull the dependencies needed to do this linting. Please have a look at the documentation in the `frequenz.repo.config` package for more details.
46+
4147
### Cookiecutter template
4248

4349
- Add a new GitHub workflow to check that release notes were updated.
@@ -52,6 +58,14 @@
5258

5359
- Add an `.editorconfig` file to ensure a common basic editor configuration for different file types.
5460

61+
- Add a `pytest` hook to collect and lint code examples found in *docstrings* using `pylint`.
62+
63+
Examples found in code *docstrings* in the `src/` directory will now be collected and checked using `pylint`. This is done via the file `src/conftest.py`, which hooks into `pytest`, so to only check the examples you can run `pylint src`.
64+
65+
!!! info
66+
67+
There is a bug in the library used to extract the examples that prevents from collecting examples from `__init__.py` files. See https://github.com/frequenz-floss/frequenz-repo-config-python/issues/113 for more details.
68+
5569
## Bug Fixes
5670

5771
- The distribution package doesn't include tests and other useless files anymore.

cookiecutter/{{cookiecutter.github_repo_name}}/MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ exclude CODEOWNERS
99
exclude CONTRIBUTING.md
1010
exclude mkdocs.yml
1111
exclude noxfile.py
12+
exclude src/conftest.py
1213
recursive-exclude .github *
1314
recursive-exclude docs *
1415
{%- if cookiecutter.type == "api" %}

cookiecutter/{{cookiecutter.github_repo_name}}/pyproject.toml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
requires = [
66
"setuptools == 67.7.2",
77
"setuptools_scm[toml] == 7.1.0",
8-
"frequenz-repo-config[{{cookiecutter.type}}] == 0.4.0",
8+
"frequenz-repo-config[{{cookiecutter.type}}] == 0.5.0",
99
]
1010
build-backend = "setuptools.build_meta"
1111

@@ -70,7 +70,7 @@ dev-mkdocs = [
7070
"mkdocs-material == 9.1.16",
7171
"mkdocs-section-index == 0.3.5",
7272
"mkdocstrings[python] == 0.22.0",
73-
"frequenz-repo-config[{{cookiecutter.type}}] == 0.4.0",
73+
"frequenz-repo-config[{{cookiecutter.type}}] == 0.5.0",
7474
]
7575
dev-mypy = [
7676
"mypy == 1.2.0",
@@ -79,23 +79,22 @@ dev-mypy = [
7979
]
8080
dev-noxfile = [
8181
"nox == 2023.4.22",
82-
"frequenz-repo-config[{{cookiecutter.type}}] == 0.4.0",
82+
"frequenz-repo-config[{{cookiecutter.type}}] == 0.5.0",
8383
]
8484
dev-pylint = [
8585
"pylint == 2.17.3",
8686
# For checking the noxfile, docs/ script, and tests
8787
"{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-noxfile,dev-pytest]",
8888
]
89-
{%- if cookiecutter.type == "api" %}
90-
dev-pytest = ["pytest == 7.3.1"]
91-
{%- else %}
9289
dev-pytest = [
9390
"pytest == 7.3.1",
91+
"frequenz-repo-config[extra-lint-examples] == 0.5.0",
92+
{%- if cookiecutter.type != "api" %}
9493
"pytest-mock == 3.10.0",
9594
"pytest-asyncio == 0.21.0",
9695
"async-solipsism == 0.5",
97-
]
9896
{%- endif %}
97+
]
9998
dev = [
10099
"{{cookiecutter.pypi_package_name}}[dev-mkdocs,dev-docstrings,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]",
101100
]
@@ -138,7 +137,7 @@ disable = [
138137

139138
[tool.pytest.ini_options]
140139
{%- if cookiecutter.type != "api" %}
141-
testpaths = ["tests"]
140+
testpaths = ["tests", "src"]
142141
asyncio_mode = "auto"
143142
required_plugins = ["pytest-asyncio", "pytest-mock"]
144143
{%- else %}
@@ -147,7 +146,7 @@ testpaths = ["pytests"]
147146
{%- if cookiecutter.type != "api" %}
148147

149148
[[tool.mypy.overrides]]
150-
module = ["async_solipsism", "async_solipsism.*"]
149+
module = ["async_solipsism", "async_solipsism.*", "sybil", "sybil.*"]
151150
ignore_missing_imports = true
152151
{%- endif %}
153152
{%- if cookiecutter.type == "api" %}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# License: {{cookiecutter.license}}
2+
# Copyright © {% now 'utc', '%Y' %} {{cookiecutter.author_name}}
3+
4+
"""Validate docstring code examples.
5+
6+
Code examples are often wrapped in triple backticks (```) within docstrings.
7+
This plugin extracts these code examples and validates them using pylint.
8+
"""
9+
10+
from frequenz.repo.config.pytest import examples
11+
from sybil import Sybil
12+
13+
pytest_collect_file = Sybil(**examples.get_sybil_arguments()).pytest()

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Then simply run [Cookiecutter] where you want to create the new project:
3535

3636
```sh
3737
cookiecutter gh:frequenz-floss/frequenz-repo-config-python \
38-
--directory=cookiecutter --checkout v0.4.0
38+
--directory=cookiecutter --checkout v0.5.0
3939
```
4040

4141
This command will prompt you for the project type, name, and other

0 commit comments

Comments
 (0)