Skip to content

Commit 3544deb

Browse files
authored
Update typings for traitlets 5.10 (#1330)
1 parent 46e685b commit 3544deb

File tree

17 files changed

+92
-67
lines changed

17 files changed

+92
-67
lines changed

examples/simple/simple_ext1/application.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ class SimpleApp1(ExtensionAppJinjaMixin, ExtensionApp):
3131
load_other_extensions = True
3232

3333
# Local path to static files directory.
34-
static_paths = [DEFAULT_STATIC_FILES_PATH]
34+
static_paths = [DEFAULT_STATIC_FILES_PATH] # type:ignore[assignment]
3535

3636
# Local path to templates directory.
37-
template_paths = [DEFAULT_TEMPLATE_FILES_PATH]
37+
template_paths = [DEFAULT_TEMPLATE_FILES_PATH] # type:ignore[assignment]
3838

3939
configA = Unicode("", config=True, help="Config A example.") # noqa
4040

examples/simple/simple_ext2/application.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ class SimpleApp2(ExtensionAppJinjaMixin, ExtensionApp):
2424
load_other_extensions = True
2525

2626
# Local path to static files directory.
27-
static_paths = [DEFAULT_STATIC_FILES_PATH]
27+
static_paths = [DEFAULT_STATIC_FILES_PATH] # type:ignore[assignment]
2828

2929
# Local path to templates directory.
30-
template_paths = [DEFAULT_TEMPLATE_FILES_PATH]
30+
template_paths = [DEFAULT_TEMPLATE_FILES_PATH] # type:ignore[assignment]
3131

3232
configD = Unicode("", config=True, help="Config D example.") # noqa
3333

jupyter_server/auth/identity.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -702,22 +702,24 @@ def auth_enabled(self):
702702

703703
def get_user(self, handler: JupyterHandler) -> User | None:
704704
"""Get the user."""
705-
user = self.login_handler_class.get_user(handler)
705+
user = self.login_handler_class.get_user(handler) # type:ignore[attr-defined]
706706
if user is None:
707707
return None
708708
return _backward_compat_user(user)
709709

710710
@property
711711
def login_available(self):
712-
return self.login_handler_class.get_login_available(self.settings)
712+
return self.login_handler_class.get_login_available( # type:ignore[attr-defined]
713+
self.settings
714+
)
713715

714716
def should_check_origin(self, handler: JupyterHandler) -> bool:
715717
"""Whether we should check origin."""
716-
return self.login_handler_class.should_check_origin(handler)
718+
return self.login_handler_class.should_check_origin(handler) # type:ignore[attr-defined]
717719

718720
def is_token_authenticated(self, handler: JupyterHandler) -> bool:
719721
"""Whether we are token authenticated."""
720-
return self.login_handler_class.is_token_authenticated(handler)
722+
return self.login_handler_class.is_token_authenticated(handler) # type:ignore[attr-defined]
721723

722724
def validate_security(
723725
self,
@@ -732,4 +734,6 @@ def validate_security(
732734
self.log.critical(_i18n("Hint: run the following command to set a password"))
733735
self.log.critical(_i18n("\t$ python -m jupyter_server.auth password"))
734736
sys.exit(1)
735-
return self.login_handler_class.validate_security(app, ssl_options)
737+
return self.login_handler_class.validate_security( # type:ignore[attr-defined]
738+
app, ssl_options
739+
)

jupyter_server/extension/manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ def load_extension(self, name):
351351
"""Load an extension by name."""
352352
extension = self.extensions.get(name)
353353

354-
if extension.enabled:
354+
if extension and extension.enabled:
355355
try:
356356
extension.load_all_points(self.serverapp)
357357
except Exception as e:

jupyter_server/gateway/connections.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def disconnect(self):
7373
if self.ws is not None:
7474
# Close connection
7575
self.ws.close()
76-
elif not self.ws_future.done():
76+
elif self.ws_future and not self.ws_future.done():
7777
# Cancel pending connection. Since future.cancel() is a noop on tornado, we'll track cancellation locally
7878
self.ws_future.cancel()
7979
self.log.debug(f"_disconnect: future cancelled, disconnected: {self.disconnected}")
@@ -93,6 +93,8 @@ async def _read_messages(self):
9393
if not self.disconnected:
9494
self.log.warning(f"Lost connection to Gateway: {self.kernel_id}")
9595
break
96+
if isinstance(message, bytes):
97+
message = message.decode("utf8")
9698
self.handle_outgoing_message(
9799
message
98100
) # pass back to notebook client (see self.on_open and WebSocketChannelsHandler.open)
@@ -136,7 +138,7 @@ def handle_outgoing_message(self, incoming_msg: str, *args: Any) -> None:
136138

137139
def handle_incoming_message(self, message: str) -> None:
138140
"""Send message to gateway server."""
139-
if self.ws is None:
141+
if self.ws is None and self.ws_future is not None:
140142
loop = IOLoop.current()
141143
loop.add_future(self.ws_future, lambda future: self.handle_incoming_message(message))
142144
else:

jupyter_server/gateway/gateway_client.py

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def _url_validate(self, proposal):
156156
@default("ws_url")
157157
def _ws_url_default(self):
158158
default_value = os.environ.get(self.ws_url_env)
159-
if default_value is None and self.gateway_enabled:
159+
if self.url is not None and default_value is None and self.gateway_enabled:
160160
default_value = self.url.lower().replace("http", "ws")
161161
return default_value
162162

@@ -462,7 +462,7 @@ def _gateway_retry_max_default(self):
462462
)
463463
gateway_token_renewer_class_env = "JUPYTER_GATEWAY_TOKEN_RENEWER_CLASS"
464464
gateway_token_renewer_class = Type(
465-
klass=GatewayTokenRenewerBase,
465+
klass=GatewayTokenRenewerBase, # type:ignore[type-abstract]
466466
config=True,
467467
help="""The class to use for Gateway token renewal. (JUPYTER_GATEWAY_TOKEN_RENEWER_CLASS env var)""",
468468
)
@@ -546,7 +546,9 @@ def __init__(self, **kwargs):
546546
"""Initialize a gateway client."""
547547
super().__init__(**kwargs)
548548
self._connection_args = {} # initialized on first use
549-
self.gateway_token_renewer = self.gateway_token_renewer_class(parent=self, log=self.log)
549+
self.gateway_token_renewer = self.gateway_token_renewer_class(
550+
parent=self, log=self.log
551+
) # type:ignore[operator]
550552

551553
# store of cookies with store time
552554
self._cookies: ty.Dict[str, ty.Tuple[Morsel, datetime]] = {}
@@ -570,11 +572,12 @@ def init_connection_args(self):
570572
# Ensure any adjustments are reflected in env.
571573
os.environ["KERNEL_LAUNCH_TIMEOUT"] = str(GatewayClient.KERNEL_LAUNCH_TIMEOUT)
572574

573-
self._connection_args["headers"] = json.loads(self.headers)
574-
if self.auth_header_key not in self._connection_args["headers"]:
575-
self._connection_args["headers"].update(
576-
{f"{self.auth_header_key}": f"{self.auth_scheme} {self.auth_token}"}
577-
)
575+
if self.headers:
576+
self._connection_args["headers"] = json.loads(self.headers)
577+
if self.auth_header_key not in self._connection_args["headers"]:
578+
self._connection_args["headers"].update(
579+
{f"{self.auth_header_key}": f"{self.auth_scheme} {self.auth_token}"}
580+
)
578581
self._connection_args["connect_timeout"] = self.connect_timeout
579582
self._connection_args["request_timeout"] = self.request_timeout
580583
self._connection_args["validate_cert"] = self.validate_cert
@@ -598,18 +601,19 @@ def load_connection_args(self, **kwargs):
598601

599602
# Give token renewal a shot at renewing the token
600603
prev_auth_token = self.auth_token
601-
try:
602-
self.auth_token = self.gateway_token_renewer.get_token(
603-
self.auth_header_key, self.auth_scheme, self.auth_token
604-
)
605-
except Exception as ex:
606-
self.log.error(
607-
f"An exception occurred attempting to renew the "
608-
f"Gateway authorization token using an instance of class "
609-
f"'{self.gateway_token_renewer_class}'. The request will "
610-
f"proceed using the current token value. Exception was: {ex}"
611-
)
612-
self.auth_token = prev_auth_token
604+
if self.auth_token:
605+
try:
606+
self.auth_token = self.gateway_token_renewer.get_token(
607+
self.auth_header_key, self.auth_scheme, self.auth_token
608+
)
609+
except Exception as ex:
610+
self.log.error(
611+
f"An exception occurred attempting to renew the "
612+
f"Gateway authorization token using an instance of class "
613+
f"'{self.gateway_token_renewer_class}'. The request will "
614+
f"proceed using the current token value. Exception was: {ex}"
615+
)
616+
self.auth_token = prev_auth_token
613617

614618
for arg, value in self._connection_args.items():
615619
if arg == "headers":

jupyter_server/gateway/managers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ def _replace_path_kernelspec_resources(self, kernel_specs):
236236
This enables clients to properly route through jupyter_server to a gateway
237237
for kernel resources such as logo files
238238
"""
239+
if not self.parent:
240+
return {}
239241
kernelspecs = kernel_specs["kernelspecs"]
240242
for kernel_name in kernelspecs:
241243
resources = kernelspecs[kernel_name]["resources"]
@@ -273,6 +275,8 @@ async def get_all_specs(self):
273275
# If different log a warning and reset the default. However, the
274276
# caller of this method will still return this server's value until
275277
# the next fetch of kernelspecs - at which time they'll match.
278+
if not self.parent:
279+
return {}
276280
km = self.parent.kernel_manager
277281
remote_default_kernel_name = fetched_kspecs.get("default")
278282
if remote_default_kernel_name != km.default_kernel_name:
@@ -416,7 +420,7 @@ def client(self, **kwargs):
416420

417421
# add kwargs last, for manual overrides
418422
kw.update(kwargs)
419-
return self.client_factory(**kw)
423+
return self.client_factory(**kw) # type:ignore[operator]
420424

421425
async def refresh_model(self, model=None):
422426
"""Refresh the kernel model.

jupyter_server/serverapp.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,21 +1879,25 @@ def init_configurables(self):
18791879
# this determination, instantiate the GatewayClient config singleton.
18801880
self.gateway_config = GatewayClient.instance(parent=self)
18811881

1882-
if not issubclass(self.kernel_manager_class, AsyncMappingKernelManager):
1882+
if not issubclass(
1883+
self.kernel_manager_class, AsyncMappingKernelManager # type:ignore[arg-type]
1884+
):
18831885
warnings.warn(
18841886
"The synchronous MappingKernelManager class is deprecated and will not be supported in Jupyter Server 3.0",
18851887
DeprecationWarning,
18861888
stacklevel=2,
18871889
)
18881890

1889-
if not issubclass(self.contents_manager_class, AsyncContentsManager):
1891+
if not issubclass(
1892+
self.contents_manager_class, AsyncContentsManager # type:ignore[arg-type]
1893+
):
18901894
warnings.warn(
18911895
"The synchronous ContentsManager classes are deprecated and will not be supported in Jupyter Server 3.0",
18921896
DeprecationWarning,
18931897
stacklevel=2,
18941898
)
18951899

1896-
self.kernel_spec_manager = self.kernel_spec_manager_class(
1900+
self.kernel_spec_manager = self.kernel_spec_manager_class( # type:ignore[operator]
18971901
parent=self,
18981902
)
18991903

@@ -1915,21 +1919,21 @@ def init_configurables(self):
19151919
"because jupyter-client's version does not allow them (should be >8.3.0)."
19161920
)
19171921

1918-
self.kernel_manager = self.kernel_manager_class(**kwargs)
1919-
self.contents_manager = self.contents_manager_class(
1922+
self.kernel_manager = self.kernel_manager_class(**kwargs) # type:ignore[operator]
1923+
self.contents_manager = self.contents_manager_class( # type:ignore[operator]
19201924
parent=self,
19211925
log=self.log,
19221926
)
19231927
# Trigger a default/validation here explicitly while we still support the
19241928
# deprecated trait on ServerApp (FIXME remove when deprecation finalized)
19251929
self.contents_manager.preferred_dir # noqa
1926-
self.session_manager = self.session_manager_class(
1930+
self.session_manager = self.session_manager_class( # type:ignore[operator]
19271931
parent=self,
19281932
log=self.log,
19291933
kernel_manager=self.kernel_manager,
19301934
contents_manager=self.contents_manager,
19311935
)
1932-
self.config_manager = self.config_manager_class(
1936+
self.config_manager = self.config_manager_class( # type:ignore[operator]
19331937
parent=self,
19341938
log=self.log,
19351939
)
@@ -1958,7 +1962,9 @@ def init_configurables(self):
19581962
f"Ignoring deprecated config ServerApp.login_handler_class={self.login_handler_class}."
19591963
" Superseded by ServerApp.identity_provider_class={self.identity_provider_class}."
19601964
)
1961-
self.identity_provider = self.identity_provider_class(**identity_provider_kwargs)
1965+
self.identity_provider = self.identity_provider_class(
1966+
**identity_provider_kwargs
1967+
) # type:ignore[operator]
19621968

19631969
if self.identity_provider_class is LegacyIdentityProvider:
19641970
# legacy config stored the password in tornado_settings
@@ -1979,7 +1985,7 @@ def init_configurables(self):
19791985
# that means it has some config that should take higher priority than deprecated ServerApp.token
19801986
self.log.warning("Ignoring deprecated ServerApp.token config")
19811987

1982-
self.authorizer = self.authorizer_class(
1988+
self.authorizer = self.authorizer_class( # type:ignore[operator]
19831989
parent=self, log=self.log, identity_provider=self.identity_provider
19841990
)
19851991

@@ -2100,7 +2106,7 @@ def init_webapp(self):
21002106
if not self.ssl_options:
21012107
# could be an empty dict or None
21022108
# None indicates no SSL config
2103-
self.ssl_options = None
2109+
self.ssl_options = None # type:ignore[assignment]
21042110
else:
21052111
# SSL may be missing, so only import it if it's to be used
21062112
import ssl
@@ -2130,7 +2136,7 @@ def init_resources(self):
21302136
old_soft, old_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
21312137
soft = self.min_open_files_limit
21322138
hard = old_hard
2133-
if old_soft < soft:
2139+
if soft is not None and old_soft < soft:
21342140
if hard < soft:
21352141
hard = soft
21362142
self.log.debug(
@@ -2911,7 +2917,7 @@ async def _cleanup(self):
29112917
await self.cleanup_extensions()
29122918
await self.cleanup_kernels()
29132919
try:
2914-
await self.kernel_websocket_connection_class.close_all()
2920+
await self.kernel_websocket_connection_class.close_all() # type:ignore[attr-defined]
29152921
except AttributeError:
29162922
# This can happen in two different scenarios:
29172923
#

jupyter_server/services/contents/filecheckpoints.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,9 @@ class FileCheckpoints(FileManagerMixin, Checkpoints):
4343
root_dir = Unicode(config=True)
4444

4545
def _root_dir_default(self):
46-
try:
47-
return self.parent.root_dir
48-
except AttributeError:
46+
if not self.parent:
4947
return os.getcwd()
48+
return self.parent.root_dir
5049

5150
# ContentsManager-dependent checkpoint API
5251
def create_checkpoint(self, contents_mgr, path):

jupyter_server/services/contents/filemanager.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,9 @@ class FileContentsManager(FileManagerMixin, ContentsManager):
4848

4949
@default("root_dir")
5050
def _default_root_dir(self):
51-
try:
52-
return self.parent.root_dir
53-
except AttributeError:
51+
if not self.parent:
5452
return os.getcwd()
53+
return self.parent.root_dir
5554

5655
@validate("root_dir")
5756
def _validate_root_dir(self, proposal):
@@ -65,6 +64,8 @@ def _validate_root_dir(self, proposal):
6564

6665
@default("preferred_dir")
6766
def _default_preferred_dir(self):
67+
if not self.parent:
68+
return ""
6869
try:
6970
value = self.parent.preferred_dir
7071
if value == self.parent.root_dir:

0 commit comments

Comments
 (0)