Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update typings for traitlets 5.10 #1330

Merged
merged 4 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/simple/simple_ext1/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ class SimpleApp1(ExtensionAppJinjaMixin, ExtensionApp):
load_other_extensions = True

# Local path to static files directory.
static_paths = [DEFAULT_STATIC_FILES_PATH]
static_paths = [DEFAULT_STATIC_FILES_PATH] # type:ignore[assignment]

# Local path to templates directory.
template_paths = [DEFAULT_TEMPLATE_FILES_PATH]
template_paths = [DEFAULT_TEMPLATE_FILES_PATH] # type:ignore[assignment]

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

Expand Down
4 changes: 2 additions & 2 deletions examples/simple/simple_ext2/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ class SimpleApp2(ExtensionAppJinjaMixin, ExtensionApp):
load_other_extensions = True

# Local path to static files directory.
static_paths = [DEFAULT_STATIC_FILES_PATH]
static_paths = [DEFAULT_STATIC_FILES_PATH] # type:ignore[assignment]

# Local path to templates directory.
template_paths = [DEFAULT_TEMPLATE_FILES_PATH]
template_paths = [DEFAULT_TEMPLATE_FILES_PATH] # type:ignore[assignment]

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

Expand Down
14 changes: 9 additions & 5 deletions jupyter_server/auth/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,22 +702,24 @@ def auth_enabled(self):

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

@property
def login_available(self):
return self.login_handler_class.get_login_available(self.settings)
return self.login_handler_class.get_login_available( # type:ignore[attr-defined]
self.settings
)

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

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

