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.4.6
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: v7.4.7
Choose a head ref
  • 2 commits
  • 5 files changed
  • 3 contributors

Commits on Nov 16, 2022

  1. Backport PR #882 on branch 7.x (Fix connection reconciliation to hand…

    …le restarts) (#883)
    
    Co-authored-by: Kevin Bates <kbates4@gmail.com>
    meeseeksmachine and kevin-bates authored Nov 16, 2022

    Verified

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

    SHA256 hashes:
    
    jupyter_client-7.4.7-py3-none-any.whl: df56ae23b8e1da1b66f89dee1368e948b24a7f780fa822c5735187589fc4c157
    
    jupyter_client-7.4.7.tar.gz: 330f6b627e0b4bf2f54a3a0dd9e4a22d2b649c8518168afedce2c96a1ceb2860
    blink1073 committed Nov 16, 2022

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    5ffa3d4 View commit details
Showing with 48 additions and 41 deletions.
  1. +16 −2 CHANGELOG.md
  2. +1 −1 jupyter_client/_version.py
  3. +14 −13 jupyter_client/connect.py
  4. +15 −23 jupyter_client/tests/test_connect.py
  5. +2 −2 pyproject.toml
18 changes: 16 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,22 @@

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

## 7.4.7

([Full Changelog](https://github.com/jupyter/jupyter_client/compare/v7.4.6...56df36b535710d2c247a2749deec456c75191af5))

### Bugs fixed

- Fix connection reconciliation to handle restarts [#882](https://github.com/jupyter/jupyter_client/pull/882) ([@kevin-bates](https://github.com/kevin-bates))

### Contributors to this release

([GitHub contributors page for this release](https://github.com/jupyter/jupyter_client/graphs/contributors?from=2022-11-15&to=2022-11-16&type=c))

[@meeseeksmachine](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_client+involves%3Ameeseeksmachine+updated%3A2022-11-15..2022-11-16&type=Issues)

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

## 7.4.6

([Full Changelog](https://github.com/jupyter/jupyter_client/compare/v7.4.5...3394591f161be4a19f9e61c66ba510d7e29afd59))
@@ -16,8 +32,6 @@

[@meeseeksmachine](https://github.com/search?q=repo%3Ajupyter%2Fjupyter_client+involves%3Ameeseeksmachine+updated%3A2022-11-10..2022-11-15&type=Issues)

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

## 7.4.5

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

__version__ = "7.4.6"
__version__ = "7.4.7"

# Build up version_info tuple for backwards compatibility
pattern = r'(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)'
27 changes: 14 additions & 13 deletions jupyter_client/connect.py
Original file line number Diff line number Diff line change
@@ -573,7 +573,8 @@ def _reconcile_connection_info(self, info: KernelConnectionInfo) -> None:
Because some provisioners (like derivations of LocalProvisioner) may have already
written the connection file, this method needs to ensure that, if the connection
file exists, its contents match that of what was returned by the provisioner. If
the file does exist and its contents do not match, a ValueError is raised.
the file does exist and its contents do not match, the file will be replaced with
the provisioner information (which is considered the truth).
If the file does not exist, the connection information in 'info' is loaded into the
KernelManager and written to the file.
@@ -586,24 +587,24 @@ def _reconcile_connection_info(self, info: KernelConnectionInfo) -> None:
if os.path.exists(self.connection_file):
with open(self.connection_file) as f:
file_info = json.load(f)
# Prior to the following comparison, we need to adjust the value of "key" to
# be bytes, otherwise the comparison below will fail.
file_info["key"] = file_info["key"].encode()
if not self._equal_connections(info, file_info):
raise ValueError(
"Connection file already exists and does not match "
"the expected values returned from provisioner!"
)
# Prior to the following comparison, we need to adjust the value of "key" to
# be bytes, otherwise the comparison below will fail.
file_info["key"] = file_info["key"].encode()
if not self._equal_connections(info, file_info):
os.remove(self.connection_file) # Contents mismatch - remove the file
self._connection_file_written = False
else:
file_exists = True

if not file_exists:
# Load the connection info and write out file. Note, this does not necessarily
# overwrite non-zero port values, so we'll validate afterward.
# Load the connection info and write out file, clearing existing
# port-based attributes so they will be reloaded
for name in port_names:
setattr(self, name, 0)
self.load_connection_info(info)
self.write_connection_file()

# Ensure what is in KernelManager is what we expect. This will catch issues if the file
# already existed, yet it's contents differed from the KernelManager's (and provisioner).
# 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(
38 changes: 15 additions & 23 deletions jupyter_client/tests/test_connect.py
Original file line number Diff line number Diff line change
@@ -240,15 +240,15 @@ def test_mixin_cleanup_random_ports():


param_values = [
(True, True, None),
(True, False, ValueError),
(False, True, None),
(False, False, ValueError),
(True, True),
(True, False),
(False, True),
(False, False),
]


@pytest.mark.parametrize("file_exists, km_matches, expected_exception", param_values)
def test_reconcile_connection_info(file_exists, km_matches, expected_exception):
@pytest.mark.parametrize("file_exists, km_matches", param_values)
def test_reconcile_connection_info(file_exists, km_matches):

expected_info = sample_info
mismatched_info = sample_info.copy()
@@ -272,9 +272,10 @@ def test_reconcile_connection_info(file_exists, km_matches, expected_exception):
provisioner_info = info
km.load_connection_info(provisioner_info)
else:
# Let this be the case where the connection file exists, the KM has no values
# prior to reconciliation, but the provisioner has returned different values
# and a ValueError is expected.
# Let this be the case where the connection file exists, and the KM has those values
# that differ from the ones returned by the provisioner. This is the restart-with-
# changed-ports case (typical for remote provisioners).
km.load_connection_info(expected_info)
provisioner_info = mismatched_info
else: # connection file does not exist
if km_matches:
@@ -284,20 +285,11 @@ def test_reconcile_connection_info(file_exists, km_matches, expected_exception):
provisioner_info = expected_info
else:
# Let this be the case where the connection file does not exist, yet the KM
# has values that do not match those returned from the provisioner and a
# ValueError is expected.
# has values that do not match those returned from the provisioner. This case
# is probably not practical and is equivalent to the True, False case.
km.load_connection_info(expected_info)
provisioner_info = mismatched_info

if expected_exception is None:
km._reconcile_connection_info(provisioner_info)
km_info = km.get_connection_info()
assert km._equal_connections(km_info, provisioner_info)
else:
with pytest.raises(expected_exception) as ex:
km._reconcile_connection_info(provisioner_info)
if file_exists:
assert "Connection file already exists" in str(ex.value)
else:
assert "KernelManager's connection information already exists" in str(ex.value)
assert km._equal_connections(km.get_connection_info(), provisioner_info) is False
km._reconcile_connection_info(provisioner_info)
km_info = km.get_connection_info()
assert km._equal_connections(km_info, provisioner_info)
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "jupyter_client"
version = "7.4.6"
version = "7.4.7"
description = "Jupyter protocol implementation and client libraries"
keywords = [ "Interactive", "Interpreter", "Shell", "Web",]
classifiers = [
@@ -93,7 +93,7 @@ skip = ["check-links"]
ignore = [".mailmap", "*.yml", "*.yaml"]

[tool.tbump.version]
current = "7.4.6"
current = "7.4.7"
regex = '''
(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
((?P<channel>a|b|rc|.dev)(?P<release>\d+))?