Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jupyter/jupyter_client
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v7.1.0
Choose a base ref
...
head repository: jupyter/jupyter_client
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4428715b65741ddccac9305d318d4ace08fa711a
Choose a head ref
Loading
36 changes: 3 additions & 33 deletions .github/workflows/check-release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Check Release
on:
push:
branches: ["master"]
branches: ["main"]
pull_request:
branches: ["*"]

@@ -17,38 +17,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Python
uses: actions/setup-python@v2
with:
python-version: 3.9
architecture: "x64"
- name: Install node
uses: actions/setup-node@v2
with:
node-version: "14.x"
- name: Get pip cache dir
id: pip-cache
run: |
echo "::set-output name=dir::$(pip cache dir)"
- name: Cache pip
uses: actions/cache@v1
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('setup.cfg') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-pip-
- name: Cache checked links
if: ${{ matrix.group == 'link_check' }}
uses: actions/cache@v2
with:
path: ~/.cache/pytest-link-check
key: ${{ runner.os }}-linkcheck-${{ hashFiles('**/*.md', '**/*.rst') }}-md-links
restore-keys: |
${{ runner.os }}-linkcheck-
- name: Upgrade packaging dependencies
run: |
pip install --upgrade pip setuptools wheel --user
- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- name: Install Dependencies
run: |
pip install -e .
89 changes: 50 additions & 39 deletions .github/workflows/downstream.yml
Original file line number Diff line number Diff line change
@@ -9,49 +9,60 @@ on:
jobs:
tests:
runs-on: ubuntu-latest

strategy:
matrix:
python-version: ["3.9"]
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Set up Python 3.9
uses: actions/setup-python@v2
- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Test IPykernel
uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
with:
python-version: 3.9
package_name: ipykernel
package_spec: "pyqt5 ipykernel[test]"

- name: Test NBClient
uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
with:
package_name: nbclient
env_values: IPYKERNEL_CELL_NAME=\<IPY-INPUT\>

# Note: Currently fails
# - name: Test QtConsole
# uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
# with:
# package_name: qtconsole

- name: Install dependencies
run: |
pip install --upgrade pip
pip install pyqt5 pytest
pip install ipykernel[test]
pip install --pre -U --upgrade-strategy=only-if-needed ipykernel
pip install qtconsole[test]
pip install --pre -U --upgrade-strategy=only-if-needed qtconsole
pip install nbclient[test]
pip install --pre -U --upgrade-strategy=only-if-needed nbclient
pip install nbconvert[test]
pip install --pre -U --upgrade-strategy=only-if-needed nbconvert
pip install jupyter_server[test]
pip install --pre -U --upgrade-strategy=only-if-needed jupyter_server
pip install . --force-reinstall
pip freeze
python -c 'import jupyter_client; print("jupyter_client", jupyter_client.__version__)'
- name: Test ipykernel
if: ${{ always() }}
run: pytest --pyargs ipykernel
- name: Test nbclient
if: ${{ always() }}
run: IPYKERNEL_CELL_NAME="<IPY-INPUT>" pytest --pyargs nbclient
- name: Test nbconvert
if: ${{ always() }}
run: pytest --pyargs nbconvert
#qtconsole tests disabled because of a core dump
#- name: Test qtconsole
# if: ${{ always() }}
# run: pytest --pyargs qtconsole
#jupyter_server tests disabled because pip package doesn't allow for testing
#see https://github.com/jupyter-server/jupyter_server/issues/563
#- name: Test jupyter_server
# if: ${{ always() }}
# run: pytest --pyargs jupyter_server
uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
with:
package_name: nbconvert

- name: Test jupyter_server
uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
with:
package_name: jupyter_server

# Test using jupyter_kernel_test

- name: Setup conda ${{ matrix.python-version }}
uses: conda-incubator/setup-miniconda@v2
with:
auto-update-conda: true
activate-environment: jupyter_kernel_test
miniforge-variant: Mambaforge
python-version: ${{ matrix.python-version }}

