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: v8.0.1
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: v8.0.2
Choose a head ref
  • 4 commits
  • 29 files changed
  • 2 contributors

Commits on Jan 28, 2023

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    fac9c3a View commit details

Commits on Jan 30, 2023

  1. Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    666eab0 View commit details
  2. Adopt more ruff rules (#924)

    * more linting
    
    * typing
    
    * fix bug
    
    * fix json util test
    blink1073 authored Jan 30, 2023
    Copy the full SHA
    717d36e View commit details
  3. Publish 8.0.2

    SHA256 hashes:
    
    jupyter_client-8.0.2-py3-none-any.whl: c53731eb590b68839b0ce04bf46ff8c4f03278f5d9fe5c3b0f268a57cc2bd97e
    
    jupyter_client-8.0.2.tar.gz: 47ac9f586dbcff4d79387ec264faf0fdeb5f14845fa7345fd7d1e378f8096011
    blink1073 committed Jan 30, 2023
    Copy the full SHA
    5a12a38 View commit details
27 changes: 27 additions & 0 deletions .github/workflows/downstream.yml
Original file line number Diff line number Diff line change
@@ -31,6 +31,16 @@ jobs:
package_name: nbclient
env_values: IPYKERNEL_CELL_NAME=\<IPY-INPUT\>

papermill:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v3
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- uses: jupyterlab/maintainer-tools/.github/actions/downstream-test@v1
with:
package_name: papermill

nbconvert:
runs-on: ubuntu-latest
timeout-minutes: 15
@@ -115,3 +125,20 @@ jobs:
run: |
cd ${GITHUB_WORKSPACE}/../qtconsole
xvfb-run --auto-servernum ${pythonLocation}/bin/python -m pytest -x -vv -s --full-trace --color=yes qtconsole
downstreams_check: # This job does nothing and is only used for the branch protection
if: always()
needs:
- ipykernel
- nbclient
- papermill
- nbconvert
- jupyter_server
- jupyter_kernel_test
- qtconsole
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) }}
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ repos:
- id: black

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.221
rev: v0.0.236
hooks:
- id: ruff
args: ["--fix"]
23 changes: 21 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,27 @@

<!-- <START NEW CHANGELOG ENTRY> -->

## 8.0.2

