New Upstream Release - octave-kernel

Ready changes

Summary

Merged new upstream version: 0.35.1 (was: 0.32.0).

Diff

diff --git a/.github/workflows/check-release.yml b/.github/workflows/check-release.yml
new file mode 100644
index 0000000..cf36b78
--- /dev/null
+++ b/.github/workflows/check-release.yml
@@ -0,0 +1,29 @@
+name: Check Release
+on:
+  push:
+    branches: ["main"]
+  pull_request:
+    branches: ["*"]
+
+jobs:
+  check_release:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        group: [check_release, link_check]
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Base Setup
+        uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+      - name: Install Dependencies
+        run: |
+          make install
+      - name: Check Release
+        if: ${{ matrix.group == 'check_release' }}
+        uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v1
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+      - name: Run Link Check
+        if: ${{ matrix.group == 'link_check' }}
+        uses: jupyter-server/jupyter_releaser/.github/actions/check-links@v1
diff --git a/.github/workflows/enforce-label.yml b/.github/workflows/enforce-label.yml
new file mode 100644
index 0000000..354a046
--- /dev/null
+++ b/.github/workflows/enforce-label.yml
@@ -0,0 +1,11 @@
+name: Enforce PR label
+
+on:
+  pull_request:
+    types: [labeled, unlabeled, opened, edited, synchronize]
+jobs:
+  enforce-label:
+    runs-on: ubuntu-latest
+    steps:
+      - name: enforce-triage-label
+        uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..8e5c70f
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,64 @@
+
+name: tests
+
+on:
+  push:
+  pull_request:
+    branches: [ "main" ]
+  schedule:
+    # Run weekly
+    # * is a special character in YAML so you have to quote this string
+    - cron:  '0 0 * * 0'
+
+defaults:
+  run:
+    shell: bash -l {0}
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python-version: [3.7, 3.8, 3.9, '3.10']
+
+    steps:
+    - uses: actions/checkout@v2
+    - name: Base Setup
+      uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+    - name: Setup conda ${{ matrix.python-version }}
+      uses: conda-incubator/setup-miniconda@v2
+      with:
+        auto-update-conda: true
+        miniforge-variant: Mambaforge
+        python-version: ${{ matrix.python-version }}
+    - name: Install dependencies
+      run: |
+        conda install -y octave
+        make install
+        make docker-build
+    - name: Run test
+      run: |
+         python -m octave_kernel.check
+         xvfb-run --auto-servernum make test
+         python -m octave_kernel install --user
+
+  make_sdist:
+    name: Make SDist
+    runs-on: ubuntu-latest
+    timeout-minutes: 10
+    steps:
+      - uses: actions/checkout@v2
+      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+      - run: make data-files
+      - uses: jupyterlab/maintainer-tools/.github/actions/make-sdist@v1
+
+  test_sdist:
+    runs-on: ubuntu-latest
+    needs: [make_sdist]
+    name: Install from SDist and Test
+    timeout-minutes: 20
+    steps:
+      - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
+      - uses: jupyterlab/maintainer-tools/.github/actions/test-sdist@v1
+        with:
+          test_command: "jupyter kernelspec list | grep octave"
diff --git a/.gitignore b/.gitignore
index 23b38bf..1801d1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ build/
 octave-workspace
 *.egg-info/
 *.pyc
