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.3
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: e3ac7a69355dd1af66038eda767e51e92ef034fb
Choose a head ref
  • 3 commits
  • 8 files changed
  • 5 contributors

Commits on Feb 24, 2023

  1. Adds spec for the copyToGlobals request (#932)

    Co-authored-by: Steven Silvester <steven.silvester@ieee.org>
    brichet and blink1073 authored Feb 24, 2023
    Copy the full SHA
    df84040 View commit details

Commits on Mar 9, 2023

  1. [pre-commit.ci] pre-commit autoupdate (#935)

    Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
    Co-authored-by: Steven Silvester <steven.silvester@ieee.org>
    pre-commit-ci[bot] and blink1073 authored Mar 9, 2023
    Copy the full SHA
    f6a03ac View commit details

Commits on Mar 19, 2023

  1. ThreadedZMQStream: close stream before socket (#936)

    Co-authored-by: Carlos Cordoba <ccordoba12@gmail.com>
    Co-authored-by: Steven Silvester <steven.silvester@ieee.org>
    3 people authored Mar 19, 2023
    Copy the full SHA
    e3ac7a6 View commit details
Showing with 102 additions and 26 deletions.
  1. +1 −1 .pre-commit-config.yaml
  2. +55 −6 docs/messaging.rst
  3. +9 −9 jupyter_client/__init__.py
  4. +5 −5 jupyter_client/session.py
  5. +27 −2 jupyter_client/threaded.py
  6. +1 −1 jupyter_client/utils.py
  7. +3 −1 pyproject.toml
  8. +1 −1 tests/test_jsonutil.py
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.243
rev: v0.0.254
hooks:
- id: ruff
args: ["--fix"]
61 changes: 55 additions & 6 deletions docs/messaging.rst
Original file line number Diff line number Diff line change
@@ -1131,9 +1131,14 @@ Additions to the DAP

The Jupyter debugger protocol makes several additions to the DAP:

- the `dumpCell` request and response messages
- the `debugInfo` request and response messages
- the `inspectVariables` request and response messages
- the `dumpCell`_ request and response messages
- the `debugInfo`_ request and response messages
- the `inspectVariables`_ request and response messages
- the `richInspectVariables`_ request and response messages
- the `copyToGlobals`_ request and response messages

dumpCell
########

In order to support the debugging of notebook cells and of Jupyter consoles,
which are not based on source files, we need a message to submit code to the
@@ -1159,6 +1164,9 @@ debugger to which breakpoints can be added.
}
}

debugInfo
#########

In order to support page reloading, or a client connecting at a later stage,
Jupyter kernels must store the state of the debugger (such as breakpoints,
whether the debugger is currently stopped). The `debugInfo` request is a DAP
@@ -1196,6 +1204,9 @@ whether the debugger is currently stopped). The `debugInfo` request is a DAP

The `source_breakpoint` schema is specified by the Debug Adapter Protocol.

inspectVariables
################

The `inspectVariables` is meant to retrieve the values of all the variables
that have been defined in the kernel. It is a DAP `Request` with no extra
argument.
@@ -1224,10 +1235,13 @@ argument.
}
}

The ``richInspectVariables`` request allows to get the rich representation of a
richInspectVariables
####################

The `richInspectVariables` request allows to get the rich representation of a
variable that has been defined in the kernel.

Content of the ``richInspectVariables`` request::
Content of the `richInspectVariables` request::

{
'type' : 'request',
@@ -1239,7 +1253,7 @@ variable that has been defined in the kernel.
}
}

Content of the ``richInspectVariables`` response::
Content of the `richInspectVariables` response::

{
'type' : 'response',
@@ -1251,6 +1265,41 @@ variable that has been defined in the kernel.
}
}

copyToGlobals
#############