- name: Test jupyter_kernel_test
shell: bash -l {0}
run: |
git clone https://github.com/jupyter/jupyter_kernel_test.git
cd jupyter_kernel_test
conda env update --name jupyter_kernel_test --file environment.yml
conda install -c conda-forge xeus-cling
pip install -e ".[test]"
python -m unittest -v
33 changes: 4 additions & 29 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -69,7 +69,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.6, 3.7, 3.8, 3.9]
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]

env:
OS: ${{ matrix.os }}
@@ -78,33 +78,8 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Update pip
run: |
pip install --upgrade pip
pip install --upgrade wheel setuptools
- name: Get pip cache dir
id: pip-cache
run: |
echo "::set-output name=dir::$(pip cache dir)"
- name: Cache pip
uses: actions/cache@v2
with:
path: |
${{ steps.pip-cache.outputs.dir }}
.mypy_cache
key: ${{ runner.os }}-python-${{ matrix.python-version }}-pip-${{ hashFiles('**/requirements*.txt') }}-git-${{ github.sha }}
restore-keys: |
${{ runner.os }}-python-${{ matrix.python-version }}-pip-${{ hashFiles('**/requirements*.txt') }}
${{ runner.os }}-python-${{ matrix.python-version }}-pip-
${{ runner.os }}-python
${{ runner.os }}-
- name: Base Setup
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1

- name: Install dependencies
run: |
@@ -114,7 +89,7 @@ jobs:
- name: Check types
run: mypy jupyter_client --exclude '\/tests|kernelspecapp|ioloop|runapp' --install-types --non-interactive

- name: Run the tests
- name: Run the tests with coverage
run: pytest --cov jupyter_client -v jupyter_client

- name: Build the docs
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -17,6 +17,8 @@ absolute.json
htmlcov/
docs/changelog.md
.mypy_cache
Pipfile
Pipfle.lock

# Sphinx documentation
_build
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ and download the dependencies of code and test suite by executing:

```bash
cd /my/projects/jupyter_client/
pip install -e .[test]
pip install -e ".[test]"
pytest
```

@@ -41,7 +41,7 @@ The documentation of Jupyter Client is generated from the files in `docs/` using
For a minimal Sphinx installation to process the Jupyter Client docs, execute:

```bash
pip install .[doc]
pip install ".[doc]"
```

The following commands build the documentation in HTML format and check for broken links:
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ with Jupyter kernels.
kernels
wrapperkernels
provisioning
pending-kernels

.. toctree::
:maxdepth: 2
108 changes: 108 additions & 0 deletions docs/messaging.rst
Original file line number Diff line number Diff line change
@@ -1667,6 +1667,114 @@ handlers should set the parent header and publish status busy / idle,
just like an execute request.


Changelog
=========

5.5 (draft)
-----------

- Added ``debug_request/reply`` messages
- Added ``debug_event`` message

5.4
---

- Sending a ``shutdown_request`` message on the ``shell`` channel is deprecated.
It should be sent on the control channel.

5.3
---

- Kernels can now opt to be interrupted by a message sent on the control channel
instead of a system signal. See :ref:`kernelspecs` and :ref:`msging_interrupt`.

5.2
---

- Resolve ambiguity of ``cursor_pos`` field in the presence
of unicode surrogate pairs.
In 5.2, cursor_pos **must be** the actual encoding-independent offset in unicode codepoints.

.. seealso::

:ref:`cursor_pos_unicode_note`

5.1
---

- ``date`` in the header was accidentally omitted from the spec prior to 5.1,
but it has always been in the canonical implementation,
so implementers are strongly encouraged to include it.
It is mandatory in 5.1.
- ``status='abort'`` in replies has not proved useful, and is considered deprecated.
Kernels should send ``status='error'`` instead.
- ``comm_info_request/reply`` added
- ``connect_request/reply`` have not proved useful, and are considered deprecated.
Kernels are not expected to implement handlers for this message.
- new ``transient`` field in ``display_data``
- new ``update_display_data`` message

5.0
---

General changes:

- ``version`` key added to message headers
- busy and idle status messages should be sent before/after handling every request,
not just execution

Message renames to remove Python-specific-ness:

- ``pyin`` message renamed to ``execute_input``
- ``pyerr`` renamed to ``error``
- ``object_info_request/reply`` messages renamed to ``inspect_request/reply``

Kernel info:

- versions changed from lists of integers to strings
- ``ipython_version`` is removed
- ``language_info``, ``implementation``, ``implementation_version``, ``banner``
and ``help_links`` keys are added.
- ``language_version`` is moved to ``language_info.version``
- ``language`` is moved to ``language_info.name``

Execution:

- ``user_variables`` is removed from ``execute_request/reply`` because it is redundant with ``user_expressions``
- ``password`` key added to ``input_request``

Output:

- ``data`` key in stream messages renamed to ``text`` for consistency with the notebook format.
- ``application/json`` in mimebundles should be unpacked JSON data,
not a double-serialized JSON string.

Inspection:

- ``name`` key in ``inspect_request`` replaced with ``code`` and ``cursor_pos``,
moving the lexing responsibility to the kernel.
- ``object_info_reply`` is now a mimebundle,
allowing formatting decisions to be made by the kernel.

Completion:

- ``complete_request``: ``line``, ``block``, and ``text`` keys are removed in favor of a single ``code`` for context.
Lexing is up to the kernel.
- ``complete_reply``:
- ``matched_text`` is removed in favor of ``cursor_start`` and ``cursor_end``.
- ``metadata`` is added for extended information.
- new ``is_complete_request`` and ``is_complete_reply`` messages

4.1
---

- ``comm_open/close/msg`` messages added
- ``clear_output``: ``stdout``, ``stderr``, and ``display`` boolean keys for selective clearing are removed,
and ``wait`` is added.
The selective clearing keys are ignored in v4 and the default behavior remains the same,
so v4 ``clear_output`` messages will be safely handled by a v4.1 frontend.


Notes
=====

36 changes: 36 additions & 0 deletions docs/pending-kernels.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Pending Kernels
===============

*Added in 7.1.0*

In scenarios where an kernel takes a long time to start (e.g. kernels running remotely), it can be advantageous to immediately return the kernel's model and ID from key methods like ``.start_kernel()`` and ``.shutdown_kernel()``. The kernel will continue its task without blocking other managerial actions.

This intermediate state is called a **"pending kernel"**.

How they work
-------------

When ``.start_kernel()`` or ``.shutdown_kernel()`` is called, a ``Future`` is created under the ``KernelManager.ready`` property. This property can be awaited anytime to ensure that the kernel moves out of its pending state, e.g.:

.. code-block:: python
# await a Kernel Manager's `.ready` property to
# block further action until the kernel is out
# of its pending state.
await kernel_manager.ready
Once the kernel is finished pending, ``.ready.done()`` will be ``True`` and either 1) ``.ready.result()`` will return ``None`` or 2) ``.ready.exception()`` will return a raised exception

Using pending kernels
---------------------

The most common way to interact with pending kernels is through the ``MultiKernelManager``—the object that manages a collection of kernels—by setting its ``use_pending_kernels`` trait to ``True``. Pending kernels are "opt-in"; they are not used by default in the ``MultiKernelManager``.

When ``use_pending_kernels`` is ``True``, the following changes are made to the ``MultiKernelManager``:

1. ``start_kernel`` and ``stop_kernel`` return immediately while running the pending task in a background thread.
2. The following methods raise a ``RuntimeError`` if a kernel is pending:
* ``restart_kernel``
* ``interrupt_kernel``
* ``shutdown_kernel``
3. ``shutdown_all`` will wait for all pending kernels to become ready before attempting to shut them down.
2 changes: 1 addition & 1 deletion docs/provisioning.rst
Original file line number Diff line number Diff line change
@@ -153,7 +153,7 @@ in the role meant for this kernel by calling a method implemented within *this*
raise PermissionError(f"User is not in role {self.role} and "
f"cannot launch this kernel.")
return super().pre_launch(**kwargs)
return await super().pre_launch(**kwargs)
It is important to note *when* it's necessary to call the superclass in
a given method - since the operations it performs may be critical to the
Loading