+jupyter-data
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1cfe181..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-language: python
-dist: trusty
-cache:
-    apt: true
-    pip: true
-python:
-  - "2.7"
-  - "3.5"
-  - "3.6"
-services:
-  docker
-install:
-  - travis_retry sudo add-apt-repository -y ppa:octave/stable
-  - travis_retry sudo apt-get update -qq
-  - travis_retry sudo apt-get install -y octave
-  - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
-  - bash miniconda.sh -b -p $HOME/miniconda
-  - export PATH="$HOME/miniconda/bin:$PATH"
-  - hash -r
-  - conda config --set always_yes yes --set changeps1 no
-  - conda update -q conda
-  - conda info -a
-  - conda install -c conda-forge pip
-  - pip install .
-  - make docker-build
-script:
-  - make test
-  - python -m octave_kernel install --user
-notifications:
-  email:
-    - steven.silvester@ieee.org
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..58093e6
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,183 @@
+# Changelog
+
+<!-- <START NEW CHANGELOG ENTRY> -->
+
+## 0.35.1
+
+([Full Changelog](https://github.com/Calysto/octave_kernel/compare/v0.35.0...59c1841ae47ec594516d0aca355e0ef14f7eb61f))
+
+### Bugs fixed
+
+- Include test and example notebook in sdist [#228](https://github.com/Calysto/octave_kernel/pull/228) ([@blink1073](https://github.com/blink1073))
+
+### Contributors to this release
+
+([GitHub contributors page for this release](https://github.com/Calysto/octave_kernel/graphs/contributors?from=2022-11-28&to=2022-11-29&type=c))
+
+[@blink1073](https://github.com/search?q=repo%3ACalysto%2Foctave_kernel+involves%3Ablink1073+updated%3A2022-11-28..2022-11-29&type=Issues)
+
+<!-- <END NEW CHANGELOG ENTRY> -->
+
+## 0.35.0
+
+No merged PRs
+
+## 0.34.2
+
+([Full Changelog](https://github.com/Calysto/octave_kernel/compare/v0.34.1...0c2501cc4d452cad5ee17f6a5369d57c6da30a90))
+
+### Bugs fixed
+
+- Fix error: '_make_figures' undefined near line 1, column 1 [#212](https://github.com/Calysto/octave_kernel/pull/212) ([@mokeyish](https://github.com/mokeyish))
+
+### Contributors to this release
+
+([GitHub contributors page for this release](https://github.com/Calysto/octave_kernel/graphs/contributors?from=2022-02-07&to=2022-03-31&type=c))
+
+[@mokeyish](https://github.com/search?q=repo%3ACalysto%2Foctave_kernel+involves%3Amokeyish+updated%3A2022-02-07..2022-03-31&type=Issues)
+
+## 0.34.1
+
+([Full Changelog](https://github.com/Calysto/octave_kernel/compare/v0.34.0...d6b0a4a0beae56e5b85e6640cf29fb2a504fc1d5))
+
+### Bugs fixed
+
+- Improve handling of default inline toolkit [#209](https://github.com/Calysto/octave_kernel/pull/209) ([@blink1073](https://github.com/blink1073))
+
+### Contributors to this release
+
+([GitHub contributors page for this release](https://github.com/Calysto/octave_kernel/graphs/contributors?from=2022-01-04&to=2022-02-07&type=c))
+
+[@blink1073](https://github.com/search?q=repo%3ACalysto%2Foctave_kernel+involves%3Ablink1073+updated%3A2022-01-04..2022-02-07&type=Issues)
+
+## 0.34.0
+
+([Full Changelog](https://github.com/Calysto/octave_kernel/compare/v0.33.1...0ae34050c2e6a2cbf45b9cdb1a69762fece9e081))
+
+### Enhancements made
+
+- Use octave executable and qt backend by default [#204](https://github.com/Calysto/octave_kernel/pull/204) ([@blink1073](https://github.com/blink1073))
+
+### Maintenance and upkeep improvements
+
+- Fail if kernel test fails [#203](https://github.com/Calysto/octave_kernel/pull/203) ([@blink1073](https://github.com/blink1073))
+- Use published jupyter_kernel_test [#202](https://github.com/Calysto/octave_kernel/pull/202) ([@blink1073](https://github.com/blink1073))
+
+### Contributors to this release
+
+([GitHub contributors page for this release](https://github.com/Calysto/octave_kernel/graphs/contributors?from=2021-11-27&to=2022-01-04&type=c))
+
+[@blink1073](https://github.com/search?q=repo%3ACalysto%2Foctave_kernel+involves%3Ablink1073+updated%3A2021-11-27..2022-01-04&type=Issues)
+
+## 0.33.1
+
+([Full Changelog](https://github.com/Calysto/octave_kernel/compare/0.32.0...94f977d10ee6e1e278a2b2d79239f953a3274b7b))
+
+### Maintenance and upkeep improvements
+
+- Prep for jupyter releaser usage [#200](https://github.com/Calysto/octave_kernel/pull/200) ([@blink1073](https://github.com/blink1073))
+- Upgrade to jupyter packaging and github actions [#199](https://github.com/Calysto/octave_kernel/pull/199) ([@blink1073](https://github.com/blink1073))
+
+### Contributors to this release
+
+([GitHub contributors page for this release](https://github.com/Calysto/octave_kernel/graphs/contributors?from=2020-05-23&to=2021-11-27&type=c))
+
+[@blink1073](https://github.com/search?q=repo%3ACalysto%2Foctave_kernel+involves%3Ablink1073+updated%3A2020-05-23..2021-11-27&type=Issues)
+
+## 0.32.0
+
+- Snap plot fix [#175](https://github.com/Calysto/octave_kernel/pull/175) ([@PhilFreeman](https://github.com/PhilFreeman))
+- Add libglu1 to apt.txt, switch to JupyterLab for Binder [#173](https://github.com/Calysto/octave_kernel/pull/173) ([@jtpio](https://github.com/jtpio))
+- Add Binder files [#172](https://github.com/Calysto/octave_kernel/pull/172) ([@jtpio](https://github.com/jtpio))
+- Fix tests with Octave 5. [#160](https://github.com/Calysto/octave_kernel/pull/160) ([@QuLogic](https://github.com/QuLogic))
+
+## v0.31.0
+
+- Use new line_handler from metakernel (optionally) [#158](https://github.com/Calysto/octave_kernel/pull/158) ([@blink1073](https://github.com/blink1073))
+- Add the full license [#157](https://github.com/Calysto/octave_kernel/pull/157) ([@toddrme2178](https://github.com/toddrme2178))
+
+## v0.30.2
+
+- Allow inline backend to be specified using plot magic [#154](https://github.com/Calysto/octave_kernel/pull/154) ([@blink1073](https://github.com/blink1073))
+
+## v0.30.1
+
+- Clean up plot handling and add config [#153](https://github.com/Calysto/octave_kernel/pull/153) ([@blink1073](https://github.com/blink1073))
+
+## v0.29.2
+
+- Add a Dockerfile [#151](https://github.com/Calysto/octave_kernel/pull/151) ([@blink1073](https://github.com/blink1073))
+
+## v0.28.6
+
+- Adds texinfo to README [#140](https://github.com/Calysto/octave_kernel/pull/140) ([@sigurdurb](https://github.com/sigurdurb))
+
+## v0.28.5
+
+- Use `jupyter` rather than `ipython` in README [#137](https://github.com/Calysto/octave_kernel/pull/137) ([@robertoostenveld](https://github.com/robertoostenveld))
+
+## v0.28.4
+
+- Include `LICENSE.txt` file in wheels [#131](https://github.com/Calysto/octave_kernel/pull/131) ([@toddrme2178](https://github.com/toddrme2178))
+
+## v0.28.3
+
+- Kernel JSON path as env variable [#114](https://github.com/Calysto/octave_kernel/pull/114) ([@diocas](https://github.com/diocas))
+
+## v0.28.2
+
+- Ensure `octaverc` does not override PS1 [#108](https://github.com/Calysto/octave_kernel/pull/108) ([@blink1073](https://github.com/blink1073))
+
+## v0.28.0
+
+- Switch to a `data_files` based install [#104](https://github.com/Calysto/octave_kernel/pull/104) ([@blink1073](https://github.com/blink1073))
+
+## v0.27.1
+
+- Fix unmatched backtick [#101](https://github.com/Calysto/octave_kernel/pull/101) ([@Carreau](https://github.com/Carreau))
+- Use conda forge octave for testing [#100](https://github.com/Calysto/octave_kernel/pull/100) ([@blink1073](https://github.com/blink1073))
+
+## v0.27.0
+
+- Add images and switch to metakernel standard install method [#99](https://github.com/Calysto/octave_kernel/pull/99) ([@blink1073](https://github.com/blink1073))
+- Fix Travis and add Python 3.6 test [#92](https://github.com/Calysto/octave_kernel/pull/92) ([@blink1073](https://github.com/blink1073))
+
+## v0.24.7
+
+- Fix project URL in setup.py [#73](https://github.com/Calysto/octave_kernel/pull/73) ([@shoyer](https://github.com/shoyer))
+
+## v0.23.1
+
+- Fix readline behavior on Windows [#68](https://github.com/Calysto/octave_kernel/pull/68) ([@blink1073](https://github.com/blink1073))
+
+## v0.23.0
+
+- Fix indefinite pause on Windows [#67](https://github.com/Calysto/octave_kernel/pull/67) ([@blink1073](https://github.com/blink1073))
+- Override input again [#66](https://github.com/Calysto/octave_kernel/pull/66) ([@blink1073](https://github.com/blink1073))
+
+## v0.22.0
+
+- Disambiguate license [#64](https://github.com/Calysto/octave_kernel/pull/64) ([@blink1073](https://github.com/blink1073))
+- Fix interrupt and shutdown behavior [#63](https://github.com/Calysto/octave_kernel/pull/63) ([@blink1073](https://github.com/blink1073))
+
+## v0.21.0
+
+- Fix `imwrite` handling [#61](https://github.com/Calysto/octave_kernel/pull/61) ([@blink1073](https://github.com/blink1073))
+
+## v0.20.0
+
+- Add handling of input functions [#60](https://github.com/Calysto/octave_kernel/pull/60) ([@blink1073](https://github.com/blink1073))
+
+## v0.18.0
+
+- Handle `surf` vs `imshow` [#51](https://github.com/Calysto/octave_kernel/pull/51) ([@thomasjm](https://github.com/thomasjm))
+
+## v0.16.1
+
+- Add makefile [#43](https://github.com/Calysto/octave_kernel/pull/43) ([@blink1073](https://github.com/blink1073))
+- Plot images at their native resolution, without any resizing [#40](https://github.com/Calysto/octave_kernel/pull/40) ([@alexdu](https://github.com/alexdu))
+
+## v0.13
+
+- Also use `OCTAVE_EXECUTABLE` in banner property if available [#21](https://github.com/Calysto/octave_kernel/pull/21) ([@zertrin](https://github.com/zertrin))
+- Fixed deprecation warning in Jupyter 4 caused by importing from IPython.kernel [#16](https://github.com/Calysto/octave_kernel/pull/16) ([@akubera](https://github.com/akubera))
diff --git a/Dockerfile b/Dockerfile
index 5c4e83f..f36eb11 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,7 +19,7 @@ USER $NB_UID
 # Install extra packages
 RUN conda install --quiet --yes \
     'octave_kernel'  && \
-    conda clean -tipsy && \
+    conda clean -tipy && \
     fix-permissions $CONDA_DIR && \
     fix-permissions /home/$NB_USER
 
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 99ec43a..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,11 +0,0 @@
-include *.txt
-include *.rst
-include *.py
-include Makefile
-include octave_kernel/kernel.json
-recursive-include octave_kernel *.m
-recursive-include octave_kernel *.png
-prune .git
-prune docs/build
-prune dist
-prune build
diff --git a/Makefile b/Makefile
index 7056cee..6f79958 100644
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,27 @@
 # Note: This is meant for octave_kernel developer use only
-.PHONY: all clean test release docker-build docker-run
+.PHONY: data-files build install clean test docker-build docker-run
 
-export NAME=`python setup.py --name 2>/dev/null`
-export VERSION=`python setup.py --version 2>/dev/null`
 
-all: clean
-	python setup.py install
+data-files: clean
+	mkdir -p jupyter-data/share/jupyter/kernels/octave
+	cp octave_kernel/kernel.json jupyter-data/share/jupyter/kernels/octave
+	cp -r octave_kernel/images jupyter-data/share/jupyter/kernels/octave/images
+
+install: data-files
+	pip install -e ".[test]"
+
 
 clean:
+	rm -rf jupyter-data
 	rm -rf build
 	rm -rf dist
 
+
+build: data-files
+	pip install build twine
+	python -m build .
+	twine check --strict dist/*
+
 docker-build:
 	docker build --rm --force-rm -t calysto/octave-notebook:latest .
 
@@ -18,20 +29,7 @@ docker-run:
 	docker run -it --rm -p $(PORT):8888 calysto/octave-notebook
 
 test: clean
-	pip install jupyter_kernel_test nbconvert
-	python -V 2>&1 | grep "Python 3" && python test_octave_kernel.py || echo "Skipping unit test"
+	python test_octave_kernel.py
+	python -m octave_kernel.check
 	jupyter nbconvert --to notebook --execute --ExecutePreprocessor.kernel_name=octave --ExecutePreprocessor.timeout=60 --stdout octave_kernel.ipynb > /dev/null;
 	make clean
-
-release: test clean
-	pip install wheel
-	python setup.py register
-	python setup.py bdist_wheel --universal
-	python setup.py sdist
-	git commit -a -m "Release $(VERSION)"; true
-	git tag v$(VERSION)
-	git push origin --all
-	git push origin --tags
-	twine upload dist/*
-	printf '\nUpgrade octave_kernel-feedstock with release and sha256 sum:'
-	shasum -a 256 dist/*.tar.gz
diff --git a/README.rst b/README.rst
index eae1681..aa7f08e 100644
--- a/README.rst
+++ b/README.rst
@@ -2,14 +2,12 @@ An Octave kernel for Jupyter
 ============================
 
 .. image:: https://mybinder.org/badge_logo.svg
- :target: https://mybinder.org/v2/gh/Calysto/octave_kernel/master?urlpath=/lab/tree/octave_kernel.ipynb
+ :target: https://mybinder.org/v2/gh/Calysto/octave_kernel/main?urlpath=/lab/tree/octave_kernel.ipynb
 
 Prerequisites
 -------------
 `Jupyter Notebook <http://jupyter.readthedocs.org/en/latest/install.html>`_ and GNU Octave_.
 
-It is recommended to also install ``gnuplot`` for Octave to enable inline plotting.
-
 Installation
 ------------
 To install using pip::
@@ -24,7 +22,7 @@ To install using conda::
     conda install octave_kernel
     conda install texinfo # For the inline documentation (shift-tab) to appear.
 
-We require the ``octave-cli`` executable to run the kernel.
+We require the ``octave`` executable to run the kernel.
 Add that executable's directory to the ``PATH`` environment variable or use the
 ``OCTAVE_EXECUTABLE`` to point to the executable itself.
 Note that on Octave 5 on Windows, the executable is in ``"Octave-5.x.x.x\mingw64\bin"``.
@@ -77,7 +75,7 @@ init file is explicitly called after the kernel has set ``more off`` to prevent
 a lockup when the pager is invoked in ``~/.octaverc``.
 
 The inline toolkit is the ``graphics_toolkit`` used to generate plots for the inline
-backend.  It defaults to ``gnuplot``.  The different backend can be used for inline
+backend.  It defaults to ``qt``.  The different backend can be used for inline
 plotting either by using this configuration or by using the plot magic and putting the backend name after ``inline:``, e.g. ``plot -b inline:fltk``.
 
 
@@ -157,6 +155,15 @@ Specify a different format using the ``%plot -f <backend>`` magic or using a con
 On some systems, the default ``'png'`` produces a black plot.  On other systems ``'svg'`` produces a
 black plot.
 
+Local Installation
+------------------
+
+To install from a git checkout, run:
+
+.. code:: shell
+
+    make install
+
 
 .. _Octave: https://www.gnu.org/software/octave/download.html
-.. _online: http://nbviewer.ipython.org/github/Calysto/octave_kernel/blob/master/octave_kernel.ipynb
+.. _online: http://nbviewer.ipython.org/github/Calysto/octave_kernel/blob/main/octave_kernel.ipynb
diff --git a/RELEASE.md b/RELEASE.md
new file mode 100644
index 0000000..1c035ac
--- /dev/null
+++ b/RELEASE.md
@@ -0,0 +1,26 @@
+# Release Guide
+
+## Using `jupyter_releaser`
+
+The recommended way to make a release is to use [`jupyter_releaser`](https://github.com/jupyter-server/jupyter_releaser#checklist-for-adoption).
+
+## Manual Release
+
+- Update `CHANGELOG`
+
+- Run the following:
+
+```bash
+export VERSION=<version>
+pip install jupyter_releaser
+tbump --only-patch $VERSION
+git commit -a -m "Release $VERSION"
+git tag $VERSION; true;
+git push --all
+git push --tags
+rm -rf dist build
+make data-files
+python -m build .
+twine check dist/*
+twine upload dist/*
+```
diff --git a/debian/changelog b/debian/changelog
index 21c5761..0d75952 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+octave-kernel (0.35.1-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Wed, 31 Jan 2024 18:21:58 -0000
+
 octave-kernel (0.32.0-4) unstable; urgency=medium
 
   [ Debian Janitor ]
diff --git a/octave_kernel/__init__.py b/octave_kernel/__init__.py
index be3043d..5bc14e1 100644
--- a/octave_kernel/__init__.py
+++ b/octave_kernel/__init__.py
@@ -1,5 +1,4 @@
 """An Octave kernel for Jupyter"""
 
-__version__ = '0.32.0'
-
+from ._version import __version__
 from .kernel import OctaveKernel
diff --git a/octave_kernel/_version.py b/octave_kernel/_version.py
new file mode 100644
index 0000000..288ed76
--- /dev/null
+++ b/octave_kernel/_version.py
@@ -0,0 +1 @@
+__version__ = '0.35.1'
diff --git a/octave_kernel/check.py b/octave_kernel/check.py
index cbd5ac0..531fd58 100644
--- a/octave_kernel/check.py
+++ b/octave_kernel/check.py
@@ -15,6 +15,7 @@ if __name__ == "__main__":
         print('Octave connection established')
         print(o.banner)
         e = o.octave_engine
+        e._startup()
         toolkits = e.eval('available_graphics_toolkits', silent=True)[8:]
         print('Graphics toolkit: %s' % e._default_toolkit)
         print('Available toolkits: %s' % toolkits)
diff --git a/octave_kernel/kernel.py b/octave_kernel/kernel.py
index 13e0296..fb80b31 100644
--- a/octave_kernel/kernel.py
+++ b/octave_kernel/kernel.py
@@ -1,6 +1,7 @@
 from __future__ import print_function
 
 import atexit
+import base64
 import codecs
 import glob
 import json
@@ -19,7 +20,7 @@ from metakernel import MetaKernel, ProcessMetaKernel, REPLWrapper, u, MetaKernel
 from metakernel.pexpect import which
 from IPython.display import Image, SVG
 
-from . import __version__
+from ._version import __version__
 
 
 STDIN_PROMPT = '__stdin_prompt>'
@@ -36,6 +37,14 @@ HELP_LINKS = [
 
 ] + MetaKernel.help_links
 
+class PDF(object):
+    """Wrapper for PDF object for display.
+    """
+    def __init__(self, filename):
+        with open(filename, 'rb') as f:
+            data = f.read()
+            self._repr_pdf_ = base64.b64encode(data)
+
 
 def get_kernel_json():
     """Get the kernel json for the kernel.
@@ -52,12 +61,12 @@ def get_kernel_json():
 class OctaveKernel(ProcessMetaKernel):
     app_name = 'octave_kernel'
     implementation = 'Octave Kernel'
-    implementation_version = __version__,
+    implementation_version = __version__
     language = 'octave'
     help_links = HELP_LINKS
     kernel_json = Dict(get_kernel_json()).tag(config=True)
     cli_options = Unicode('').tag(config=True)
-    inline_toolkit = Unicode('gnuplot').tag(config=True)
+    inline_toolkit = Unicode('').tag(config=True)
 
     _octave_engine = None
     _language_version = None
@@ -88,6 +97,7 @@ class OctaveKernel(ProcessMetaKernel):
         if self._octave_engine:
             return self._octave_engine
         self._octave_engine = OctaveEngine(plot_settings=self.plot_settings,
+                                           defer_startup=True,
                                            error_handler=self.Error,
                                            stdin_handler=self.raw_input,
                                            stream_handler=self.Print,
@@ -106,6 +116,8 @@ class OctaveKernel(ProcessMetaKernel):
             self._octave_engine = None
             self.do_shutdown(True)
             return
+        if not self.octave_engine._has_startup:
+            self.octave_engine._startup()
         val = ProcessMetaKernel.do_execute_direct(self, code, silent=silent)
         if not silent:
             try:
@@ -161,7 +173,7 @@ class OctaveEngine(object):
     def __init__(self, error_handler=None, stream_handler=None,
                  line_handler=None,
                  stdin_handler=None, plot_settings=None,
-                 inline_toolkit='gnuplot',
+                 inline_toolkit=None, defer_startup = False,
                  cli_options='', logger=None):
         if not logger:
             logger = logging.getLogger(__name__)
@@ -175,7 +187,10 @@ class OctaveEngine(object):
         self.stream_handler = stream_handler
         self.stdin_handler = stdin_handler or sys.stdin
         self.line_handler = line_handler
-        self._startup(plot_settings)
+        self._has_startup = False
+        self._plot_settings = plot_settings
+        if not defer_startup:
+            self._startup()
         atexit.register(self._cleanup)
 
     @property
@@ -184,6 +199,9 @@ class OctaveEngine(object):
 
     @plot_settings.setter
     def plot_settings(self, settings):
+        if not self._has_startup:
+            self._default_toolkit = self.eval('graphics_toolkit', silent=True).split()[-1]
+
         settings = settings or dict(backend='inline')
         self._plot_settings = settings
 
@@ -203,8 +221,11 @@ class OctaveEngine(object):
         settings.setdefault('plot_dir', None)
 
         cmds = []
+
+        default_inline_toolkit = self.inline_toolkit or self._default_toolkit
+
         if settings['backend'] == 'inline':
-            cmds.append("graphics_toolkit('%s')" % self.inline_toolkit)
+            cmds.append("graphics_toolkit('%s')" % default_inline_toolkit)
             cmds.append("set(0, 'defaultfigurevisible', 'off');")
         elif settings['backend'].startswith('inline:'):
             backend = settings['backend'].replace('inline:', '')
@@ -264,6 +285,8 @@ class OctaveEngine(object):
             self.eval('drawnow("expose");')
             if not plot_dir:
                 return
+        if not self._has_startup:
+            self._startup()
         fmt = settings['format']
         res = settings['resolution']
         wid = settings['width']
@@ -305,6 +328,8 @@ class OctaveEngine(object):
             try:
                 if fname.lower().endswith('.svg'):
                     im = self._handle_svg(filename)
+                elif fname.lower().endswith('.pdf'):
+                    im = PDF(filename)
                 else:
                     im = Image(filename)
                 images.append(im)
@@ -317,14 +342,15 @@ class OctaveEngine(object):
             shutil.rmtree(plot_dir, True)
         return images
 
-    def _startup(self, plot_settings):
+    def _startup(self):
+        self._has_startup = True
         cwd = os.getcwd().replace(os.path.sep, '/')
         self._default_toolkit = self.eval('graphics_toolkit', silent=True).split()[-1]
         cmd = 'more off; source ~/.octaverc; cd("%s");%s'
         self.eval(cmd % (cwd, self.repl.prompt_change_cmd), silent=True)
         here = os.path.realpath(os.path.dirname(__file__))
         self.eval('addpath("%s")' % here.replace(os.path.sep, '/'))
-        self.plot_settings = plot_settings
+        self.plot_settings = self._plot_settings
 
     def _handle_svg(self, filename):
         """
@@ -372,7 +398,7 @@ class OctaveEngine(object):
 
     def _create_repl(self):
         cmd = self.executable
-        if 'octave-cli' not in cmd:
+        if 'octave' not in cmd:
             version_cmd = [self.executable, '--version']
             version = subprocess.check_output(version_cmd).decode('utf-8')
             if 'version 4' in version:
@@ -452,12 +478,12 @@ class OctaveEngine(object):
             fullpath = which(executable)
             if 'snap' not in fullpath:
                 executable = fullpath
-                if 'octave-cli' not in executable:
-                    raise OSError('OCTAVE_EXECUTABLE does not point to an octave-cli file, please see README')
+                if 'octave' not in executable:
+                    raise OSError('OCTAVE_EXECUTABLE does not point to an octave file, please see README')
         else:
-            executable = which('octave-cli')
+            executable = which('octave')
             if not executable:
-                raise OSError('octave-cli not found, please see README')
+                raise OSError('octave not found, please see README')
         return executable.replace(os.path.sep, '/')
 
     def _cleanup(self):
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..c3ce3a5
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,71 @@
+[build-system]
+requires = ["hatchling >=1.5"]
+build-backend = "hatchling.build"
+
+[project]
+name = "octave_kernel"
+description = "'A Jupyter kernel for Octave.'"
+license = {file = "LICENSE.txt"}
+authors = [{name = "'Steven Silvester'", email = "steven.silvester@ieee.org"}]
+classifiers = [
+    "Intended Audience :: Science/Research",
+    "License :: OSI Approved :: BSD License",
+    "Operating System :: OS Independent",
+    "Programming Language :: Python",
+    "Programming Language :: Python :: 3",
+    "Topic :: Scientific/Engineering",
+    "Topic :: Software Development",
+    "Topic :: System :: Shells",
+]
+urls = {Homepage = "http://github.com/Calysto/octave_kernel"}
+requires-python = ">=3.7"
+dependencies = [
+    "metakernel >=0.24.0",
+    "jupyter_client >=4.3.0",
+    "ipykernel",
+]
+dynamic = ["version"]
+
+[project.readme]
+file = "README.rst"
+content-type = "text/x-rst"
+
+[project.optional-dependencies]
+test = ["pytest", "nbconvert", "jupyter_kernel_test", "nbconvert"]
+
+[tool.hatch.build.targets.wheel.shared-data]
+"jupyter-data/share" = "share"
+
+[tool.hatch.build.targets.sdist]
+artifacts = ["jupyter-data"]
+include = [
+    "/jupyter-data",
+    "/octave_kernel",
+    "/*.md",
+    "/*.ipynb",
+    "/*.py"
+]
+
+[tool.hatch.version]
+path = "octave_kernel/_version.py"
+source = "code"
+
+[tool.jupyter-releaser]
+skip = ["check-links"]
+
+[tool.jupyter-releaser.hooks]
+after-prep-git = ["make data-files"]
+
+[tool.tbump.version]
+current = "0.35.1"
+regex = '''
+  (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
+  ((?P<channel>a|b|rc|.dev)(?P<release>\d+))?
+'''
+
+[tool.tbump.git]
+message_template = "Bump to {new_version}"
+tag_template = "v{new_version}"
+
+[[tool.tbump.file]]
+src = "octave_kernel/_version.py"
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 498ec14..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[metadata]
-license_file = LICENSE.txt
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 5313a98..0000000
--- a/setup.py
+++ /dev/null
@@ -1,66 +0,0 @@
-"""Setup script for octave_kernel package.
-"""
-import glob
-
-DISTNAME = 'octave_kernel'
-DESCRIPTION = 'A Jupyter kernel for Octave.'
-LONG_DESCRIPTION = open('README.rst', 'rb').read().decode('utf-8')
-MAINTAINER = 'Steven Silvester'
-MAINTAINER_EMAIL = 'steven.silvester@ieee.org'
-URL = 'http://github.com/Calysto/octave_kernel'
-LICENSE = 'BSD'
-REQUIRES = ["metakernel (>=0.24.0)", "jupyter_client (>=4.3.0)", "ipykernel"]
-INSTALL_REQUIRES = ["metakernel >=0.24.0", "jupyter_client >=4.3.0", "ipykernel"]
-PACKAGES = [DISTNAME]
-PACKAGE_DATA = {
-    DISTNAME: ['*.m'] + glob.glob('%s/**/*.*' % DISTNAME)
-}
-DATA_FILES = [
-    ('share/jupyter/kernels/octave', [
-        '%s/kernel.json' % DISTNAME
-     ] + glob.glob('%s/images/*.png' % DISTNAME)
-    )
-]
-CLASSIFIERS = """\
-Intended Audience :: Science/Research
-License :: OSI Approved :: BSD License
-Operating System :: OS Independent
-Programming Language :: Python
-Programming Language :: Python :: 2.7
-Programming Language :: Python :: 3.3
-Programming Language :: Python :: 3.4
-Topic :: Scientific/Engineering
-Topic :: Software Development
-Topic :: System :: Shells
-"""
-
-from setuptools import setup
-
-with open('octave_kernel/__init__.py', 'rb') as fid:
-    for line in fid:
-        line = line.decode('utf-8')
-        if line.startswith('__version__'):
-            version = line.strip().split()[-1][1:-1]
-            break
-
-
-setup(
-    name=DISTNAME,
-    version=version,
-    maintainer=MAINTAINER,
-    maintainer_email=MAINTAINER_EMAIL,
-    packages=PACKAGES,
-    package_data=PACKAGE_DATA,
-    include_package_data=True,
-    data_files=DATA_FILES,
-    url=URL,
-    download_url=URL,
-    license=LICENSE,
-    platforms=["Any"],
-    description=DESCRIPTION,
-    long_description=LONG_DESCRIPTION,
-    long_description_content_type='text/x-rst',
-    classifiers=list(filter(None, CLASSIFIERS.split('\n'))),
-    requires=REQUIRES,
-    install_requires=INSTALL_REQUIRES
- )

More details

Full run details

Historical runs