([Full Changelog](https://github.com/jupyter/jupyter_client/compare/v8.0.1...717d36edcd9ce595f727d8b5a27e270c2a6e2c46))

### Bugs fixed

- Add papermill downstream check and fix kernel client replies [#925](https://github.com/jupyter/jupyter_client/pull/925) ([@blink1073](https://github.com/blink1073))

### Maintenance and upkeep improvements

- Adopt more ruff rules [#924](https://github.com/jupyter/jupyter_client/pull/924) ([@blink1073](https://github.com/blink1073))
- Prefer print in kernelspecapp [#923](https://github.com/jupyter/jupyter_client/pull/923) ([@blink1073](https://github.com/blink1073))

### Contributors to this release

([GitHub contributors page for this release](https://github.com/jupyter/jupyter_client/graphs/contributors?from=2023-01-26&to=2023-01-30&type=c))

[@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_client+involves%3Ablink1073+updated%3A2023-01-26..2023-01-30&type=Issues)

<!-- <END NEW CHANGELOG ENTRY> -->

## 8.0.1

([Full Changelog](https://github.com/jupyter/jupyter_client/compare/v8.0.0...dc6113c360e05122430b8e130374e9f4e4b701d7))
@@ -16,8 +37,6 @@

[@blink1073](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_client+involves%3Ablink1073+updated%3A2023-01-26..2023-01-26&type=Issues)

<!-- <END NEW CHANGELOG ENTRY> -->

## 8.0.0

([Full Changelog](https://github.com/jupyter/jupyter_client/compare/v7.3.5...760a7835d8b20a9daea3737759b1751d5e55dad8))
2 changes: 1 addition & 1 deletion jupyter_client/_version.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
import re
from typing import List, Union

__version__ = "8.0.1"
__version__ = "8.0.2"

# Build up version_info tuple for backwards compatibility
pattern = r'(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)'
5 changes: 1 addition & 4 deletions jupyter_client/asynchronous/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Implements an async kernel client"""
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
import asyncio

import zmq.asyncio
from traitlets import Instance, Type
@@ -17,10 +16,8 @@ def _(self, *args, **kwargs):
reply = kwargs.pop("reply", False)
timeout = kwargs.pop("timeout", None)
msg_id = meth(self, *args, **kwargs)
fut: asyncio.Future = asyncio.Future()
fut.set_result(msg_id)
if not reply:
return fut
return msg_id
return self._recv_reply(msg_id, timeout=timeout, channel=channel)

return _
5 changes: 3 additions & 2 deletions jupyter_client/channels.py
Original file line number Diff line number Diff line change
@@ -159,7 +159,7 @@ def unpause(self) -> None:

def is_beating(self) -> bool:
"""Is the heartbeat running and responsive (and not paused)."""
if self.is_alive() and not self._pause and self._beating:
if self.is_alive() and not self._pause and self._beating: # noqa
return True
else:
return False
@@ -290,7 +290,8 @@ def __init__(self, socket: zmq.asyncio.Socket, session: Session, loop: t.Any = N
Unused here, for other implementations
"""
if not isinstance(socket, zmq.asyncio.Socket):
raise ValueError('Socket must be asyncio')
msg = 'Socket must be asyncio'
raise ValueError(msg)
super().__init__(socket, session)

async def _recv(self, **kwargs: t.Any) -> t.Dict[str, t.Any]: # type:ignore[override]
54 changes: 26 additions & 28 deletions jupyter_client/client.py
Original file line number Diff line number Diff line change
@@ -195,7 +195,8 @@ async def _async_wait_for_ready(self, timeout: t.Optional[float] = None) -> None
break

if not await self._async_is_alive():
raise RuntimeError("Kernel died before replying to kernel_info")
msg = "Kernel died before replying to kernel_info"
raise RuntimeError(msg)

# Check if current time is ready check time plus timeout
if time.time() > abs_timeout:
@@ -223,7 +224,8 @@ async def _async_recv_reply(
else:
reply = await self._async_get_shell_msg(timeout=timeout)
except Empty as e:
raise TimeoutError("Timeout waiting for reply") from e
msg = "Timeout waiting for reply"
raise TimeoutError(msg) from e
if reply["parent_header"].get("msg_id") != msg_id:
# not my reply, someone may have forgotten to retrieve theirs
continue
@@ -232,13 +234,10 @@ async def _async_recv_reply(
async def _stdin_hook_default(self, msg: t.Dict[str, t.Any]) -> None:
"""Handle an input request"""
content = msg["content"]
if content.get("password", False):
prompt = getpass
else:
prompt = input # type: ignore
prompt = getpass if content.get("password", False) else input

try:
raw_data = prompt(content["prompt"])
raw_data = prompt(content["prompt"]) # type:ignore[operator]
except EOFError:
# turn EOFError into EOF character
raw_data = "\x04"
@@ -475,11 +474,13 @@ async def _async_execute_interactive(
The reply message for this request
"""
if not self.iopub_channel.is_alive():
raise RuntimeError("IOPub channel must be running to receive output")
emsg = "IOPub channel must be running to receive output"
raise RuntimeError(emsg)
if allow_stdin is None:
allow_stdin = self.allow_stdin
if allow_stdin and not self.stdin_channel.is_alive():
raise RuntimeError("stdin channel must be running to allow input")
emsg = "stdin channel must be running to allow input"
raise RuntimeError(emsg)
msg_id = await ensure_async(
self.execute(
code,
@@ -492,20 +493,19 @@ async def _async_execute_interactive(
)
if stdin_hook is None:
stdin_hook = self._stdin_hook_default
if output_hook is None:
# detect IPython kernel
if "IPython" in sys.modules:
from IPython import get_ipython

ip = get_ipython()
in_kernel = getattr(ip, "kernel", False)
if in_kernel:
output_hook = partial(
self._output_hook_kernel,
ip.display_pub.session,
ip.display_pub.pub_socket,
ip.display_pub.parent_header,
)
# detect IPython kernel
if output_hook is None and "IPython" in sys.modules:
from IPython import get_ipython

ip = get_ipython()
in_kernel = getattr(ip, "kernel", False)
if in_kernel:
output_hook = partial(
self._output_hook_kernel,
ip.display_pub.session,
ip.display_pub.pub_socket,
ip.display_pub.parent_header,
)
if output_hook is None:
# default: redisplay plain-text outputs
output_hook = self._output_hook_default
@@ -532,7 +532,8 @@ async def _async_execute_interactive(
timeout_ms = int(1000 * timeout)
events = dict(poller.poll(timeout_ms))
if not events:
raise TimeoutError("Timeout waiting for output")
emsg = "Timeout waiting for output"
raise TimeoutError(emsg)
if stdin_socket in events:
req = await ensure_async(self.stdin_channel.get_msg(timeout=0))
res = stdin_hook(req)
@@ -747,10 +748,7 @@ def comm_info(self, target_name: t.Optional[str] = None) -> str:
-------
The msg_id of the message sent
"""
if target_name is None:
content = {}
else:
content = {"target_name": target_name}
content = {} if target_name is None else {"target_name": target_name}
msg = self.session.msg("comm_info_request", content)
self.shell_channel.send(msg)
return msg["header"]["msg_id"]
11 changes: 5 additions & 6 deletions jupyter_client/connect.py
Original file line number Diff line number Diff line change
@@ -218,7 +218,8 @@ def find_connection_file(

matches = [os.path.abspath(m) for m in matches]
if not matches:
raise OSError(f"Could not find {filename!r} in {path!r}")
msg = f"Could not find {filename!r} in {path!r}"
raise OSError(msg)
elif len(matches) == 1:
return matches[0]
else:
@@ -592,10 +593,11 @@ def _reconcile_connection_info(self, info: KernelConnectionInfo) -> None:
# Ensure what is in KernelManager is what we expect.
km_info = self.get_connection_info()
if not self._equal_connections(info, km_info):
raise ValueError(
msg = (
"KernelManager's connection information already exists and does not match "
"the expected values returned from provisioner!"
)
raise ValueError(msg)

@staticmethod
def _equal_connections(conn1: KernelConnectionInfo, conn2: KernelConnectionInfo) -> bool:
@@ -613,10 +615,7 @@ def _equal_connections(conn1: KernelConnectionInfo, conn2: KernelConnectionInfo)
"signature_scheme",
]

for key in pertinent_keys:
if conn1.get(key) != conn2.get(key):
return False
return True
return all(conn1.get(key) == conn2.get(key) for key in pertinent_keys)

# --------------------------------------------------------------------------
# Creating connected sockets
10 changes: 4 additions & 6 deletions jupyter_client/ioloop/manager.py
Original file line number Diff line number Diff line change
@@ -63,9 +63,8 @@ def start_restarter(self):

def stop_restarter(self):
"""Stop the restarter."""
if self.autorestart:
if self._restarter is not None:
self._restarter.stop()
if self.autorestart and self._restarter is not None:
self._restarter.stop()

connect_shell = as_zmqstream(KernelManager.connect_shell)
connect_control = as_zmqstream(KernelManager.connect_control)
@@ -107,9 +106,8 @@ def start_restarter(self):

def stop_restarter(self):
"""Stop the restarter."""
if self.autorestart:
if self._restarter is not None:
self._restarter.stop()
if self.autorestart and self._restarter is not None:
self._restarter.stop()

connect_shell = as_zmqstream(AsyncKernelManager.connect_shell)
connect_control = as_zmqstream(AsyncKernelManager.connect_control)
5 changes: 3 additions & 2 deletions jupyter_client/jsonutil.py
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@

# holy crap, strptime is not threadsafe.
# Calling it once at import seems to help.
datetime.strptime("1", "%d")
datetime.strptime("1", "%d") # noqa

# -----------------------------------------------------------------------------
# Classes and functions
@@ -174,10 +174,11 @@ def json_clean(obj):
nkeys = len(obj)
nkeys_collapsed = len(set(map(str, obj)))
if nkeys != nkeys_collapsed:
raise ValueError(
msg = (
'dict cannot be safely converted to JSON: '
'key collision would lead to dropped values'
)
raise ValueError(msg)
# If all OK, proceed by making the new dict that will be json-safe
out = {}
for k, v in obj.items():
6 changes: 4 additions & 2 deletions jupyter_client/kernelspec.py
Original file line number Diff line number Diff line change
@@ -368,10 +368,12 @@ def install_kernel_spec(
kernel_name = os.path.basename(source_dir)
kernel_name = kernel_name.lower()
if not _is_valid_kernel_name(kernel_name):
raise ValueError(f"Invalid kernel name {kernel_name!r}. {_kernel_name_description}")
msg = f"Invalid kernel name {kernel_name!r}. {_kernel_name_description}"
raise ValueError(msg)

if user and prefix:
raise ValueError("Can't specify both user and prefix. Please choose one or the other.")
msg = "Can't specify both user and prefix. Please choose one or the other."
raise ValueError(msg)

if replace is not None:
warnings.warn(
Loading