pytest-notebook-policy 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Michael Booth
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: pytest-notebook-policy
3
+ Version: 0.8.0
4
+ Summary: Pytest plugin for notebook policy and quality checks
5
+ Keywords: pytest,marimo,jupyter,notebooks,lint,quality,policy
6
+ Author: Michael Booth
7
+ Author-email: Michael Booth <michael@databooth.com.au>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Framework :: Pytest
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development :: Quality Assurance
19
+ Requires-Dist: jinja2
20
+ Requires-Dist: pytest>=8.0
21
+ Requires-Dist: jupytext>=1.16 ; extra == 'sync'
22
+ Requires-Python: >=3.10
23
+ Project-URL: Homepage, https://github.com/DataBooth/pytest-notebook-policy
24
+ Project-URL: Repository, https://github.com/DataBooth/pytest-notebook-policy
25
+ Project-URL: Issues, https://github.com/DataBooth/pytest-notebook-policy/issues
26
+ Provides-Extra: sync
27
+ Description-Content-Type: text/markdown
28
+
29
+ # pytest-notebook-policy
30
+ [![CI](https://github.com/DataBooth/pytest-notebook-policy/actions/workflows/ci.yml/badge.svg)](https://github.com/DataBooth/pytest-notebook-policy/actions/workflows/ci.yml)
31
+ `pytest-notebook-policy` is a `pytest` plugin that enforces notebook policy and quality rules.
32
+
33
+ It focuses on notebook-specific checks for marimo and Jupyter workflows, not generic Python linting.
34
+
35
+ ## Terminology and discoverability
36
+ If you are looking for notebook **best practices**, **assurance**, **validation**, or **testing** tooling, this project is intended to cover those needs through enforceable policy checks and automated quality gates.
37
+
38
+ ## What this package is
39
+ `pytest-notebook-policy` is a lightweight semantic checker for notebook workflows.
40
+
41
+ It focuses on enforcing notebook patterns that are easy to miss in review, such as:
42
+ - `on_change` callback usage where reactivity is clearer
43
+ - cross-cell mutation of shared objects
44
+ - non-idempotent cell behaviour
45
+ - mixed test/helper cells and fixture placement conventions
46
+
47
+ ## Why this package exists
48
+ marimo already gives you:
49
+ - native notebook testing with `pytest`
50
+ - built-in notebook linting via `marimo check` ([announcement](https://marimo.io/blog/marimo-check))
51
+
52
+ `pytest-notebook-policy` is designed to complement those tools with opinionated, team-level checks tailored to a stricter “production notebook” style.
53
+
54
+ In practice:
55
+ - use **Ruff** for general Python quality/security
56
+ - use **marimo check** for core notebook validity and formatting rules
57
+ - use **pytest-notebook-policy** for extra policy checks around reactive design and notebook maintainability
58
+
59
+ ## Machine-assisted coding guardrails
60
+ `pytest-notebook-policy` is especially useful as an automated quality gate when notebooks are generated or edited by coding agents (for example Claude, Warp, Codex, or similar tools).
61
+
62
+ Adding it to pre-commit and CI helps catch marimo-specific issues immediately, so agents can self-correct before code reaches review.
63
+
64
+ Example pre-commit hook:
65
+
66
+ ```yaml
67
+ repos:
68
+ - repo: local
69
+ hooks:
70
+ - id: pytest-notebook-quality
71
+ name: pytest-notebook-quality
72
+ entry: uv run pytest-notebook-quality experiments notebooks
73
+ language: system
74
+ pass_filenames: false
75
+ ```
76
+
77
+ This keeps the feedback loop short:
78
+ - agent proposes notebook edits
79
+ - pre-commit/CI runs Ruff + `pytest-notebook-policy` checks
80
+ - agent fixes violations and retries
81
+
82
+ ## Current rules
83
+ - `M001`: prefer reactive dependencies over `on_change` handlers.
84
+ - `M002`: keep test cells focused; avoid mixing tests with helper/setup code in the same cell.
85
+ - `M003`: avoid mutable module-level state in notebook files.
86
+ - `M004`: prefer fixtures in `conftest.py` or helper modules rather than notebook modules.
87
+ - `M005`: avoid cross-cell mutation of shared objects (including notebook inputs and module-level mutable state).
88
+ - `M006`: avoid non-idempotent calls in cells (for example `random.*`, `np.random.*`, `time.time`, `uuid.uuid4`).
89
+ - `J001`: avoid notebook magics and shell escapes in policy-checked notebooks.
90
+ - `J002`: avoid non-idempotent calls in Jupyter notebook code cells.
91
+ - `J010`: (opt-in) check that paired `.ipynb` and `.py` files stay in sync.
92
+ - `J011`: require a top-of-notebook parameter/configuration cell in the first few code cells.
93
+ - `J012`: keep notebooks and cells small enough to stay reviewable and maintainable.
94
+ - `J013`: avoid excessive inline function/class definitions in notebooks; extract reusable logic into modules.
95
+ Detailed rationale and remediation guidance: [`docs/RULES.md`](docs/RULES.md).
96
+
97
+ ## Usage
98
+ Install in a project:
99
+
100
+ ```shell
101
+ uv add --dev pytest-notebook-policy
102
+ ```
103
+
104
+ Install pre-commit hooks:
105
+
106
+ ```shell
107
+ uv run --with pre-commit pre-commit install
108
+ ```
109
+
110
+ Run hooks across all files:
111
+
112
+ ```shell
113
+ uv run --with pre-commit pre-commit run --all-files
114
+ ```
115
+
116
+ CI runs on push/PR using `.github/workflows/ci.yml` and executes Ruff plus the test suite.
117
+
118
+ Run checks explicitly:
119
+
120
+ ```shell
121
+ uv run pytest --notebook-check
122
+ ```
123
+
124
+ Enable by default in `pyproject.toml`:
125
+
126
+ ```toml
127
+ [tool.pytest.ini_options]
128
+ notebook_check = true
129
+ ```
130
+
131
+ Filter rules:
132
+
133
+ ```shell
134
+ uv run pytest --notebook-check --notebook-check-select M001 --notebook-check-ignore M004
135
+ ```
136
+
137
+ Choose Jupyter rule source:
138
+
139
+ ```shell
140
+ uv run pytest --notebook-check --notebook-check-jupyter-source paired-py
141
+ ```
142
+
143
+ Set default Jupyter rule source in `pyproject.toml`:
144
+
145
+ ```toml
146
+ [tool.pytest.ini_options]
147
+ notebook_check = true
148
+ notebook_check_jupyter_source = "paired-py"
149
+ ```
150
+
151
+ `paired-py` prefers the paired `.py` notebook (when available and readable) for J-rules and falls back to `.ipynb`.
152
+
153
+ Tune Jupyter size/complexity thresholds:
154
+
155
+ ```shell
156
+ uv run pytest --notebook-check \
157
+ --notebook-check-jupyter-max-code-cells 30 \
158
+ --notebook-check-jupyter-max-cell-lines 120 \
159
+ --notebook-check-jupyter-max-inline-definitions 5
160
+ ```
161
+
162
+ Set defaults in `pyproject.toml`:
163
+
164
+ ```toml
165
+ [tool.pytest.ini_options]
166
+ notebook_check_jupyter_max_code_cells = "30"
167
+ notebook_check_jupyter_max_cell_lines = "120"
168
+ notebook_check_jupyter_max_inline_definitions = "5"
169
+ ```
170
+
171
+ Run combined Ruff + notebook policy checks:
172
+
173
+ ```shell
174
+ uv run pytest-notebook-quality path/to/notebooks
175
+ ```
176
+
177
+ Skip Ruff and run only notebook policy checks:
178
+
179
+ ```shell
180
+ uv run pytest-notebook-quality --skip-ruff path/to/notebooks
181
+ ```
182
+
183
+ Customise deterministic rule toggles and thresholds on the quality command:
184
+
185
+ ```shell
186
+ uv run pytest-notebook-quality --skip-ruff \
187
+ --notebook-check-select M \
188
+ --notebook-check-select J \
189
+ --notebook-check-ignore J010 \
190
+ --notebook-check-jupyter-source paired-py \
191
+ --notebook-check-jupyter-max-code-cells 30 \
192
+ --notebook-check-jupyter-max-cell-lines 120 \
193
+ --notebook-check-jupyter-max-inline-definitions 5 \
194
+ path/to/notebooks
195
+ ```
196
+
197
+ Write an NBOM-style JSON manifest (notebook surface + dependency correlation):
198
+
199
+ ```shell
200
+ uv run pytest-notebook-quality --skip-ruff \
201
+ --report-nbom-json reports/notebook-policy-nbom.json \
202
+ --report-dependency-enrichment \
203
+ path/to/notebooks
204
+ ```
205
+ Include optional vulnerability IDs (queried from OSV) in dependency enrichment output:
206
+
207
+ ```shell
208
+ uv run pytest-notebook-quality --skip-ruff \
209
+ --report-nbom-json reports/notebook-policy-nbom.json \
210
+ --report-dependency-vulns \
211
+ path/to/notebooks
212
+ ```
213
+ `--report-dependency-vulns` implicitly enables dependency enrichment.
214
+
215
+ Generate a markdown report with findings-first layout, touchpoint summary, and appendices:
216
+
217
+ ```shell
218
+ uv run pytest-notebook-quality --skip-ruff --report-md reports/notebook-policy-report.md path/to/notebooks
219
+ ```
220
+
221
+ Enable optional dependency enrichment in the report:
222
+
223
+ ```shell
224
+ uv run pytest-notebook-quality --skip-ruff \
225
+ --report-md reports/notebook-policy-report.md \
226
+ --report-dependency-enrichment \
227
+ path/to/notebooks
228
+ ```
229
+
230
+ Project-specific quality defaults can be set in `pyproject.toml`:
231
+
232
+ ```toml
233
+ [tool.pytest_notebook_policy.quality]
234
+ select = ["M", "J"]
235
+ ignore = ["J010"]
236
+ jupyter_source = "paired-py"
237
+ jupyter_max_code_cells = 30
238
+ jupyter_max_cell_lines = 120
239
+ jupyter_max_inline_definitions = 5
240
+ report_md = "reports/notebook-policy-report.md"
241
+ report_dependency_enrichment = true
242
+ report_dependency_vulns = false
243
+ report_nbom_json = "reports/notebook-policy-nbom.json"
244
+ ```
245
+
246
+ Enable optional sync tooling:
247
+
248
+ ```shell
249
+ uv add --dev 'pytest-notebook-policy[sync]'
250
+ ```
251
+
252
+ ## Versioning and release workflow
253
+ - Versioning follows Semantic Versioning (`MAJOR.MINOR.PATCH`).
254
+ - Release history lives in `RELEASE_NOTES.md`.
255
+
256
+ Typical release flow:
257
+
258
+ ```shell
259
+ uv version --bump patch
260
+ uv build
261
+ uv run --with twine twine check dist/*
262
+ ```
263
+
264
+ When ready to release (not run yet here), upload with Twine:
265
+
266
+ ```shell
267
+ uv run --with twine twine upload dist/*
268
+ ```
269
+ ## Notebook fixtures for testing
270
+ The repository includes notebook fixtures in `tests/fixtures`:
271
+
272
+ - `tests/fixtures/synthetic`: synthetic notebooks for targeted pass/fail checks.
273
+ - `tests/fixtures/real`: real-world notebooks sourced from public repositories (with provenance in `tests/fixtures/real/SOURCES.txt`).
274
+
275
+ Refresh pinned real fixtures and print their observed rule-code sets:
276
+
277
+ ```shell
278
+ uv run python scripts/refresh_real_fixtures.py
279
+ ```
@@ -0,0 +1,251 @@
1
+ # pytest-notebook-policy
2
+ [![CI](https://github.com/DataBooth/pytest-notebook-policy/actions/workflows/ci.yml/badge.svg)](https://github.com/DataBooth/pytest-notebook-policy/actions/workflows/ci.yml)
3
+ `pytest-notebook-policy` is a `pytest` plugin that enforces notebook policy and quality rules.
4
+
5
+ It focuses on notebook-specific checks for marimo and Jupyter workflows, not generic Python linting.
6
+
7
+ ## Terminology and discoverability
8
+ If you are looking for notebook **best practices**, **assurance**, **validation**, or **testing** tooling, this project is intended to cover those needs through enforceable policy checks and automated quality gates.
9
+
10
+ ## What this package is
11
+ `pytest-notebook-policy` is a lightweight semantic checker for notebook workflows.
12
+
13
+ It focuses on enforcing notebook patterns that are easy to miss in review, such as:
14
+ - `on_change` callback usage where reactivity is clearer
15
+ - cross-cell mutation of shared objects
16
+ - non-idempotent cell behaviour
17
+ - mixed test/helper cells and fixture placement conventions
18
+
19
+ ## Why this package exists
20
+ marimo already gives you:
21
+ - native notebook testing with `pytest`
22
+ - built-in notebook linting via `marimo check` ([announcement](https://marimo.io/blog/marimo-check))
23
+
24
+ `pytest-notebook-policy` is designed to complement those tools with opinionated, team-level checks tailored to a stricter “production notebook” style.
25
+
26
+ In practice:
27
+ - use **Ruff** for general Python quality/security
28
+ - use **marimo check** for core notebook validity and formatting rules
29
+ - use **pytest-notebook-policy** for extra policy checks around reactive design and notebook maintainability
30
+
31
+ ## Machine-assisted coding guardrails
32
+ `pytest-notebook-policy` is especially useful as an automated quality gate when notebooks are generated or edited by coding agents (for example Claude, Warp, Codex, or similar tools).
33
+
34
+ Adding it to pre-commit and CI helps catch marimo-specific issues immediately, so agents can self-correct before code reaches review.
35
+
36
+ Example pre-commit hook:
37
+
38
+ ```yaml
39
+ repos:
40
+ - repo: local
41
+ hooks:
42
+ - id: pytest-notebook-quality
43
+ name: pytest-notebook-quality
44
+ entry: uv run pytest-notebook-quality experiments notebooks
45
+ language: system
46
+ pass_filenames: false
47
+ ```
48
+
49
+ This keeps the feedback loop short:
50
+ - agent proposes notebook edits
51
+ - pre-commit/CI runs Ruff + `pytest-notebook-policy` checks
52
+ - agent fixes violations and retries
53
+
54
+ ## Current rules
55
+ - `M001`: prefer reactive dependencies over `on_change` handlers.
56
+ - `M002`: keep test cells focused; avoid mixing tests with helper/setup code in the same cell.
57
+ - `M003`: avoid mutable module-level state in notebook files.
58
+ - `M004`: prefer fixtures in `conftest.py` or helper modules rather than notebook modules.
59
+ - `M005`: avoid cross-cell mutation of shared objects (including notebook inputs and module-level mutable state).
60
+ - `M006`: avoid non-idempotent calls in cells (for example `random.*`, `np.random.*`, `time.time`, `uuid.uuid4`).
61
+ - `J001`: avoid notebook magics and shell escapes in policy-checked notebooks.
62
+ - `J002`: avoid non-idempotent calls in Jupyter notebook code cells.
63
+ - `J010`: (opt-in) check that paired `.ipynb` and `.py` files stay in sync.
64
+ - `J011`: require a top-of-notebook parameter/configuration cell in the first few code cells.
65
+ - `J012`: keep notebooks and cells small enough to stay reviewable and maintainable.
66
+ - `J013`: avoid excessive inline function/class definitions in notebooks; extract reusable logic into modules.
67
+ Detailed rationale and remediation guidance: [`docs/RULES.md`](docs/RULES.md).
68
+
69
+ ## Usage
70
+ Install in a project:
71
+
72
+ ```shell
73
+ uv add --dev pytest-notebook-policy
74
+ ```
75
+
76
+ Install pre-commit hooks:
77
+
78
+ ```shell
79
+ uv run --with pre-commit pre-commit install
80
+ ```
81
+
82
+ Run hooks across all files:
83
+
84
+ ```shell
85
+ uv run --with pre-commit pre-commit run --all-files
86
+ ```
87
+
88
+ CI runs on push/PR using `.github/workflows/ci.yml` and executes Ruff plus the test suite.
89
+
90
+ Run checks explicitly:
91
+
92
+ ```shell
93
+ uv run pytest --notebook-check
94
+ ```
95
+
96
+ Enable by default in `pyproject.toml`:
97
+
98
+ ```toml
99
+ [tool.pytest.ini_options]
100
+ notebook_check = true
101
+ ```
102
+
103
+ Filter rules:
104
+
105
+ ```shell
106
+ uv run pytest --notebook-check --notebook-check-select M001 --notebook-check-ignore M004
107
+ ```
108
+
109
+ Choose Jupyter rule source:
110
+
111
+ ```shell
112
+ uv run pytest --notebook-check --notebook-check-jupyter-source paired-py
113
+ ```
114
+
115
+ Set default Jupyter rule source in `pyproject.toml`:
116
+
117
+ ```toml
118
+ [tool.pytest.ini_options]
119
+ notebook_check = true
120
+ notebook_check_jupyter_source = "paired-py"
121
+ ```
122
+
123
+ `paired-py` prefers the paired `.py` notebook (when available and readable) for J-rules and falls back to `.ipynb`.
124
+
125
+ Tune Jupyter size/complexity thresholds:
126
+
127
+ ```shell
128
+ uv run pytest --notebook-check \
129
+ --notebook-check-jupyter-max-code-cells 30 \
130
+ --notebook-check-jupyter-max-cell-lines 120 \
131
+ --notebook-check-jupyter-max-inline-definitions 5
132
+ ```
133
+
134
+ Set defaults in `pyproject.toml`:
135
+
136
+ ```toml
137
+ [tool.pytest.ini_options]
138
+ notebook_check_jupyter_max_code_cells = "30"
139
+ notebook_check_jupyter_max_cell_lines = "120"
140
+ notebook_check_jupyter_max_inline_definitions = "5"
141
+ ```
142
+
143
+ Run combined Ruff + notebook policy checks:
144
+
145
+ ```shell
146
+ uv run pytest-notebook-quality path/to/notebooks
147
+ ```
148
+
149
+ Skip Ruff and run only notebook policy checks:
150
+
151
+ ```shell
152
+ uv run pytest-notebook-quality --skip-ruff path/to/notebooks
153
+ ```
154
+
155
+ Customise deterministic rule toggles and thresholds on the quality command:
156
+
157
+ ```shell
158
+ uv run pytest-notebook-quality --skip-ruff \
159
+ --notebook-check-select M \
160
+ --notebook-check-select J \
161
+ --notebook-check-ignore J010 \
162
+ --notebook-check-jupyter-source paired-py \
163
+ --notebook-check-jupyter-max-code-cells 30 \
164
+ --notebook-check-jupyter-max-cell-lines 120 \
165
+ --notebook-check-jupyter-max-inline-definitions 5 \
166
+ path/to/notebooks
167
+ ```
168
+
169
+ Write an NBOM-style JSON manifest (notebook surface + dependency correlation):
170
+
171
+ ```shell
172
+ uv run pytest-notebook-quality --skip-ruff \
173
+ --report-nbom-json reports/notebook-policy-nbom.json \
174
+ --report-dependency-enrichment \
175
+ path/to/notebooks
176
+ ```
177
+ Include optional vulnerability IDs (queried from OSV) in dependency enrichment output:
178
+
179
+ ```shell
180
+ uv run pytest-notebook-quality --skip-ruff \
181
+ --report-nbom-json reports/notebook-policy-nbom.json \
182
+ --report-dependency-vulns \
183
+ path/to/notebooks
184
+ ```
185
+ `--report-dependency-vulns` implicitly enables dependency enrichment.
186
+
187
+ Generate a markdown report with findings-first layout, touchpoint summary, and appendices:
188
+
189
+ ```shell
190
+ uv run pytest-notebook-quality --skip-ruff --report-md reports/notebook-policy-report.md path/to/notebooks
191
+ ```
192
+
193
+ Enable optional dependency enrichment in the report:
194
+
195
+ ```shell
196
+ uv run pytest-notebook-quality --skip-ruff \
197
+ --report-md reports/notebook-policy-report.md \
198
+ --report-dependency-enrichment \
199
+ path/to/notebooks
200
+ ```
201
+
202
+ Project-specific quality defaults can be set in `pyproject.toml`:
203
+
204
+ ```toml
205
+ [tool.pytest_notebook_policy.quality]
206
+ select = ["M", "J"]
207
+ ignore = ["J010"]
208
+ jupyter_source = "paired-py"
209
+ jupyter_max_code_cells = 30
210
+ jupyter_max_cell_lines = 120
211
+ jupyter_max_inline_definitions = 5
212
+ report_md = "reports/notebook-policy-report.md"
213
+ report_dependency_enrichment = true
214
+ report_dependency_vulns = false
215
+ report_nbom_json = "reports/notebook-policy-nbom.json"
216
+ ```
217
+
218
+ Enable optional sync tooling:
219
+
220
+ ```shell
221
+ uv add --dev 'pytest-notebook-policy[sync]'
222
+ ```
223
+
224
+ ## Versioning and release workflow
225
+ - Versioning follows Semantic Versioning (`MAJOR.MINOR.PATCH`).
226
+ - Release history lives in `RELEASE_NOTES.md`.
227
+
228
+ Typical release flow:
229
+
230
+ ```shell
231
+ uv version --bump patch
232
+ uv build
233
+ uv run --with twine twine check dist/*
234
+ ```
235
+
236
+ When ready to release (not run yet here), upload with Twine:
237
+
238
+ ```shell
239
+ uv run --with twine twine upload dist/*
240
+ ```
241
+ ## Notebook fixtures for testing
242
+ The repository includes notebook fixtures in `tests/fixtures`:
243
+
244
+ - `tests/fixtures/synthetic`: synthetic notebooks for targeted pass/fail checks.
245
+ - `tests/fixtures/real`: real-world notebooks sourced from public repositories (with provenance in `tests/fixtures/real/SOURCES.txt`).
246
+
247
+ Refresh pinned real fixtures and print their observed rule-code sets:
248
+
249
+ ```shell
250
+ uv run python scripts/refresh_real_fixtures.py
251
+ ```
@@ -0,0 +1,76 @@
1
+ [project]
2
+ name = "pytest-notebook-policy"
3
+ version = "0.8.0"
4
+ description = "Pytest plugin for notebook policy and quality checks"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [
9
+ { name = "Michael Booth", email = "michael@databooth.com.au" }
10
+ ]
11
+ keywords = ["pytest", "marimo", "jupyter", "notebooks", "lint", "quality", "policy"]
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Framework :: Pytest",
15
+ "Intended Audience :: Developers",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Software Development :: Quality Assurance",
22
+ ]
23
+ requires-python = ">=3.10"
24
+ dependencies = [
25
+ "jinja2",
26
+ "pytest>=8.0",
27
+ ]
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/DataBooth/pytest-notebook-policy"
31
+ Repository = "https://github.com/DataBooth/pytest-notebook-policy"
32
+ Issues = "https://github.com/DataBooth/pytest-notebook-policy/issues"
33
+
34
+ [project.scripts]
35
+ pytest-notebook-quality = "pytest_notebook_policy.quality:main"
36
+
37
+ [project.entry-points.pytest11]
38
+ notebook_policy = "pytest_notebook_policy.plugin"
39
+
40
+ [project.optional-dependencies]
41
+ sync = [
42
+ "jupytext>=1.16",
43
+ ]
44
+
45
+ [build-system]
46
+ requires = ["uv_build>=0.11.7,<0.12.0"]
47
+ build-backend = "uv_build"
48
+
49
+ [dependency-groups]
50
+ dev = [
51
+ "jupytext>=1.16",
52
+ "pytest>=8.0",
53
+ "ruff>=0.14.0",
54
+ ]
55
+
56
+ [tool.ruff]
57
+ target-version = "py310"
58
+ line-length = 100
59
+ extend-exclude = ["tests/fixtures/real/*.ipynb"]
60
+
61
+ [tool.ruff.lint]
62
+ extend-select = ["S"]
63
+
64
+ [tool.ruff.lint.per-file-ignores]
65
+ "experiments/**/*.ipynb" = ["S311"]
66
+ "experiments/**/*.py" = ["B018", "S311"]
67
+ "src/pytest_notebook_policy/quality.py" = ["S603"]
68
+ "tests/**/*.py" = ["S101"]
69
+ "tests/fixtures/**/*.ipynb" = ["S311"]
70
+ "tests/fixtures/**/*.py" = ["B018", "S311"]
71
+
72
+ [tool.uv.workspace]
73
+ members = [
74
+ "tmp/manual_checks/experiments",
75
+ ".",
76
+ ]
@@ -0,0 +1,5 @@
1
+ """pytest-notebook-policy package."""
2
+
3
+ from .plugin import Violation, scan_file
4
+
5
+ __all__ = ["Violation", "scan_file"]