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 ruff and typings #1365

Merged
merged 1 commit into from Nov 19, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Expand Up @@ -33,7 +33,7 @@ repos:
[mdformat-gfm, mdformat-frontmatter, mdformat-footnote]

- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v3.0.3"
rev: "v3.1.0"
hooks:
- id: prettier
types_or: [yaml, html, json]
Expand All @@ -58,7 +58,7 @@ repos:
- id: rst-inline-touching-normal

- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.6.1"
rev: "v1.7.0"
hooks:
- id: mypy
files: jupyter_server
Expand All @@ -67,7 +67,7 @@ repos:
["traitlets>=5.13", "jupyter_core>=5.5", "jupyter_client>=8.5"]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.5
rev: v0.1.6
hooks:
- id: ruff
types_or: [python, jupyter]
Expand All @@ -76,7 +76,7 @@ repos:
types_or: [python, jupyter]

- repo: https://github.com/scientific-python/cookie
rev: "2023.10.27"
rev: "2023.11.17"
hooks:
- id: sp-repo-review
additional_dependencies: ["repo-review[cli]"]
6 changes: 2 additions & 4 deletions docs/source/conf.py
@@ -1,5 +1,3 @@
#!/usr/bin/env python3
#
# Jupyter Server documentation build configuration file, created by
# sphinx-quickstart on Mon Apr 13 09:51:11 2015.
#
Expand Down Expand Up @@ -44,7 +42,7 @@
]

try:
import enchant # type:ignore[import-not-found] # noqa
import enchant # type:ignore[import-not-found]

extensions += ["sphinxcontrib.spelling"]
except ImportError:
Expand Down Expand Up @@ -338,7 +336,7 @@
spelling_word_list_filename = "spelling_wordlist.txt"

# import before any doc is built, so _ is guaranteed to be injected
import jupyter_server.transutils # noqa: F401
import jupyter_server.transutils

CONFIG_HEADER = """\
.. _other-full-config:
Expand Down
6 changes: 3 additions & 3 deletions examples/simple/simple_ext1/application.py
Expand Up @@ -36,11 +36,11 @@ class SimpleApp1(ExtensionAppJinjaMixin, ExtensionApp):
# Local path to templates directory.
template_paths = [DEFAULT_TEMPLATE_FILES_PATH] # type:ignore[assignment]

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

configB = Unicode("", config=True, help="Config B example.") # noqa
configB = Unicode("", config=True, help="Config B example.")

configC = Unicode("", config=True, help="Config C example.") # noqa
configC = Unicode("", config=True, help="Config C example.")

def initialize_handlers(self):
"""Initialize handlers."""
Expand Down
2 changes: 0 additions & 2 deletions examples/simple/simple_ext1/handlers.py
Expand Up @@ -47,8 +47,6 @@ def get(self, matched_part=None, *args, **kwargs):
class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler):
"""The base template handler."""

pass


class TypescriptHandler(BaseTemplateHandler):
"""A typescript handler."""
Expand Down
2 changes: 1 addition & 1 deletion examples/simple/simple_ext2/application.py
Expand Up @@ -29,7 +29,7 @@ class SimpleApp2(ExtensionAppJinjaMixin, ExtensionApp):
# Local path to templates directory.
template_paths = [DEFAULT_TEMPLATE_FILES_PATH] # type:ignore[assignment]

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

def initialize_handlers(self):
"""Initialize handlers."""
Expand Down
2 changes: 0 additions & 2 deletions examples/simple/simple_ext2/handlers.py
Expand Up @@ -20,8 +20,6 @@ def get(self, matched_part=None, *args, **kwargs):
class BaseTemplateHandler(ExtensionHandlerJinjaMixin, ExtensionHandlerMixin, JupyterHandler):
"""A base template handler."""

pass


class IndexHandler(BaseTemplateHandler):
"""The root API handler."""
Expand Down
4 changes: 2 additions & 2 deletions examples/simple/tests/test_handlers.py
Expand Up @@ -2,7 +2,7 @@
import pytest


@pytest.fixture
@pytest.fixture()
def jp_server_auth_resources(jp_server_auth_core_resources):
"""The server auth resources."""
for url_regex in [
Expand All @@ -12,7 +12,7 @@ def jp_server_auth_resources(jp_server_auth_core_resources):
return jp_server_auth_core_resources


@pytest.fixture
@pytest.fixture()
def jp_server_config(jp_template_dir, jp_server_authorizer):
"""The server config."""
return {
Expand Down
2 changes: 1 addition & 1 deletion jupyter_server/_sysinfo.py
Expand Up @@ -41,7 +41,7 @@ def pkg_commit_hash(pkg_path):
if p.exists(p.join(cur_path, ".git")):
try:
proc = subprocess.Popen(
["git", "rev-parse", "--short", "HEAD"], # noqa
["git", "rev-parse", "--short", "HEAD"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
cwd=pkg_path,
Expand Down
2 changes: 1 addition & 1 deletion jupyter_server/_tz.py
Expand Up @@ -13,7 +13,7 @@
ZERO = timedelta(0)


class tzUTC(tzinfo): # noqa: N801
class tzUTC(tzinfo):
"""tzinfo object for UTC (zero offset)"""

def utcoffset(self, d: datetime | None) -> timedelta:
Expand Down
8 changes: 4 additions & 4 deletions jupyter_server/auth/__init__.py
@@ -1,4 +1,4 @@
from .authorizer import * # noqa: F403
from .decorator import authorized # noqa: F401
from .identity import * # noqa: F403
from .security import passwd # noqa: F401
from .authorizer import *
from .decorator import authorized
from .identity import *
from .security import passwd
2 changes: 1 addition & 1 deletion jupyter_server/auth/__main__.py
Expand Up @@ -20,7 +20,7 @@ def set_password(args):
password_repeat = getpass("" if args.quiet else "Repeat password: ")
if password1 != password_repeat:
warnings.warn("Passwords do not match, try again", stacklevel=2)
elif len(password1) < 4: # noqa
elif len(password1) < 4:
warnings.warn("Please provide at least 4 characters", stacklevel=2)
else:
password = password1
Expand Down
2 changes: 1 addition & 1 deletion jupyter_server/auth/identity.py
Expand Up @@ -496,7 +496,7 @@ def is_token_authenticated(self, handler: web.RequestHandler) -> bool:
- skip origin-checks for scripts
"""
# ensure get_user has been called, so we know if we're token-authenticated
handler.current_user # noqa
handler.current_user # noqa: B018
return getattr(handler, "_token_authenticated", False)

