diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..f10a5bc1f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + # Set update schedule for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "weekly" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 18909f0d0..f21103be1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -17,7 +17,7 @@ jobs: python-version: ["3.7", "3.10"] steps: - name: Check out repository code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install dependencies run: | sudo apt-get update @@ -38,7 +38,7 @@ jobs: cd docs make html SPHINXOPTS="-W" - name: Upload HTML - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: html path: build/sphinx/html @@ -47,7 +47,7 @@ jobs: cd docs make latexpdf - name: Upload PDF - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: pdf path: docs/build/latex/nbconvert.pdf diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2f36ab907..4ef978f49 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,100 +9,71 @@ concurrency: group: tests-${{ github.ref }} cancel-in-progress: true +defaults: + run: + shell: bash -eux {0} + jobs: run-tests: runs-on: ${{ matrix.os }} + env: + NBFORMAT_VALIDATOR: jsonschema strategy: matrix: - os: ["ubuntu-latest", "macos-latest", "windows-latest"] + os: ["ubuntu-20.04", "macos-latest", "windows-latest"] python-version: ["3.7", "3.10"] include: - os: "windows-latest" python-version: "3.8" - - os: "ubuntu-latest" + - os: "ubuntu-20.04" python-version: "3.9" fail-fast: false steps: - - name: Check out repository code - uses: actions/checkout@v2 - - name: Run base setup actions - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - - uses: conda-incubator/setup-miniconda@v2 - with: - mamba-version: "*" - channels: conda-forge - - name: Install conda-forge python - shell: bash -l {0} - run: | - mamba create -n nbconvert - conda activate nbconvert - mamba install python=${{ matrix.python-version }} - - name: Install conda-forge dependencies - shell: bash -l {0} - run: | - mamba create -n nbconvert - conda activate nbconvert - mamba install pip pyqtwebengine pandoc pyxdg + - uses: actions/checkout@v3 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - name: Install Linux dependencies if: startsWith(runner.os, 'Linux') run: | sudo apt-get update - sudo apt-get install texlive-plain-generic inkscape texlive-xetex - sudo apt-get install xvfb x11-utils libxkbcommon-x11-0 - - name: Install package dependencies - shell: bash -l {0} - run: | - conda activate nbconvert - pip install codecov - pip install -e ".[execute,serve,test]" - which python - python -m ipykernel.kernelspec --sys-prefix - - - name: List installed packages - shell: bash -l {0} - run: | - conda activate nbconvert - pip freeze - pip check + sudo apt-get install texlive-plain-generic inkscape texlive-xetex latexmk + sudo apt-get install xvfb x11-utils libxkbcommon-x11-0 libxcb-xinerama0 python3-pyqt5 - - name: Run tests on MacOS - if: ${{ startsWith(runner.os, 'macos') }} - shell: bash -l {0} - run: | - conda activate nbconvert - # See https://github.com/pyppeteer/pyppeteer/pull/321 - pip install -U websockets - python -m pytest --cov nbconvert -vv + # pandoc is not up to date in the ubuntu repos, so we install directly + wget https://github.com/jgm/pandoc/releases/download/2.14.2/pandoc-2.14.2-1-amd64.deb && sudo dpkg -i pandoc-2.14.2-1-amd64.deb - name: Run tests on Linux if: ${{ startsWith(runner.os, 'linux') }} - shell: bash -l {0} run: | - conda activate nbconvert - # See https://github.com/pyppeteer/pyppeteer/pull/321 - pip install -U websockets - NBFORMAT_VALIDATOR=jsonschema xvfb-run --auto-servernum `which coverage` run -m pytest -vv - - - name: Run tests on pypy and Windows - if: ${{ startsWith(runner.os, 'Windows') }} - shell: bash -l {0} + xvfb-run --auto-servernum hatch run cov:test + + - name: Run tests on other platforms + if: ${{ !startsWith(runner.os, 'linux') }} run: | - conda activate nbconvert - # See https://github.com/pyppeteer/pyppeteer/pull/321 - pip install -U websockets - python -m pytest -vv + hatch run cov:test - name: Code coverage - shell: bash -l {0} run: | - conda activate nbconvert + pip install codecov coverage[toml] codecov + test_lint: + name: Test Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - name: Run Linters + run: | + hatch run lint:style + pipx run 'validate-pyproject[all]' pyproject.toml + pipx run doc8 --max-line-length=200 --ignore-path=docs/source/other/full-config.rst + check_release: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - run: pip install -e . - uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2 @@ -114,7 +85,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 with: @@ -124,7 +95,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/pre-commit@v1 @@ -133,45 +104,37 @@ jobs: timeout-minutes: 20 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 with: - python_version: "3.7" - - name: Install miniumum versions - uses: jupyterlab/maintainer-tools/.github/actions/install-minimums@v1 + dependency_type: minimum + only_create_file: 1 - name: Run the unit tests run: | export NBFORMAT_VALIDATOR=jsonschema - pytest -vv -W default || pytest -vv -W default --lf + hatch run test:nowarn || hatch run test:nowarn --lf test_prereleases: name: Test Prereleases runs-on: ubuntu-latest timeout-minutes: 20 steps: - - name: Checkout - uses: actions/checkout@v2 - - name: Base Setup - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - - name: Install the Python dependencies - run: | - pip install --pre -e ".[test]" - - name: List installed packages - run: | - pip freeze - pip check + - uses: actions/checkout@v3 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + with: + dependency_type: pre - name: Run the tests run: | export NBFORMAT_VALIDATOR=jsonschema - pytest -vv -W default || pytest -vv -W default --lf + hatch run test:nowarn || hatch run test:nowarn --lf make_sdist: name: Make SDist runs-on: ubuntu-latest timeout-minutes: 10 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/make-sdist@v1 @@ -183,3 +146,20 @@ jobs: steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - uses: jupyterlab/maintainer-tools/.github/actions/test-sdist@v1 + + tests_check: # This job does nothing and is only used for the branch protection + if: always() + needs: + - run-tests + - pre_commit + - test_minimum_versions + - test_prereleases + - check_links + - check_release + - test_sdist + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8ef3cfbd..3c8b7ff96 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,9 @@ +ci: + autoupdate_schedule: monthly + repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: end-of-file-fixer - id: check-case-conflict @@ -15,69 +18,25 @@ repos: - id: check-builtin-literals - id: trailing-whitespace - - repo: https://github.com/psf/black - rev: 22.10.0 + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.19.2 hooks: - - id: black - args: ["--line-length", "100"] - - - repo: https://github.com/PyCQA/isort - rev: 5.10.1 - hooks: - - id: isort - files: \.py$ - args: [--profile=black] - stages: [manual] - - - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.10.1 - hooks: - - id: validate-pyproject - stages: [manual] + - id: check-github-workflows - repo: https://github.com/executablebooks/mdformat rev: 0.7.16 hooks: - id: mdformat - - - repo: https://github.com/asottile/pyupgrade - rev: v3.1.0 - hooks: - - id: pyupgrade - args: [--py37-plus] - - - repo: https://github.com/PyCQA/doc8 - rev: v1.0.0 - hooks: - - id: doc8 - args: [--max-line-length=200] - stages: [manual] - - - repo: https://github.com/john-hen/Flake8-pyproject - rev: 1.1.0.post0 - hooks: - - id: Flake8-pyproject - alias: flake8 additional_dependencies: - ["flake8-bugbear==22.6.22", "flake8-implicit-str-concat==0.2.0"] - stages: [manual] + [mdformat-gfm, mdformat-frontmatter, mdformat-footnote] - - repo: https://github.com/sirosen/check-jsonschema - rev: 0.18.4 + - repo: https://github.com/psf/black + rev: 22.10.0 hooks: - - id: check-jsonschema - name: "Check GitHub Workflows" - files: ^\.github/workflows/ - types: [yaml] - args: ["--schemafile", "https://json.schemastore.org/github-workflow"] - stages: [manual] + - id: black - - repo: local + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.181 hooks: - - id: check-pyproject - name: check pyproject file - language: python - entry: python -m check_requirements - files: ^pyproject.toml$ - stages: [manual] - additional_dependencies: ["tomli"] + - id: ruff + args: ["--fix"] diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 0a842d7bd..6bc1cf12c 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,14 +10,13 @@ sphinx: formats: all -conda: - environment: docs/environment.yml - build: image: latest python: - version: 3.7 + version: 3.8 install: - method: pip path: . + extra_requirements: + - docs diff --git a/CHANGELOG.md b/CHANGELOG.md index 752b94bb7..98a018e54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,63 @@ +## 7.2.6 + +([Full Changelog](https://github.com/jupyter/nbconvert/compare/v7.2.5...788dd3c4de1b6333e807250d0f33b59b80d5b202)) + +### Maintenance and upkeep improvements + +- Include all templates in sdist [#1916](https://github.com/jupyter/nbconvert/pull/1916) ([@blink1073](https://github.com/blink1073)) +- clean up workflows [#1911](https://github.com/jupyter/nbconvert/pull/1911) ([@blink1073](https://github.com/blink1073)) +- CI Cleanup [#1910](https://github.com/jupyter/nbconvert/pull/1910) ([@blink1073](https://github.com/blink1073)) + +### Documentation improvements + +- Fix docs build and switch to PyData Sphinx Theme [#1912](https://github.com/jupyter/nbconvert/pull/1912) ([@blink1073](https://github.com/blink1073)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter/nbconvert/graphs/contributors?from=2022-11-14&to=2022-12-05&type=c)) + +[@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3Ablink1073+updated%3A2022-11-14..2022-12-05&type=Issues) + + + +## 7.2.5 + +([Full Changelog](https://github.com/jupyter/nbconvert/compare/v7.2.4...e5fefbb17b0bf3d6b5bbeb9a2ee62412d75ab0d8)) + +### Bugs fixed + +- Fix for webpdf print margins [#1907](https://github.com/jupyter/nbconvert/pull/1907) ([@JWock82](https://github.com/JWock82)) + +### Maintenance and upkeep improvements + +- Bump actions/upload-artifact from 2 to 3 [#1904](https://github.com/jupyter/nbconvert/pull/1904) ([@dependabot](https://github.com/dependabot)) +- Bump actions/checkout from 2 to 3 [#1903](https://github.com/jupyter/nbconvert/pull/1903) ([@dependabot](https://github.com/dependabot)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter/nbconvert/graphs/contributors?from=2022-11-09&to=2022-11-14&type=c)) + +[@dependabot](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3Adependabot+updated%3A2022-11-09..2022-11-14&type=Issues) | [@JWock82](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3AJWock82+updated%3A2022-11-09..2022-11-14&type=Issues) + +## 7.2.4 + +([Full Changelog](https://github.com/jupyter/nbconvert/compare/v7.2.3...90ca66ccf02abc59052f4f38dcc657b0d2c34a07)) + +### Maintenance and upkeep improvements + +- Handle jupyter core warning [#1905](https://github.com/jupyter/nbconvert/pull/1905) ([@blink1073](https://github.com/blink1073)) +- Add dependabot [#1902](https://github.com/jupyter/nbconvert/pull/1902) ([@blink1073](https://github.com/blink1073)) +- Add Py-typed marker. [#1898](https://github.com/jupyter/nbconvert/pull/1898) ([@Carreau](https://github.com/Carreau)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyter/nbconvert/graphs/contributors?from=2022-10-27&to=2022-11-09&type=c)) + +[@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3Ablink1073+updated%3A2022-10-27..2022-11-09&type=Issues) | [@Carreau](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3ACarreau+updated%3A2022-10-27..2022-11-09&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3Apre-commit-ci+updated%3A2022-10-27..2022-11-09&type=Issues) + ## 7.2.3 ([Full Changelog](https://github.com/jupyter/nbconvert/compare/v7.2.2...04180fdb015c56ac320d5062a81da065791c5726)) @@ -18,8 +75,6 @@ [@akx](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3Aakx+updated%3A2022-10-19..2022-10-27&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyter%2Fnbconvert+involves%3Apre-commit-ci+updated%3A2022-10-19..2022-10-27&type=Issues) - - ## 7.2.2 ([Full Changelog](https://github.com/jupyter/nbconvert/compare/v7.2.1...a9566befb6e457b51373b61debffc78050d41273)) diff --git a/README.md b/README.md index 31d4466b2..6cf613a0b 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,8 @@ ### Jupyter Notebook Conversion -[![Google Group](https://img.shields.io/badge/-Google%20Group-lightgrey.svg)](https://groups.google.com/forum/#!forum/jupyter) [![Build Status](https://travis-ci.org/jupyter/nbconvert.svg?branch=main)](https://travis-ci.org/jupyter/nbconvert) [![Documentation Status](https://readthedocs.org/projects/nbconvert/badge/?version=latest)](https://nbconvert.readthedocs.io/en/latest/?badge=latest) -[![Documentation Status](https://readthedocs.org/projects/nbconvert/badge/?version=stable)](https://nbconvert.readthedocs.io/en/stable/?badge=stable) [![codecov.io](https://codecov.io/github/jupyter/nbconvert/coverage.svg?branch=main)](https://codecov.io/github/jupyter/nbconvert?branch=main) The **nbconvert** tool, `jupyter nbconvert`, converts notebooks to various other diff --git a/check_requirements.py b/check_requirements.py index a3c53fc74..ae10f441f 100644 --- a/check_requirements.py +++ b/check_requirements.py @@ -21,11 +21,11 @@ if errors: print('Missing deps in "all" reqs:') - print([e for e in errors]) + print(list(errors)) if remaining_all: print('Reqs in "all" but nowhere else:') - print([r for r in remaining_all]) + print(list(remaining_all)) if errors or remaining_all: sys.exit(1) diff --git a/codecov.yml b/codecov.yml index 2962fbce9..b75c3e2db 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,8 +3,7 @@ coverage: project: default: target: auto - threshold: 10 + threshold: 1 patch: default: target: 0% -comments: off diff --git a/docs/environment.yml b/docs/environment.yml deleted file mode 100644 index 447a88ecf..000000000 --- a/docs/environment.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: nbconvert_docs -channels: - - conda-forge -dependencies: - - python==3.9 - - pandoc - - nbformat - - jupyter_client - - ipython - - sphinx>=1.5.1 - - sphinx_rtd_theme - - tornado - - entrypoints - - ipykernel - - pip - - pip: - - nbsphinx>=0.7.1 diff --git a/docs/source/conf.py b/docs/source/conf.py index 2cd92cc26..9eb629219 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -24,7 +24,7 @@ # Automatically generate config_options.rst with open(os.path.join(HERE, "..", "autogen_config.py")) as f: - exec(compile(f.read(), "autogen_config.py", "exec"), {}) + exec(compile(f.read(), "autogen_config.py", "exec"), {}) # noqa print("Created docs for config options") # -- General configuration ------------------------------------------------ @@ -82,7 +82,7 @@ # Get information from _version.py and use it to generate version and release _version_py = os.path.join(HERE, "../../nbconvert/_version.py") version_ns = {} -exec(compile(open(_version_py).read(), _version_py, "exec"), version_ns) +exec(compile(open(_version_py).read(), _version_py, "exec"), version_ns) # noqa # The short X.Y version. version = "%i.%i" % version_ns["version_info"][:2] # The full version, including alpha/beta/rc tags. @@ -135,15 +135,7 @@ # -- Options for HTML output ---------------------------------------------- -# Set on_rtd to whether we are building on readthedocs.org. We get this line of -# code grabbed from docs.readthedocs.org -on_rtd = os.environ.get("READTHEDOCS", None) == "True" - -if not on_rtd: # only import and set the theme if we're building docs locally - import sphinx_rtd_theme - - html_theme = "sphinx_rtd_theme" - html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] +html_theme = "pydata_sphinx_theme" # otherwise, readthedocs.org uses their default theme, so no need to specify it diff --git a/docs/source/install.rst b/docs/source/install.rst index 0fa6b9a08..8cdc10f3a 100644 --- a/docs/source/install.rst +++ b/docs/source/install.rst @@ -69,7 +69,7 @@ packages are specific to different operating systems: sudo apt-get install texlive-xetex texlive-fonts-recommended texlive-plain-generic * macOS (OS X): `MacTeX `_. -* Windows: `MikTex `_ +* Windows: `Latex Project `_. Because nbconvert depends on packages and fonts included in standard TeX distributions, if you do not have a complete installation, you diff --git a/docs/source/nbconvert_library.ipynb b/docs/source/nbconvert_library.ipynb index cd69c50d1..cb3f8e37b 100644 --- a/docs/source/nbconvert_library.ipynb +++ b/docs/source/nbconvert_library.ipynb @@ -71,6 +71,7 @@ "outputs": [], "source": [ "import nbformat\n", + "\n", "jake_notebook = nbformat.reads(response, as_version=4)\n", "jake_notebook.cells[0]" ] @@ -101,7 +102,7 @@ "\n", "# 2. Instantiate the exporter. We use the `classic` template for now; we'll get into more details\n", "# later about how to customize the exporter further.\n", - "html_exporter = HTMLExporter(template_name = 'classic')\n", + "html_exporter = HTMLExporter(template_name='classic')\n", "\n", "# 3. Process the notebook we loaded earlier\n", "(body, resources) = html_exporter.from_notebook_node(jake_notebook)" @@ -185,6 +186,7 @@ "source": [ "# Import the RST exproter\n", "from nbconvert import RSTExporter\n", + "\n", "# Instantiate it\n", "rst_exporter = RSTExporter()\n", "# Convert the notebook to RST format\n", @@ -237,6 +239,7 @@ "outputs": [], "source": [ "from IPython.display import Image\n", + "\n", "Image(data=resources['outputs']['output_3_0.png'], format='png')" ] }, @@ -297,6 +300,7 @@ "source": [ "# create a configuration object that changes the preprocessors\n", "from traitlets.config import Config\n", + "\n", "c = Config()\n", "c.HTMLExporter.preprocessors = ['nbconvert.preprocessors.ExtractOutputPreprocessor']\n", "\n", @@ -322,7 +326,7 @@ }, "outputs": [], "source": [ - "(_, resources) = html_exporter.from_notebook_node(jake_notebook)\n", + "(_, resources) = html_exporter.from_notebook_node(jake_notebook)\n", "(_, resources_with_fig) = html_exporter_with_figs.from_notebook_node(jake_notebook)\n", "\n", "print(\"resources without figures:\")\n", @@ -380,17 +384,18 @@ "from traitlets import Integer\n", "from nbconvert.preprocessors import Preprocessor\n", "\n", + "\n", "class PelicanSubCell(Preprocessor):\n", " \"\"\"A Pelican specific preprocessor to remove some of the cells of a notebook\"\"\"\n", - " \n", + "\n", " # I could also read the cells from nb.metadata.pelican if someone wrote a JS extension,\n", - " # but for now I'll stay with configurable value. \n", - " start = Integer(0, help=\"first cell of notebook to be converted\").tag(config=True)\n", - " end = Integer(-1, help=\"last cell of notebook to be converted\").tag(config=True)\n", - " \n", + " # but for now I'll stay with configurable value.\n", + " start = Integer(0, help=\"first cell of notebook to be converted\").tag(config=True)\n", + " end = Integer(-1, help=\"last cell of notebook to be converted\").tag(config=True)\n", + "\n", " def preprocess(self, nb, resources):\n", " self.log.info(\"I'll keep only cells from %d to %d\", self.start, self.end)\n", - " nb.cells = nb.cells[self.start:self.end] \n", + " nb.cells = nb.cells[self.start : self.end]\n", " return nb, resources" ] }, @@ -412,7 +417,7 @@ "outputs": [], "source": [ "# Create a new config object that configures both the new preprocessor, as well as the exporter\n", - "c = Config()\n", + "c = Config()\n", "c.PelicanSubCell.start = 4\n", "c.PelicanSubCell.end = 6\n", "c.RSTExporter.preprocessors = [PelicanSubCell]\n", @@ -443,14 +448,17 @@ "source": [ "from jinja2 import DictLoader\n", "\n", - "dl = DictLoader({'footer': \n", - "\"\"\"\n", + "dl = DictLoader(\n", + " {\n", + " 'footer': \"\"\"\n", "{%- extends 'lab/index.html.j2' -%} \n", "\n", "{% block footer %}\n", "FOOOOOOOOTEEEEER\n", "{% endblock footer %}\n", - "\"\"\"})\n", + "\"\"\"\n", + " }\n", + ")\n", "\n", "\n", "exportHTML = HTMLExporter(extra_loaders=[dl], template_file='footer')\n", diff --git a/nbconvert/_version.py b/nbconvert/_version.py index 722df4e5f..9e291e28c 100644 --- a/nbconvert/_version.py +++ b/nbconvert/_version.py @@ -2,7 +2,7 @@ from typing import List # Version string must appear intact for versioning -__version__ = "7.2.3" +__version__ = "7.2.6" # Build up version_info tuple for backwards compatibility pattern = r"(?P\d+).(?P\d+).(?P\d+)(?P.*)" diff --git a/nbconvert/exporters/pdf.py b/nbconvert/exporters/pdf.py index 1c72f3e9a..3befa0e72 100644 --- a/nbconvert/exporters/pdf.py +++ b/nbconvert/exporters/pdf.py @@ -15,7 +15,7 @@ from .latex import LatexExporter -class LatexFailed(IOError): +class LatexFailed(IOError): # noqa """Exception for failed latex run Captured latex output is in error.output. diff --git a/nbconvert/exporters/templateexporter.py b/nbconvert/exporters/templateexporter.py index a4aeb5889..8e7b6f9d7 100644 --- a/nbconvert/exporters/templateexporter.py +++ b/nbconvert/exporters/templateexporter.py @@ -122,7 +122,7 @@ def get_source(self, environment, template): return self.loader.get_source(environment, template) except TemplateNotFound: if template.endswith(self.extension): - raise TemplateNotFound(template) + raise TemplateNotFound(template) from None return self.loader.get_source(environment, template + self.extension) def list_templates(self): @@ -569,9 +569,9 @@ def _template_paths(self, prune=True, root_dirs=None): def get_compatibility_base_template_conf(cls, name): # Hard-coded base template confs to use for backwards compatibility for 5.x-only templates if name == "display_priority": - return dict(base_template="base") + return {"base_template": "base"} if name == "full": - return dict(base_template="classic", mimetypes={"text/html": True}) + return {"base_template": "classic", "mimetypes": {"text/html": True}} def get_template_names(self): # finds a list of template names where each successive template name is the base template diff --git a/nbconvert/exporters/tests/files/notebook2.ipynb b/nbconvert/exporters/tests/files/notebook2.ipynb index 1ff2e7532..f459aa2fe 100644 --- a/nbconvert/exporters/tests/files/notebook2.ipynb +++ b/nbconvert/exporters/tests/files/notebook2.ipynb @@ -55,7 +55,7 @@ "metadata": {}, "outputs": [], "source": [ - "a = np.random.uniform(size=(100,100))" + "a = np.random.uniform(size=(100, 100))" ] }, { diff --git a/nbconvert/exporters/tests/files/notebook_inject.ipynb b/nbconvert/exporters/tests/files/notebook_inject.ipynb index 2ddb76129..f7f7173e4 100644 --- a/nbconvert/exporters/tests/files/notebook_inject.ipynb +++ b/nbconvert/exporters/tests/files/notebook_inject.ipynb @@ -5,257 +5,304 @@ "execution_count": null, "id": "79aede83-fba6-4715-bce6-9f3926b128a2", "metadata": { - "tags": ["FOO\">
alert('raw cell')" - ] + "cell_type": "raw", + "id": "372c2bf1", + "metadata": {}, + "source": [ + "Payload in raw cell " + ] }, { - "cell_type": "markdown", - "id": "2d42de4a", - "metadata": {}, - "source": [ - "" - ] + "cell_type": "markdown", + "id": "2d42de4a", + "metadata": {}, + "source": [ + "" + ] }, { - "cell_type": "code", - "execution_count": null, - "id": "b72e53fa", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/svg+xml": [""] - }, - "execution_count": null, - "metadata": {} - } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b72e63fa", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/png": [""] - }, - "execution_count": null, - "metadata": { - "filenames": { - "image/png": "\">" - } - } - } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b72e63f3", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/jpeg": [""] - }, - "execution_count": null, - "metadata": { - "filenames": { - "image/jpeg": "\">" - } - } - } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b72e635a", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/png": ["\">"] - }, - "execution_count": null, - "metadata": {} - } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "p72e635a", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/jpeg": ["\">"] - }, - "execution_count": null, - "metadata": {} - } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d72e635a", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/png": ["abcd"] - }, - "execution_count": null, - "metadata": { - "width": ">" - } - } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d72e095a", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/png": ["abcd"] - }, - "execution_count": null, - "metadata": { - "width": [">"] - } + "cell_type": "code", + "execution_count": null, + "id": "b72e53fa", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/svg+xml": [ + "" + ] + }, + "execution_count": null, + "metadata": {} + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b72e63fa", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": [ + "" + ] + }, + "execution_count": null, + "metadata": { + "filenames": { + "image/png": "\">" } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae4f574d", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "image/png": ["abcd"] - }, - "execution_count": null, - "metadata": { - "height": ">" - } + } + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b72e63f3", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/jpeg": [ + "" + ] + }, + "execution_count": null, + "metadata": { + "filenames": { + "image/jpeg": "\">" } - ], - "source": [""] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "w72e635a", - "metadata": {}, - "outputs": [ - { - "output_type": "execute_result", - "data": { - "application/vnd.jupyter.widget-view+json": {"model_id": "wid1", "foo": "\"" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" } - ], - "source": [ - "import os; os.system('touch /tmp/pwned')" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "3616e107", - "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b72e635a", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": [ + "\">" + ] + }, + "execution_count": null, + "metadata": {} + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "p72e635a", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/jpeg": [ + "\">" + ] + }, + "execution_count": null, + "metadata": {} + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d72e635a", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": [ + "abcd" + ] + }, + "execution_count": null, + "metadata": { + "width": ">" } - ], - "source": [ - "import os; os.system('touch /tmp/pwned')" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "4616e107", - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "alert('application/javascript output')" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d72e095a", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": [ + "abcd" + ] + }, + "execution_count": null, + "metadata": { + "width": [ + ">" + ] } - ], - "source": [ - "import os; os.system('touch /tmp/pwned')" - ] - } + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ae4f574d", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "image/png": [ + "abcd" + ] + }, + "execution_count": null, + "metadata": { + "height": ">" + } + } + ], + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "w72e635a", + "metadata": {}, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "wid1", + "foo": "\"" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import os\n", + "\n", + "os.system('touch /tmp/pwned')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "3616e107", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import os\n", + "\n", + "os.system('touch /tmp/pwned')" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "4616e107", + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "alert('application/javascript output')" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import os\n", + "\n", + "os.system('touch /tmp/pwned')" + ] + } ], "metadata": { "title": "TITLE", @@ -277,7 +324,12 @@ "version": "3.10.5" }, "widgets": { - "application/vnd.jupyter.widget-state+json": {"state": {"wid1": {}}, "foo": "pwntester