The `copyToGlobals` request allows to copy a variable from the local variable panel
of the debugger to the `global`` scope to inspect it after debug session.

Content of the `copyToGlobals` request::

{
'type': 'request',
'command': 'copyToGlobals',
'arguments': {
# the variable to copy from the frame corresponding to `srcFrameId`
'srcVariableName': str,
'srcFrameId': int,
# the copied variable name in the global scope
'dstVariableName': str
}
}

Content of the `copyToGlobals` response::

{
'type': 'response',
'success': bool,
'command': 'setExpression',
'body': {
# string representation of the copied variable
'value': str,
# type of the copied variable
'type': str,
'variablesReference': int
}
}

.. versionadded:: 5.5

Messages on the IOPub (PUB/SUB) channel
18 changes: 9 additions & 9 deletions jupyter_client/__init__.py
Original file line number Diff line number Diff line change
@@ -6,17 +6,17 @@

try:
from .asynchronous import AsyncKernelClient # noqa
from .blocking import BlockingKernelClient # noqa
from .client import KernelClient # noqa
from .blocking import BlockingKernelClient
from .client import KernelClient
from .connect import * # noqa
from .launcher import * # noqa
from .manager import AsyncKernelManager # noqa
from .manager import KernelManager # noqa
from .manager import run_kernel # noqa
from .multikernelmanager import AsyncMultiKernelManager # noqa
from .multikernelmanager import MultiKernelManager # noqa
from .provisioning import KernelProvisionerBase # noqa
from .provisioning import LocalProvisioner # noqa
from .manager import AsyncKernelManager
from .manager import KernelManager
from .manager import run_kernel
from .multikernelmanager import AsyncMultiKernelManager
from .multikernelmanager import MultiKernelManager
from .provisioning import KernelProvisionerBase
from .provisioning import LocalProvisioner
except ModuleNotFoundError:
import warnings

10 changes: 5 additions & 5 deletions jupyter_client/session.py
Original file line number Diff line number Diff line change
@@ -249,7 +249,7 @@ def __init__(self, msg_dict: t.Dict[str, t.Any]) -> None:
dct = self.__dict__
for k, v in dict(msg_dict).items():
if isinstance(v, dict):
v = Message(v)
v = Message(v) # noqa
dct[k] = v

# Having this iterator lets dict(msg_obj) work out of the box.
@@ -861,9 +861,9 @@ def send(
stream.send_multipart(to_send, copy=copy)

if self.debug:
pprint.pprint(msg) # noqa
pprint.pprint(to_send) # noqa
pprint.pprint(buffers) # noqa
pprint.pprint(msg)
pprint.pprint(to_send)
pprint.pprint(buffers)

msg["tracker"] = tracker

@@ -1088,7 +1088,7 @@ def deserialize(
buffers = [memoryview(bytes(b.bytes)) for b in msg_list[5:]]
message["buffers"] = buffers
if self.debug:
pprint.pprint(message) # noqa
pprint.pprint(message)
# adapt to the current version
return adapt(message)

29 changes: 27 additions & 2 deletions jupyter_client/threaded.py
Original file line number Diff line number Diff line change
@@ -4,12 +4,14 @@
import asyncio
import atexit
import time
from concurrent.futures import Future
from threading import Event, Thread
from typing import Any, Dict, List, Optional

import zmq
from tornado.ioloop import IOLoop
from traitlets import Instance, Type
from traitlets.log import get_logger
from zmq.eventloop import zmqstream

from .channels import HBChannel
@@ -45,7 +47,7 @@ def __init__(
session : :class:`session.Session`
The session to use.
loop
A pyzmq ioloop to connect the socket to using a ZMQStream
A tornado ioloop to connect the socket to using a ZMQStream
"""
super().__init__()

@@ -79,7 +81,30 @@ def stop(self) -> None:
self._is_alive = False

def close(self) -> None:
""" "Close the channel."""
"""Close the channel."""
if self.stream is not None and self.ioloop is not None:
# c.f.Future for threadsafe results
f: Future = Future()

def close_stream():
try:
if self.stream is not None:
self.stream.close(linger=0)
self.stream = None
except Exception as e:
f.set_exception(e)
else:
f.set_result(None)

self.ioloop.add_callback(close_stream)
# wait for result
try:
f.result(timeout=5)
except Exception as e:
log = get_logger()
msg = f"Error closing stream {self.stream}: {e}"
log.warning(msg, RuntimeWarning, stacklevel=2)

if self.socket is not None:
try:
self.socket.close(linger=0)
2 changes: 1 addition & 1 deletion jupyter_client/utils.py
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ def _filefind(filename, path_dirs=None):

for path in path_dirs:
if path == ".":
path = os.getcwd()
path = os.getcwd() # noqa
testname = _expand_path(os.path.join(path, filename))
if os.path.isfile(testname):
return os.path.abspath(testname)
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@ test = "mypy --install-types --non-interactive {args:.}"
dependencies = [
"black[jupyter]==23.1.0",
"mdformat>0.7",
"ruff==0.0.243",
"ruff==0.0.254",
]
[tool.hatch.envs.lint.scripts]
style = [
@@ -242,6 +242,8 @@ ignore = [
"SIM108",
# S110 `try`-`except`-`pass` detected, consider logging the exception
"S110",
# PLW0603 Using the global statement to update
"PLW0603",
]
unfixable = [
# Don't touch print statements
2 changes: 1 addition & 1 deletion tests/test_jsonutil.py
Original file line number Diff line number Diff line change
@@ -182,7 +182,7 @@ def test_json_default():

for val, jval in pairs:
if jval is None:
jval = val
jval = val # noqa
out = json.loads(json.dumps(val, default=jsonutil.json_default))
# validate our cleanup
assert out == jval