def validate_security(
Expand Down
4 changes: 2 additions & 2 deletions jupyter_server/auth/login.py
Expand Up @@ -179,7 +179,7 @@ def is_token_authenticated(cls, handler):
"""DEPRECATED in 2.0, use IdentityProvider API"""
if getattr(handler, "_user_id", None) is None:
# ensure get_user has been called, so we know if we're token-authenticated
handler.current_user # noqa
handler.current_user # noqa: B018
return getattr(handler, "_token_authenticated", False)

@classmethod
Expand Down Expand Up @@ -233,7 +233,7 @@ def get_user_token(cls, handler):
"""DEPRECATED in 2.0, use IdentityProvider API"""
token = handler.token
if not token:
return
return None
# check login token from URL argument or Authorization header
user_token = cls.get_token(handler)
authenticated = False
Expand Down
3 changes: 1 addition & 2 deletions jupyter_server/auth/security.py
Expand Up @@ -52,8 +52,7 @@ def passwd(passphrase=None, algorithm="argon2"):
if p0 == p1:
passphrase = p0
break
else:
warnings.warn("Passwords do not match.", stacklevel=2)
warnings.warn("Passwords do not match.", stacklevel=2)
else:
msg = "No matching passwords found. Giving up."
raise ValueError(msg)
Expand Down
2 changes: 1 addition & 1 deletion jupyter_server/auth/utils.py
Expand Up @@ -166,4 +166,4 @@ def get_anonymous_username() -> str:
Get a random user-name based on the moons of Jupyter.
This function returns names like "Anonymous Io" or "Anonymous Metis".
"""
return moons_of_jupyter[random.randint(0, len(moons_of_jupyter) - 1)] # noqa
return moons_of_jupyter[random.randint(0, len(moons_of_jupyter) - 1)]
12 changes: 6 additions & 6 deletions jupyter_server/base/handlers.py
Expand Up @@ -64,7 +64,7 @@

def json_sys_info():
"""Get sys info as json."""
global _sys_info_cache # noqa
global _sys_info_cache # noqa: PLW0603
if _sys_info_cache is None:
_sys_info_cache = json.dumps(get_sys_info())
return _sys_info_cache
Expand Down Expand Up @@ -527,11 +527,11 @@ def check_xsrf_cookie(self) -> None:
"""Bypass xsrf cookie checks when token-authenticated"""
if not hasattr(self, "_jupyter_current_user"):
# Called too early, will be checked later
return
return None
if self.token_authenticated or self.settings.get("disable_check_xsrf", False):
# Token-authenticated requests do not need additional XSRF-check
# Servers without authentication are vulnerable to XSRF
return
return None
try:
return super().check_xsrf_cookie()
except web.HTTPError as e:
Expand Down Expand Up @@ -608,11 +608,11 @@ async def prepare(self) -> Awaitable[None] | None: # type:ignore[override]
# check for overridden get_current_user + default IdentityProvider
# deprecated way to override auth (e.g. JupyterHub < 3.0)
# allow deprecated, overridden get_current_user
warnings.warn( # noqa
warnings.warn(
"Overriding JupyterHandler.get_current_user is deprecated in jupyter-server 2.0."
" Use an IdentityProvider class.",
DeprecationWarning,
# stacklevel not useful here
stacklevel=1,
)
user = User(self.get_current_user())
else:
Expand Down Expand Up @@ -695,7 +695,7 @@ def write_error(self, status_code: int, **kwargs: Any) -> None:
# get the custom message, if defined
try:
message = exception.log_message % exception.args
except Exception: # noqa
except Exception:
pass

# construct the custom reason, if defined
Expand Down
1 change: 0 additions & 1 deletion jupyter_server/base/websocket.py
Expand Up @@ -81,7 +81,6 @@ def check_origin(self, origin: Optional[str] = None) -> bool:

def clear_cookie(self, *args, **kwargs):
"""meaningless for websockets"""
pass

@no_type_check
def open(self, *args, **kwargs):
Expand Down
11 changes: 4 additions & 7 deletions jupyter_server/extension/application.py
Expand Up @@ -28,7 +28,7 @@ def _preparse_for_subcommand(application_klass, argv):
"""Preparse command line to look for subcommands."""
# Read in arguments from command line.
if len(argv) == 0:
return
return None

# Find any subcommands.
if application_klass.subcommands and len(argv) > 0:
Expand Down Expand Up @@ -218,7 +218,7 @@ def _default_serverapp(self):
if ServerApp.initialized():
try:
return ServerApp.instance()
except Exception: # noqa
except Exception:
# error retrieving instance, e.g. MultipleInstanceError
pass

Expand Down Expand Up @@ -271,7 +271,7 @@ def _default_static_url_prefix(self):

handlers: List[tuple[t.Any, ...]] = List(
help=_i18n("""Handlers appended to the server.""")
).tag(config=True) # type:ignore[assignment]
).tag(config=True)

def _config_file_name_default(self):
"""The default config file name."""
Expand All @@ -281,15 +281,12 @@ def _config_file_name_default(self):

def initialize_settings(self):
"""Override this method to add handling of settings."""
pass

def initialize_handlers(self):
"""Override this method to append handlers to a Jupyter Server."""
pass

def initialize_templates(self):
"""Override this method to add handling of template files."""
pass

def _prepare_config(self):
"""Builds a Config object from the extension's traits and passes
Expand Down Expand Up @@ -599,7 +596,7 @@ def launch_instance(cls, argv=None, **kwargs):
extension's landing page.
"""
# Handle arguments.
if argv is None: # noqa
if argv is None: # noqa: SIM108
args = sys.argv[1:] # slice out extension config.
else:
args = argv
Expand Down
8 changes: 2 additions & 6 deletions jupyter_server/extension/manager.py
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

import importlib
from itertools import starmap

from tornado.gen import multi
from traitlets import Any, Bool, Dict, HasTraits, Instance, List, Unicode, default, observe
Expand Down Expand Up @@ -392,12 +393,7 @@ def load_all_extensions(self):

async def stop_all_extensions(self):
"""Call the shutdown hooks in all extensions."""
await multi(
[
self.stop_extension(name, apps)
for name, apps in sorted(dict(self.extension_apps).items())
]
)
await multi(list(starmap(self.stop_extension, sorted(dict(self.extension_apps).items()))))

def any_activity(self):
"""Check for any activity currently happening across all extension applications."""
Expand Down
12 changes: 2 additions & 10 deletions jupyter_server/extension/utils.py
Expand Up @@ -7,26 +7,18 @@
class ExtensionLoadingError(Exception):
"""An extension loading error."""

pass


class ExtensionMetadataError(Exception):
"""An extension metadata error."""

pass


class ExtensionModuleNotFound(Exception):
"""An extension module not found error."""

pass


class NotAnExtensionApp(Exception):
"""An error raised when a module is not an extension."""

pass


def get_loader(obj, logger=None):
"""Looks for _load_jupyter_server_extension as an attribute
Expand All @@ -36,12 +28,12 @@ def get_loader(obj, logger=None):
underscore prefix.
"""
try:
return getattr(obj, "_load_jupyter_server_extension") # noqa B009
return obj._load_jupyter_server_extension
except AttributeError:
pass

try:
func = getattr(obj, "load_jupyter_server_extension") # noqa B009
func = obj.load_jupyter_server_extension
except AttributeError:
msg = "_load_jupyter_server_extension function was not found."
raise ExtensionLoadingError(msg) from None
Expand Down
2 changes: 1 addition & 1 deletion jupyter_server/gateway/connections.py
Expand Up @@ -104,7 +104,7 @@ async def _read_messages(self):

# NOTE(esevan): if websocket is not disconnected by client, try to reconnect.
if not self.disconnected and self.retry < GatewayClient.instance().gateway_retry_max:
jitter = random.randint(10, 100) * 0.01 # noqa
jitter = random.randint(10, 100) * 0.01
retry_interval = (
min(
GatewayClient.instance().gateway_retry_interval * (2**self.retry),
Expand Down