Skip to content

Commit efba15a

Browse files
authored
Clean up handling of synchronous managers (#1044)
1 parent 4b2ac37 commit efba15a

File tree

9 files changed

+78
-43
lines changed

9 files changed

+78
-43
lines changed

jupyter_server/pytest_plugin.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
from jupyter_server.auth import Authorizer
2727
from jupyter_server.extension import serverextension
2828
from jupyter_server.serverapp import JUPYTER_SERVICE_HANDLERS, ServerApp
29-
from jupyter_server.services.contents.filemanager import FileContentsManager
30-
from jupyter_server.services.contents.largefilemanager import LargeFileManager
29+
from jupyter_server.services.contents.filemanager import AsyncFileContentsManager
30+
from jupyter_server.services.contents.largefilemanager import AsyncLargeFileManager
3131
from jupyter_server.utils import url_path_join
3232

3333
# List of dependencies needed for this plugin.
@@ -488,14 +488,14 @@ def jp_kernelspecs(jp_data_dir):
488488

489489
@pytest.fixture(params=[True, False])
490490
def jp_contents_manager(request, tmp_path):
491-
"""Returns a FileContentsManager instance based on the use_atomic_writing parameter value."""
492-
return FileContentsManager(root_dir=str(tmp_path), use_atomic_writing=request.param)
491+
"""Returns an AsyncFileContentsManager instance based on the use_atomic_writing parameter value."""
492+
return AsyncFileContentsManager(root_dir=str(tmp_path), use_atomic_writing=request.param)
493493

494494

495495
@pytest.fixture
496496
def jp_large_contents_manager(tmp_path):
497-
"""Returns a LargeFileManager instance."""
498-
return LargeFileManager(root_dir=str(tmp_path))
497+
"""Returns an AsyncLargeFileManager instance."""
498+
return AsyncLargeFileManager(root_dir=str(tmp_path))
499499

500500

501501
@pytest.fixture

jupyter_server/serverapp.py

Lines changed: 20 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import gettext
77
import hashlib
88
import hmac
9-
import inspect
109
import ipaddress
1110
import json
1211
import logging
@@ -57,8 +56,8 @@
5756
if not sys.platform.startswith("win"):
5857
from tornado.netutil import bind_unix_socket
5958

60-
from jupyter_client import KernelManager
6159
from jupyter_client.kernelspec import KernelSpecManager
60+
from jupyter_client.manager import KernelManager
6261
from jupyter_client.session import Session
6362
from jupyter_core.application import JupyterApp, base_aliases, base_flags
6463
from jupyter_core.paths import jupyter_runtime_dir
@@ -123,7 +122,7 @@
123122
AsyncFileContentsManager,
124123
FileContentsManager,
125124
)
126-
from jupyter_server.services.contents.largefilemanager import LargeFileManager
125+
from jupyter_server.services.contents.largefilemanager import AsyncLargeFileManager
127126
from jupyter_server.services.contents.manager import (
128127
AsyncContentsManager,
129128
ContentsManager,
@@ -133,7 +132,6 @@
133132
MappingKernelManager,
134133
)
135134
from jupyter_server.services.sessions.sessionmanager import SessionManager
136-
from jupyter_server.traittypes import TypeFromClasses
137135
from jupyter_server.utils import (
138136
check_pid,
139137
fetch,
@@ -1164,7 +1162,7 @@ def _deprecated_password_config(self, change):
11641162
config=True,
11651163
help="""Disable cross-site-request-forgery protection
11661164
1167-
Jupyter notebook 4.3.1 introduces protection from cross-site request forgeries,
1165+
Jupyter server includes protection from cross-site request forgeries,
11681166
requiring API requests to either:
11691167
11701168
- originate from pages served by this server (validated with XSRF cookie and token), or
@@ -1435,38 +1433,13 @@ def template_file_path(self):
14351433
help="""If True, display controls to shut down the Jupyter server, such as menu items or buttons.""",
14361434
)
14371435

1438-
# REMOVE in VERSION 2.0
1439-
# Temporarily allow content managers to inherit from the 'notebook'
1440-
# package. We will deprecate this in the next major release.
1441-
contents_manager_class = TypeFromClasses(
1442-
default_value=LargeFileManager,
1443-
klasses=[
1444-
"jupyter_server.services.contents.manager.ContentsManager",
1445-
"notebook.services.contents.manager.ContentsManager",
1446-
],
1436+
contents_manager_class = Type(
1437+
default_value=AsyncLargeFileManager,
1438+
klass=ContentsManager,
14471439
config=True,
14481440
help=_i18n("The content manager class to use."),
14491441
)
14501442

1451-
# Throws a deprecation warning to notebook based contents managers.
1452-
@observe("contents_manager_class")
1453-
def _observe_contents_manager_class(self, change):
1454-
new = change["new"]
1455-
# If 'new' is a class, get a string representing the import
1456-
# module path.
1457-
if inspect.isclass(new):
1458-
new = new.__module__
1459-
1460-
if new.startswith("notebook"):
1461-
self.log.warning(
1462-
"The specified 'contents_manager_class' class inherits a manager from the "
1463-
"'notebook' package. This is not guaranteed to work in future "
1464-
"releases of Jupyter Server. Instead, consider switching the "
1465-
"manager to inherit from the 'jupyter_server' managers. "
1466-
"Jupyter Server will temporarily allow 'notebook' managers "
1467-
"until its next major release (2.x)."
1468-
)
1469-
14701443
kernel_manager_class = Type(
14711444
klass=MappingKernelManager,
14721445
config=True,
@@ -1865,6 +1838,20 @@ def init_configurables(self):
18651838
# this determination, instantiate the GatewayClient config singleton.
18661839
self.gateway_config = GatewayClient.instance(parent=self)
18671840

1841+
if not issubclass(self.kernel_manager_class, AsyncMappingKernelManager):
1842+
warnings.warn(
1843+
"The synchronous MappingKernelManager class is deprecated and will not be supported in Jupyter Server 3.0",
1844+
DeprecationWarning,
1845+
stacklevel=2,
1846+
)
1847+
1848+
if not issubclass(self.contents_manager_class, AsyncContentsManager):
1849+
warnings.warn(
1850+
"The synchronous ContentsManager classes are deprecated and will not be supported in Jupyter Server 3.0",
1851+
DeprecationWarning,
1852+
stacklevel=2,
1853+
)
1854+
18681855
self.kernel_spec_manager = self.kernel_spec_manager_class(
18691856
parent=self,
18701857
)

jupyter_server/services/contents/filemanager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ async def save(self, model, path=""):
755755
"""Save the file model and return the model with no content."""
756756
path = path.strip("/")
757757

758-
self.run_pre_save_hook(model=model, path=path)
758+
self.run_pre_save_hooks(model=model, path=path)
759759

760760
if "type" not in model:
761761
raise web.HTTPError(400, "No file type provided")

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ filterwarnings = [
141141
"error",
142142
"ignore:Passing a schema to Validator.iter_errors:DeprecationWarning",
143143
"ignore:run_pre_save_hook is deprecated:DeprecationWarning",
144-
144+
"always:unclosed <socket.socket:ResourceWarning",
145145
"module:Jupyter is migrating its paths to use standard platformdirs:DeprecationWarning",
146146
]
147147

tests/services/contents/test_api.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import pathlib
33
import sys
4+
import warnings
45
from base64 import decodebytes, encodebytes
56
from unicodedata import normalize
67

@@ -14,6 +15,17 @@
1415
from ...utils import expected_http_error
1516

1617

18+
@pytest.fixture(autouse=True)
19+
def suppress_deprecation_warnings():
20+
with warnings.catch_warnings():
21+
warnings.filterwarnings(
22+
"ignore",
23+
message="The synchronous ContentsManager",
24+
category=DeprecationWarning,
25+
)
26+
yield
27+
28+
1729
def notebooks_only(dir_model):
1830
return [nb for nb in dir_model["content"] if nb["type"] == "notebook"]
1931

tests/services/contents/test_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
from jupyter_server.services.contents.checkpoints import AsyncCheckpoints
44
from jupyter_server.services.contents.filecheckpoints import (
5+
AsyncFileCheckpoints,
56
AsyncGenericFileCheckpoints,
6-
GenericFileCheckpoints,
77
)
88
from jupyter_server.services.contents.manager import AsyncContentsManager
99

1010

11-
@pytest.fixture(params=[AsyncGenericFileCheckpoints, GenericFileCheckpoints])
11+
@pytest.fixture(params=[AsyncGenericFileCheckpoints, AsyncFileCheckpoints])
1212
def jp_server_config(request):
1313
return {"FileContentsManager": {"checkpoints_class": request.param}}
1414

tests/services/kernels/test_api.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33
import os
44
import time
5+
import warnings
56

67
import jupyter_client
78
import pytest
@@ -16,6 +17,17 @@
1617
TEST_TIMEOUT = 60
1718

1819

20+
@pytest.fixture(autouse=True)
21+
def suppress_deprecation_warnings():
22+
with warnings.catch_warnings():
23+
warnings.filterwarnings(
24+
"ignore",
25+
message="The synchronous MappingKernelManager",
26+
category=DeprecationWarning,
27+
)
28+
yield
29+
30+
1931
@pytest.fixture
2032
def pending_kernel_is_ready(jp_serverapp):
2133
async def _(kernel_id, ready=None):

tests/services/kernels/test_cull.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import json
33
import os
44
import platform
5+
import warnings
56

67
import jupyter_client
78
import pytest
@@ -12,6 +13,17 @@
1213
CULL_INTERVAL = 1
1314

1415

16+
@pytest.fixture(autouse=True)
17+
def suppress_deprecation_warnings():
18+
with warnings.catch_warnings():
19+
warnings.filterwarnings(
20+
"ignore",
21+
message="The synchronous MappingKernelManager",
22+
category=DeprecationWarning,
23+
)
24+
yield
25+
26+
1527
@pytest.mark.parametrize(
1628
"jp_server_config",
1729
[

tests/services/sessions/test_api.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import os
44
import shutil
55
import time
6+
import warnings
67
from typing import Any
78

89
import jupyter_client
@@ -22,6 +23,17 @@
2223
TEST_TIMEOUT = 60
2324

2425

26+
@pytest.fixture(autouse=True)
27+
def suppress_deprecation_warnings():
28+
with warnings.catch_warnings():
29+
warnings.filterwarnings(
30+
"ignore",
31+
message="The synchronous MappingKernelManager",
32+
category=DeprecationWarning,
33+
)
34+
yield
35+
36+
2537
def j(r):
2638
return json.loads(r.body.decode())
2739

0 commit comments

Comments
 (0)