def validate_security(
self,
Expand All @@ -732,4 +734,6 @@ def validate_security(
self.log.critical(_i18n("Hint: run the following command to set a password"))
self.log.critical(_i18n("\t$ python -m jupyter_server.auth password"))
sys.exit(1)
return self.login_handler_class.validate_security(app, ssl_options)
return self.login_handler_class.validate_security( # type:ignore[attr-defined]
app, ssl_options
)
2 changes: 1 addition & 1 deletion jupyter_server/extension/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def load_extension(self, name):
"""Load an extension by name."""
extension = self.extensions.get(name)

if extension.enabled:
if extension and extension.enabled:
try:
extension.load_all_points(self.serverapp)
except Exception as e:
Expand Down
6 changes: 4 additions & 2 deletions jupyter_server/gateway/connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def disconnect(self):
if self.ws is not None:
# Close connection
self.ws.close()
elif not self.ws_future.done():
elif self.ws_future and not self.ws_future.done():
# Cancel pending connection. Since future.cancel() is a noop on tornado, we'll track cancellation locally
self.ws_future.cancel()
self.log.debug(f"_disconnect: future cancelled, disconnected: {self.disconnected}")
Expand All @@ -93,6 +93,8 @@ async def _read_messages(self):
if not self.disconnected:
self.log.warning(f"Lost connection to Gateway: {self.kernel_id}")
break
if isinstance(message, bytes):
message = message.decode("utf8")
self.handle_outgoing_message(
message
) # pass back to notebook client (see self.on_open and WebSocketChannelsHandler.open)
Expand Down Expand Up @@ -136,7 +138,7 @@ def handle_outgoing_message(self, incoming_msg: str, *args: Any) -> None:

def handle_incoming_message(self, message: str) -> None:
"""Send message to gateway server."""
if self.ws is None:
if self.ws is None and self.ws_future is not None:
loop = IOLoop.current()
loop.add_future(self.ws_future, lambda future: self.handle_incoming_message(message))
else:
Expand Down
44 changes: 24 additions & 20 deletions jupyter_server/gateway/gateway_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def _url_validate(self, proposal):
@default("ws_url")
def _ws_url_default(self):
default_value = os.environ.get(self.ws_url_env)
if default_value is None and self.gateway_enabled:
if self.url is not None and default_value is None and self.gateway_enabled:
default_value = self.url.lower().replace("http", "ws")
return default_value

Expand Down Expand Up @@ -462,7 +462,7 @@ def _gateway_retry_max_default(self):
)
gateway_token_renewer_class_env = "JUPYTER_GATEWAY_TOKEN_RENEWER_CLASS"
gateway_token_renewer_class = Type(
klass=GatewayTokenRenewerBase,
klass=GatewayTokenRenewerBase, # type:ignore[type-abstract]
config=True,
help="""The class to use for Gateway token renewal. (JUPYTER_GATEWAY_TOKEN_RENEWER_CLASS env var)""",
)
Expand Down Expand Up @@ -546,7 +546,9 @@ def __init__(self, **kwargs):
"""Initialize a gateway client."""
super().__init__(**kwargs)
self._connection_args = {} # initialized on first use
self.gateway_token_renewer = self.gateway_token_renewer_class(parent=self, log=self.log)
self.gateway_token_renewer = self.gateway_token_renewer_class(
parent=self, log=self.log
) # type:ignore[operator]

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

self._connection_args["headers"] = json.loads(self.headers)
if self.auth_header_key not in self._connection_args["headers"]:
self._connection_args["headers"].update(
{f"{self.auth_header_key}": f"{self.auth_scheme} {self.auth_token}"}
)
if self.headers:
self._connection_args["headers"] = json.loads(self.headers)
if self.auth_header_key not in self._connection_args["headers"]:
self._connection_args["headers"].update(
{f"{self.auth_header_key}": f"{self.auth_scheme} {self.auth_token}"}
)
self._connection_args["connect_timeout"] = self.connect_timeout
self._connection_args["request_timeout"] = self.request_timeout
self._connection_args["validate_cert"] = self.validate_cert
Expand All @@ -598,18 +601,19 @@ def load_connection_args(self, **kwargs):

# Give token renewal a shot at renewing the token
prev_auth_token = self.auth_token
try:
self.auth_token = self.gateway_token_renewer.get_token(
self.auth_header_key, self.auth_scheme, self.auth_token
)
except Exception as ex:
self.log.error(
f"An exception occurred attempting to renew the "
f"Gateway authorization token using an instance of class "
f"'{self.gateway_token_renewer_class}'. The request will "
f"proceed using the current token value. Exception was: {ex}"
)
self.auth_token = prev_auth_token
if self.auth_token:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1339 looking at this issue.

Is this the problematic line? Can we just revert this line?

try:
self.auth_token = self.gateway_token_renewer.get_token(
self.auth_header_key, self.auth_scheme, self.auth_token
)
except Exception as ex:
self.log.error(
f"An exception occurred attempting to renew the "
f"Gateway authorization token using an instance of class "
f"'{self.gateway_token_renewer_class}'. The request will "
f"proceed using the current token value. Exception was: {ex}"
)
self.auth_token = prev_auth_token

for arg, value in self._connection_args.items():
if arg == "headers":
Expand Down
6 changes: 5 additions & 1 deletion jupyter_server/gateway/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ def _replace_path_kernelspec_resources(self, kernel_specs):
This enables clients to properly route through jupyter_server to a gateway
for kernel resources such as logo files
"""
if not self.parent:
return {}
kernelspecs = kernel_specs["kernelspecs"]
for kernel_name in kernelspecs:
resources = kernelspecs[kernel_name]["resources"]
Expand Down Expand Up @@ -273,6 +275,8 @@ async def get_all_specs(self):
# If different log a warning and reset the default. However, the
# caller of this method will still return this server's value until
# the next fetch of kernelspecs - at which time they'll match.
if not self.parent:
return {}
km = self.parent.kernel_manager
remote_default_kernel_name = fetched_kspecs.get("default")
if remote_default_kernel_name != km.default_kernel_name:
Expand Down Expand Up @@ -416,7 +420,7 @@ def client(self, **kwargs):

# add kwargs last, for manual overrides
kw.update(kwargs)
return self.client_factory(**kw)
return self.client_factory(**kw) # type:ignore[operator]

async def refresh_model(self, model=None):
"""Refresh the kernel model.
Expand Down
30 changes: 18 additions & 12 deletions jupyter_server/serverapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -1879,21 +1879,25 @@ def init_configurables(self):
# this determination, instantiate the GatewayClient config singleton.
self.gateway_config = GatewayClient.instance(parent=self)

if not issubclass(self.kernel_manager_class, AsyncMappingKernelManager):
if not issubclass(
self.kernel_manager_class, AsyncMappingKernelManager # type:ignore[arg-type]
):
warnings.warn(
"The synchronous MappingKernelManager class is deprecated and will not be supported in Jupyter Server 3.0",
DeprecationWarning,
stacklevel=2,
)

if not issubclass(self.contents_manager_class, AsyncContentsManager):
if not issubclass(
self.contents_manager_class, AsyncContentsManager # type:ignore[arg-type]
):
warnings.warn(
"The synchronous ContentsManager classes are deprecated and will not be supported in Jupyter Server 3.0",
DeprecationWarning,
stacklevel=2,
)

self.kernel_spec_manager = self.kernel_spec_manager_class(
self.kernel_spec_manager = self.kernel_spec_manager_class( # type:ignore[operator]
parent=self,
)

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

self.kernel_manager = self.kernel_manager_class(**kwargs)
self.contents_manager = self.contents_manager_class(
self.kernel_manager = self.kernel_manager_class(**kwargs) # type:ignore[operator]
self.contents_manager = self.contents_manager_class( # type:ignore[operator]
parent=self,
log=self.log,
)
# Trigger a default/validation here explicitly while we still support the
# deprecated trait on ServerApp (FIXME remove when deprecation finalized)
self.contents_manager.preferred_dir # noqa
self.session_manager = self.session_manager_class(
self.session_manager = self.session_manager_class( # type:ignore[operator]
parent=self,
log=self.log,
kernel_manager=self.kernel_manager,
contents_manager=self.contents_manager,
)
self.config_manager = self.config_manager_class(
self.config_manager = self.config_manager_class( # type:ignore[operator]
parent=self,
log=self.log,
)
Expand Down Expand Up @@ -1958,7 +1962,9 @@ def init_configurables(self):
f"Ignoring deprecated config ServerApp.login_handler_class={self.login_handler_class}."
" Superseded by ServerApp.identity_provider_class={self.identity_provider_class}."
)
self.identity_provider = self.identity_provider_class(**identity_provider_kwargs)
self.identity_provider = self.identity_provider_class(
**identity_provider_kwargs
) # type:ignore[operator]

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

self.authorizer = self.authorizer_class(
self.authorizer = self.authorizer_class( # type:ignore[operator]
parent=self, log=self.log, identity_provider=self.identity_provider
)

Expand Down Expand Up @@ -2100,7 +2106,7 @@ def init_webapp(self):
if not self.ssl_options:
# could be an empty dict or None
# None indicates no SSL config
self.ssl_options = None
self.ssl_options = None # type:ignore[assignment]
else:
# SSL may be missing, so only import it if it's to be used
import ssl
Expand Down Expand Up @@ -2130,7 +2136,7 @@ def init_resources(self):
old_soft, old_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
soft = self.min_open_files_limit
hard = old_hard
if old_soft < soft:
if soft is not None and old_soft < soft:
if hard < soft:
hard = soft
self.log.debug(
Expand Down Expand Up @@ -2911,7 +2917,7 @@ async def _cleanup(self):
await self.cleanup_extensions()
await self.cleanup_kernels()
try:
await self.kernel_websocket_connection_class.close_all()
await self.kernel_websocket_connection_class.close_all() # type:ignore[attr-defined]
except AttributeError:
# This can happen in two different scenarios:
#
Expand Down
5 changes: 2 additions & 3 deletions jupyter_server/services/contents/filecheckpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ class FileCheckpoints(FileManagerMixin, Checkpoints):
root_dir = Unicode(config=True)

def _root_dir_default(self):
try:
return self.parent.root_dir
except AttributeError:
if not self.parent:
return os.getcwd()
return self.parent.root_dir

# ContentsManager-dependent checkpoint API
def create_checkpoint(self, contents_mgr, path):
Expand Down
7 changes: 4 additions & 3 deletions jupyter_server/services/contents/filemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ class FileContentsManager(FileManagerMixin, ContentsManager):

@default("root_dir")
def _default_root_dir(self):
try:
return self.parent.root_dir
except AttributeError:
if not self.parent:
return os.getcwd()
return self.parent.root_dir

@validate("root_dir")
def _validate_root_dir(self, proposal):
Expand All @@ -65,6 +64,8 @@ def _validate_root_dir(self, proposal):

@default("preferred_dir")
def _default_preferred_dir(self):
if not self.parent:
return ""
try:
value = self.parent.preferred_dir
if value == self.parent.root_dir:
Expand Down
15 changes: 8 additions & 7 deletions jupyter_server/services/contents/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,12 @@ def _validate_preferred_dir(self, proposal):
raise TraitError(e.log_message) from e
if not dir_exists:
raise TraitError(_i18n("Preferred directory not found: %r") % value)
try:
if value != self.parent.preferred_dir:
self.parent.preferred_dir = os.path.join(self.root_dir, *value.split("/"))
except (AttributeError, TraitError):
pass
if self.parent:
try:
if value != self.parent.preferred_dir:
self.parent.preferred_dir = os.path.join(self.root_dir, *value.split("/"))
except TraitError:
pass
return value

allow_hidden = Bool(False, config=True, help="Allow access to hidden files")
Expand Down Expand Up @@ -324,7 +325,7 @@ def run_post_save_hooks(self, model, os_path):

@default("checkpoints")
def _default_checkpoints(self):
return self.checkpoints_class(**self.checkpoints_kwargs)
return self.checkpoints_class(**self.checkpoints_kwargs) # type:ignore[operator]

@default("checkpoints_kwargs")
def _default_checkpoints_kwargs(self):
Expand Down Expand Up @@ -760,7 +761,7 @@ class AsyncContentsManager(ContentsManager):

@default("checkpoints")
def _default_checkpoints(self):
return self.checkpoints_class(**self.checkpoints_kwargs)
return self.checkpoints_class(**self.checkpoints_kwargs) # type:ignore[operator]

@default("checkpoints_kwargs")
def _default_checkpoints_kwargs(self):
Expand Down
3 changes: 2 additions & 1 deletion jupyter_server/services/events/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ async def get(self, *args, **kwargs):
"""Get an event socket."""
self.pre_get()
res = super().get(*args, **kwargs)
await res
if res is not None:
await res

async def event_listener(self, logger: EventLogger, schema_id: str, data: dict) -> None:
"""Write an event message."""
Expand Down
Loading
Loading