sphinx-exec-jupyter 0.1.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.
Files changed (28) hide show
  1. sphinx_exec_jupyter-0.1.0/.github/dependabot.yml +8 -0
  2. sphinx_exec_jupyter-0.1.0/.github/workflows/ci.yml +87 -0
  3. sphinx_exec_jupyter-0.1.0/.github/workflows/release.yml +24 -0
  4. sphinx_exec_jupyter-0.1.0/.gitignore +16 -0
  5. sphinx_exec_jupyter-0.1.0/.pre-commit-config.yaml +29 -0
  6. sphinx_exec_jupyter-0.1.0/.readthedocs.yml +15 -0
  7. sphinx_exec_jupyter-0.1.0/.taplo.toml +5 -0
  8. sphinx_exec_jupyter-0.1.0/.vscode/launch.json +30 -0
  9. sphinx_exec_jupyter-0.1.0/.vscode/settings.json +22 -0
  10. sphinx_exec_jupyter-0.1.0/PKG-INFO +20 -0
  11. sphinx_exec_jupyter-0.1.0/README.md +59 -0
  12. sphinx_exec_jupyter-0.1.0/biome.jsonc +18 -0
  13. sphinx_exec_jupyter-0.1.0/docs/conf.py +23 -0
  14. sphinx_exec_jupyter-0.1.0/docs/index.rst +122 -0
  15. sphinx_exec_jupyter-0.1.0/pyproject.toml +80 -0
  16. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/__init__.py +53 -0
  17. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_directive.py +24 -0
  18. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_kernel_mgr/__init__.py +264 -0
  19. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_kernel_mgr/fork-server.py +78 -0
  20. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/_kernel_mgr/myst.py +52 -0
  21. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/common.py +80 -0
  22. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/__init__.py +38 -0
  23. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/_directive.py +129 -0
  24. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/_mime_render.py +27 -0
  25. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/holoviews/collect-urls.py +19 -0
  26. sphinx_exec_jupyter-0.1.0/src/sphinx_exec_jupyter/py.typed +0 -0
  27. sphinx_exec_jupyter-0.1.0/tests/test_extension.py +23 -0
  28. sphinx_exec_jupyter-0.1.0/tests/test_kernel_mgr.py +91 -0
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ cooldown:
8
+ default-days: 7
@@ -0,0 +1,87 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ env:
9
+ FORCE_COLOR: "1"
10
+
11
+ permissions: {}
12
+
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ jobs:
18
+ get-environments:
19
+ runs-on: ubuntu-latest
20
+ outputs:
21
+ envs: ${{ steps.get-envs.outputs.envs }}
22
+ steps:
23
+ - &CLONE
24
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
25
+ with:
26
+ filter: blob:none
27
+ fetch-depth: 0
28
+ persist-credentials: false
29
+ - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 #v8.2.0
30
+ with:
31
+ enable-cache: false
32
+ - id: get-envs
33
+ run: |
34
+ ENVS_JSON=$(NO_COLOR=1 uvx hatch env show --json | jq -c 'to_entries
35
+ | map(
36
+ select(.key | startswith("hatch-test"))
37
+ | { name: .key, python: .value.python }
38
+ )')
39
+ echo "envs=${ENVS_JSON}" | tee $GITHUB_OUTPUT
40
+ test:
41
+ needs: get-environments
42
+ permissions:
43
+ id-token: write # for codecov OIDC
44
+ runs-on: ubuntu-latest
45
+ strategy:
46
+ matrix:
47
+ env: ${{ fromJSON(needs.get-environments.outputs.envs) }}
48
+ env: # environment variable for use in codecov’s env_vars tagging
49
+ ENV_NAME: ${{ matrix.env.name }}
50
+ steps:
51
+ - *CLONE
52
+ - name: Install UV
53
+ uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 #v8.2.0
54
+ - name: Install dependencies
55
+ run: uvx hatch -v env create ${{ matrix.env.name }}
56
+ - name: Run tests
57
+ run: |
58
+ uvx hatch run ${{ matrix.env.name }}:run-cov -v --color=yes -n auto --junitxml=test-results.xml
59
+ uvx hatch run ${{ matrix.env.name }}:cov-combine
60
+ uvx hatch run ${{ matrix.env.name }}:coverage xml
61
+ uvx hatch run ${{ matrix.env.name }}:cov-report
62
+ - name: Upload coverage data
63
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f #v7.0.0
64
+ with:
65
+ report_type: coverage
66
+ use_oidc: true
67
+ env_vars: ENV_NAME
68
+ fail_ci_if_error: true
69
+ - name: Upload test results
70
+ if: ${{ !cancelled() }}
71
+ uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f #v7.0.0
72
+ with:
73
+ report_type: test_results
74
+ use_oidc: true
75
+ env_vars: ENV_NAME
76
+ fail_ci_if_error: true
77
+ files: test-results.xml
78
+ check:
79
+ if: always()
80
+ needs:
81
+ - get-environments
82
+ - test
83
+ runs-on: ubuntu-latest
84
+ steps:
85
+ - uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe #v1.2.2
86
+ with:
87
+ jobs: ${{ toJSON(needs) }}
@@ -0,0 +1,24 @@
1
+ name: Publish Python Package
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions: {}
8
+
9
+ jobs:
10
+ publish:
11
+ runs-on: ubuntu-latest
12
+ environment: pypi
13
+ permissions:
14
+ id-token: write # to authenticate as Trusted Publisher to pypi.org
15
+ steps:
16
+ - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
17
+ with:
18
+ persist-credentials: false
19
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 #v6.3.0
20
+ with:
21
+ python-version: "3.x"
22
+ - run: pip install build
23
+ - run: python -m build
24
+ - uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b #v1.14.0
@@ -0,0 +1,16 @@
1
+ # Python
2
+ __pycache__/
3
+ /build/
4
+ /dist/
5
+ /.python-version
6
+
7
+ # Testing
8
+ /test-data/
9
+ /.*cache/
10
+ /.coverage*
11
+
12
+ # Docs
13
+ /docs/_build/
14
+
15
+ # IDEs
16
+ /.idea/
@@ -0,0 +1,29 @@
1
+ ci:
2
+ autoupdate_commit_msg: "ci: pre-commit autoupdate"
3
+ repos:
4
+ - repo: https://github.com/pre-commit/pre-commit-hooks
5
+ rev: v6.0.0
6
+ hooks:
7
+ - id: end-of-file-fixer
8
+ - id: trailing-whitespace
9
+ - id: no-commit-to-branch
10
+ - repo: https://github.com/astral-sh/ruff-pre-commit
11
+ rev: v0.15.18
12
+ hooks:
13
+ - id: ruff-check
14
+ args: [--fix, --exit-non-zero-on-fix]
15
+ - id: ruff-check
16
+ args: [--preview, --select=CPY]
17
+ - id: ruff-format
18
+ - repo: https://github.com/tox-dev/pyproject-fmt
19
+ rev: v2.25.0
20
+ hooks:
21
+ - id: pyproject-fmt
22
+ - repo: https://github.com/biomejs/pre-commit
23
+ rev: v2.5.0
24
+ hooks:
25
+ - id: biome-format
26
+ - repo: https://github.com/zizmorcore/zizmor-pre-commit
27
+ rev: v1.26.1
28
+ hooks:
29
+ - id: zizmor
@@ -0,0 +1,15 @@
1
+ # https://docs.readthedocs.io/en/stable/config-file/v2.html
2
+ version: 2
3
+ build:
4
+ os: ubuntu-24.04
5
+ tools:
6
+ python: "3.13"
7
+ jobs:
8
+ create_environment:
9
+ - asdf plugin add uv
10
+ - asdf install uv latest
11
+ - asdf global uv latest
12
+ build:
13
+ html:
14
+ - uvx hatch run docs-build
15
+ - mv docs/_build $READTHEDOCS_OUTPUT
@@ -0,0 +1,5 @@
1
+ [formatting]
2
+ array_auto_collapse = false
3
+ column_width = 120
4
+ compact_arrays = false
5
+ indent_string = ' '
@@ -0,0 +1,30 @@
1
+ {
2
+ // https://go.microsoft.com/fwlink/?linkid=830387
3
+ "version": "0.2.0",
4
+ "configurations": [
5
+ {
6
+ "name": "Build Documentation",
7
+ "type": "debugpy",
8
+ "request": "launch",
9
+ "python": "${command:hatch.envInterpreter}", //always default env
10
+ "module": "sphinx",
11
+ "args": ["-M", "html", ".", "_build"],
12
+ "cwd": "${workspaceFolder}/docs",
13
+ "console": "internalConsole",
14
+ "justMyCode": false,
15
+ },
16
+ {
17
+ "name": "Debug test",
18
+ "type": "debugpy",
19
+ "request": "launch",
20
+ "program": "${file}",
21
+ "pythonArgs": ["-Xfrozen_modules=off"],
22
+ "console": "internalConsole",
23
+ "justMyCode": false,
24
+ "purpose": ["debug-test"],
25
+ "presentation": {
26
+ "hidden": true,
27
+ },
28
+ },
29
+ ],
30
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "[toml][json][jsonc][python]": {
3
+ "editor.formatOnSave": true,
4
+ },
5
+ "[toml]": {
6
+ "editor.defaultFormatter": "tamasfe.even-better-toml",
7
+ },
8
+ "[json][jsonc]": {
9
+ "editor.defaultFormatter": "biomejs.biome",
10
+ },
11
+ "[python]": {
12
+ "editor.defaultFormatter": "charliermarsh.ruff",
13
+ "editor.codeActionsOnSave": {
14
+ "source.fixAll": "explicit",
15
+ "source.organizeImports": "explicit",
16
+ },
17
+ },
18
+ "python.testing.pytestEnabled": true,
19
+ "python.testing.pytestArgs": ["-vv", "--color=yes"],
20
+ "python-envs.defaultEnvManager": "pypa.hatch:hatch",
21
+ "python-envs.defaultPackageManager": "pypa.hatch:hatch",
22
+ }
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: sphinx-exec-jupyter
3
+ Version: 0.1.0
4
+ Summary: Execute code and let Jupyter format the output
5
+ Project-URL: Documentation, https://sphinx-exec-jupyter.readthedocs.io/
6
+ Project-URL: Source, https://github.com/flying-sheep/sphinx-exec-jupyter
7
+ Author-email: "Philipp A." <flying-sheep@web.de>
8
+ License-Expression: MPL-2.0
9
+ Classifier: Framework :: Sphinx :: Extension
10
+ Classifier: Programming Language :: Python :: 3 :: Only
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Programming Language :: Python :: 3.14
14
+ Requires-Python: >=3.12
15
+ Requires-Dist: myst-nb>=1.4
16
+ Requires-Dist: nbformat>=5.10.4
17
+ Requires-Dist: sphinx>=9.1
18
+ Provides-Extra: holoviews
19
+ Requires-Dist: holoviews; extra == 'holoviews'
20
+ Requires-Dist: sphinx-design; extra == 'holoviews'
@@ -0,0 +1,59 @@
1
+ # sphinx-exec-jupyter
2
+
3
+ [![Documentation Status][doc badge]][docs]
4
+ [![Test Status][test badge]][tests]
5
+ [![Coverage Status][codecov badge]][codecov]
6
+
7
+ [doc badge]: https://readthedocs.org/projects/sphinx-exec-jupyter/badge/
8
+ [docs]: https://sphinx-exec-jupyter.readthedocs.io/
9
+ [test badge]: https://github.com/flying-sheep/sphinx-exec-jupyter/actions/workflows/ci.yml/badge.svg
10
+ [tests]: https://github.com/flying-sheep/sphinx-exec-jupyter/actions/workflows/ci.yml
11
+ [codecov badge]: https://codecov.io/gh/flying-sheep/sphinx-exec-jupyter/branch/main/graph/badge.svg
12
+ [codecov]: https://codecov.io/gh/flying-sheep/sphinx-exec-jupyter
13
+
14
+ This Sphinx extension allows you to execute Jupyter notebooks and include their output in your documentation.
15
+
16
+ ## Installation
17
+
18
+ Install or depend on
19
+ `sphinx-exec-jupyter @ git+https://github.com/flying-sheep/sphinx-exec-jupyter.git`,
20
+ optionally with the `holoviews` extra (see below).
21
+ Then enable this extension in your `conf.py`:
22
+
23
+ ```python
24
+ extensions = [
25
+ "sphinx_exec_jupyter",
26
+ ]
27
+ ```
28
+
29
+ ## Directives
30
+
31
+ ### `exec-jupyter`
32
+
33
+ Executes a Jupyter notebook cell and includes its output:
34
+
35
+ ```rst
36
+ .. exec-jupyter::
37
+
38
+ import numpy as np
39
+ np.random.rand(4)
40
+ ```
41
+
42
+ ### `holoviews`
43
+
44
+ Enable by installing the `holoviews` extra by depending on
45
+ `sphinx-exec-jupyter[holoviews] @ git+https://github.com/flying-sheep/sphinx-exec-jupyter.git`
46
+
47
+ Embeds a HoloViews plot:
48
+
49
+ ```rst
50
+ .. holoviews::
51
+ :backends: bokeh,matplotlib
52
+
53
+ hv.Curve([1, 2, 3, 2, 1])
54
+ ```
55
+
56
+ The default for `backends` is defined by a Sphinx `conf.py` setting:
57
+ `holoviews_backends = ['bokeh']`
58
+
59
+ For detailed documentation, visit [Read the Docs](https://sphinx-exec-jupyter.readthedocs.io/).
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.1.1/schema.json",
3
+ "formatter": { "useEditorconfig": true },
4
+ "overrides": [
5
+ {
6
+ "includes": ["./.vscode/*.json", "**/*.jsonc"],
7
+ "json": {
8
+ "formatter": {
9
+ "trailingCommas": "all",
10
+ },
11
+ "parser": {
12
+ "allowComments": true,
13
+ "allowTrailingCommas": true,
14
+ },
15
+ },
16
+ },
17
+ ],
18
+ }
@@ -0,0 +1,23 @@
1
+ # SPDX-License-Identifier: MPL-2.0
2
+ """Configuration for Sphinx documentation."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from importlib.metadata import metadata
7
+
8
+ _meta = metadata("sphinx-exec-jupyter")
9
+ project = _meta["name"]
10
+ author = _meta["author-email"].split('"')[1]
11
+ release = _meta["version"]
12
+
13
+ extensions = [
14
+ "sphinx_exec_jupyter",
15
+ "sphinx_design",
16
+ ]
17
+
18
+ templates_path = ["_templates"]
19
+ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
20
+
21
+ master_doc = "index"
22
+
23
+ html_theme = "furo"
@@ -0,0 +1,122 @@
1
+ ``sphinx_exec_jupyter``
2
+ =======================
3
+
4
+ The ``sphinx-exec-jupyter`` Sphinx extension allows you to execute code
5
+ in a Jupyter kernel and embed the output directly into your Sphinx documentation.
6
+
7
+ This extension adds at least one directive (see `sphinx_exec_jupyter.holoviews`_ for more):
8
+
9
+ .. rst:directive:: exec-jupyter
10
+
11
+ Execute a Jupyter notebook cell and embed the output into the documentation.
12
+ The Python expression on the last line of the directive body is displayed.
13
+
14
+ It can be configured with the following settings:
15
+
16
+ .. confval:: exec_jupyter_code
17
+ :type: ``str``
18
+
19
+ Prefix code to execute before the code in ``exec-jupyter`` or ``holoviews``.
20
+ Kernels are started from forked processes after this code is executed,
21
+ so it can be used for long-running initialization code (e.g. slow imports).
22
+
23
+ .. confval:: exec_jupyter_kernel
24
+ :type: ``str``
25
+
26
+ Name of the Jupyter kernel to use.
27
+ If not set, the default kernel is used.
28
+
29
+ .. confval:: exec_jupyter_patch_myst_nb
30
+ :type: ``bool``
31
+
32
+ If ``True`` (the default), and either ``exec_jupyter_code`` or ``exec_jupyter_kernel`` are set,
33
+ the ``myst_nb`` extension is patched to use the provided code and/or kernel.
34
+
35
+ Examples
36
+ --------
37
+
38
+ .. code-block:: rst
39
+
40
+ .. exec-jupyter::
41
+
42
+ import pandas as pd
43
+
44
+ pd.DataFrame(dict(
45
+ A=[1, 2, 3],
46
+ B=[4, 5, 6],
47
+ ))
48
+
49
+ results in:
50
+
51
+ .. exec-jupyter::
52
+
53
+ import pandas as pd
54
+
55
+ pd.DataFrame(dict(
56
+ A=[1, 2, 3],
57
+ B=[4, 5, 6],
58
+ ))
59
+
60
+ ``sphinx_exec_jupyter.holoviews``
61
+ ---------------------------------
62
+
63
+ If you installed ``sphinx-exec-jupyter`` with the ``holoviews`` extra
64
+ (e.g. ``pip install sphinx-exec-jupyter[holoviews]``),
65
+ the ``sphinx_exec_jupyter.holoviews`` sub-extension is loaded automatically.
66
+
67
+ This extension adds a setting and one more directive:
68
+
69
+ .. confval:: holoviews_backends
70
+ :type: ``list[str]``
71
+ :default: ``['bokeh']``
72
+
73
+ A list of backends to use for rendering HoloViews plots.
74
+
75
+ .. rst:directive:: holoviews
76
+
77
+ Embed a HoloViews plot into the documentation.
78
+ The Python expression on the last line of the directive body is displayed.
79
+
80
+ .. rst:directive:option:: backends: backend1,backend2,...
81
+ :type: comma separated list of backends
82
+
83
+ The list of backends to use for rendering the plot. Defaults to :confval:`holoviews_backends`.
84
+
85
+ ..
86
+ See here for syntax:
87
+ https://www.sphinx-doc.org/en/master/usage/domains/restructuredtext.html#directive-rst-directive
88
+
89
+ .. _holoviews-examples:
90
+
91
+ Examples
92
+ --------
93
+
94
+ No options (defaults to bokeh):
95
+
96
+ .. code-block:: rst
97
+
98
+ .. holoviews::
99
+
100
+ hv.Curve([1, 2, 3, 2, 1])
101
+
102
+ results in:
103
+
104
+ .. holoviews::
105
+
106
+ hv.Curve([1, 2, 3, 2, 1])
107
+
108
+ With multiple backends specified (needs the ``sphinx_design`` extension to be loaded):
109
+
110
+ .. code-block:: rst
111
+
112
+ .. holoviews::
113
+ :backends: bokeh,matplotlib,plotly
114
+
115
+ hv.Curve([1, 2, 3, 2, 1])
116
+
117
+ results in:
118
+
119
+ .. holoviews::
120
+ :backends: bokeh,matplotlib,plotly
121
+
122
+ hv.Curve([1, 2, 3, 2, 1])
@@ -0,0 +1,80 @@
1
+ [build-system]
2
+ build-backend = "hatchling.build"
3
+ requires = [ "hatch-vcs", "hatchling" ]
4
+
5
+ [project]
6
+ name = "sphinx-exec-jupyter"
7
+ description = "Execute code and let Jupyter format the output"
8
+ license = "MPL-2.0"
9
+ authors = [ { name = "Philipp A.", email = "flying-sheep@web.de" } ]
10
+ requires-python = ">=3.12"
11
+ classifiers = [
12
+ "Framework :: Sphinx :: Extension",
13
+ "Programming Language :: Python :: 3 :: Only",
14
+ "Programming Language :: Python :: 3.12",
15
+ "Programming Language :: Python :: 3.13",
16
+ "Programming Language :: Python :: 3.14",
17
+ ]
18
+ dynamic = [ "version" ]
19
+ dependencies = [
20
+ "myst-nb>=1.4",
21
+ "nbformat>=5.10.4",
22
+ "sphinx>=9.1",
23
+ ]
24
+ optional-dependencies.holoviews = [ "holoviews", "sphinx-design" ]
25
+ urls.Documentation = "https://sphinx-exec-jupyter.readthedocs.io/"
26
+ urls.Source = "https://github.com/flying-sheep/sphinx-exec-jupyter"
27
+ entry-points."jupyter_client.kernel_provisioners".forking_provisioner = "sphinx_exec_jupyter._kernel_mgr:ForkingProvisioner"
28
+ entry-points."myst_nb.mime_renderers".holoviews = "sphinx_exec_jupyter.holoviews:HoloViewsMimeRenderer"
29
+
30
+ [tool.hatch]
31
+ version.source = "vcs"
32
+ envs.default.installer = "uv"
33
+ envs.default.features = [ "holoviews" ]
34
+ envs.default.dependencies = [ "furo", "matplotlib", "plotly" ]
35
+ envs.default.scripts.docs-build = "sphinx-build -M html docs docs/_build {args:-W}"
36
+ envs.default.scripts.docs-clean = "rm -rf docs/_build {args}"
37
+ envs.default.scripts.docs-open = "python -m webbrowser docs/_build/html/index.html {args}"
38
+ envs.hatch-test.features = [ "holoviews" ]
39
+ envs.hatch-test.extra-dependencies = [ "anyio", "nbformat-types", "pytest-mock" ]
40
+ envs.hatch-test.matrix = [
41
+ { python = [ "3.14", "3.12" ] },
42
+ ]
43
+
44
+ [tool.ruff]
45
+ lint.select = [ "ALL" ]
46
+ lint.ignore = [
47
+ "C408", # `dict()` is fine
48
+ "COM812", # conflict with formatter
49
+ "D203",
50
+ "D213",
51
+ "N999", # Intentional dash in scripts not used for import
52
+ "S101", # `assert` is fine
53
+ "TID252", # relative imports preferred
54
+ ]
55
+ lint.per-file-ignores."**/*-*" = [
56
+ "PLC0415", # imports are not at the top for a reason
57
+ "T201", # `print()` used for communication
58
+ ]
59
+ lint.per-file-ignores."docs/**/*" = [ "INP001" ]
60
+ lint.per-file-ignores."src/**/*" = [ "PT018" ]
61
+ lint.per-file-ignores."tests/**/*" = [ "D", "INP001" ]
62
+ lint.allowed-confusables = [ "×", "’" ]
63
+ lint.flake8-copyright.notice-rgx = "SPDX-License-Identifier: MPL-2\\.0"
64
+ lint.flake8-type-checking.exempt-modules = []
65
+ lint.flake8-type-checking.strict = true
66
+ lint.isort.required-imports = [ "from __future__ import annotations" ]
67
+
68
+ [tool.pytest]
69
+ addopts = [
70
+ "--import-mode=importlib",
71
+ "--doctest-modules",
72
+ "--pyargs",
73
+ ]
74
+ anyio_mode = "auto"
75
+ filterwarnings = [ "error" ]
76
+ strict = true
77
+
78
+ [tool.coverage]
79
+ run.patch = [ "subprocess" ]
80
+ run.source = [ "." ]
@@ -0,0 +1,53 @@
1
+ # SPDX-License-Identifier: MPL-2.0
2
+ """Sphinx extension to run code snippets using Jupyter machinery."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from contextlib import suppress
7
+ from importlib.metadata import version
8
+ from typing import TYPE_CHECKING
9
+
10
+ from sphinx.errors import ExtensionError
11
+ from sphinx.util.typing import ExtensionMetadata
12
+
13
+ from ._directive import ExecJupyterDirective
14
+ from ._kernel_mgr import maybe_patch_myst_nb
15
+
16
+ if TYPE_CHECKING:
17
+ from sphinx.application import Sphinx
18
+ from sphinx.config import Config
19
+
20
+
21
+ __all__ = ["ExecJupyterDirective", "setup"]
22
+
23
+
24
+ def setup(app: Sphinx) -> ExtensionMetadata:
25
+ """Add directive(s) and settings to Sphinx."""
26
+ app.setup_extension("myst_nb")
27
+ app.add_config_value("exec_jupyter_code", "", "env")
28
+ app.add_config_value("exec_jupyter_kernel", "python3", "env")
29
+ app.add_config_value("exec_jupyter_patch_myst_nb", True, "env") # noqa: FBT003
30
+ app.add_directive("exec-jupyter", ExecJupyterDirective)
31
+ app.connect("config-inited", _maybe_patch_myst_nb)
32
+
33
+ with suppress(ExtensionError):
34
+ app.setup_extension("sphinx_exec_jupyter.holoviews")
35
+
36
+ return ExtensionMetadata(
37
+ version=version("sphinx-exec-jupyter"),
38
+ parallel_read_safe=True,
39
+ parallel_write_safe=True,
40
+ )
41
+
42
+
43
+ def _maybe_patch_myst_nb(app: Sphinx, config: Config) -> None:
44
+ ctx = maybe_patch_myst_nb(config)
45
+ ctx.__enter__()
46
+
47
+ def cleanup(app: Sphinx, exc: Exception | None) -> None: # noqa: ARG001
48
+ if exc is None:
49
+ ctx.__exit__(None, None, None)
50
+ else:
51
+ ctx.__exit__(type(exc), exc, exc.__traceback__)
52
+
53
+ app.connect("build-finished", cleanup)
@@ -0,0 +1,24 @@
1
+ # SPDX-License-Identifier: MPL-2.0
2
+ from __future__ import annotations
3
+
4
+ from typing import TYPE_CHECKING
5
+
6
+ from sphinx.util.docutils import SphinxDirective
7
+
8
+ from ._kernel_mgr import maybe_patch_myst_nb
9
+ from .common import execute_cells
10
+
11
+ if TYPE_CHECKING:
12
+ from docutils import nodes
13
+
14
+
15
+ __all__ = ["ExecJupyterDirective"]
16
+
17
+
18
+ class ExecJupyterDirective(SphinxDirective):
19
+ has_content = True
20
+
21
+ def run(self) -> list[nodes.Node]:
22
+ code = "\n".join(self.content)
23
+ with maybe_patch_myst_nb(self.config):
24
+ return execute_cells([code], self.state.document)