From a3e8118487987c15d4742ffe16243c08b2313e38 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Thu, 14 Dec 2023 13:49:31 -0600 Subject: [PATCH 1/2] Update ruff config --- .pre-commit-config.yaml | 10 ++------- docs/source/conf.py | 8 +++---- notebook/__init__.py | 2 -- notebook/_version.py | 2 +- notebook/app.py | 38 +++++++++++++++---------------- pyproject.toml | 50 ++++++++++++++++++++++++++--------------- tests/conftest.py | 8 +++---- tests/test_app.py | 4 ++-- 8 files changed, 63 insertions(+), 59 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b314cb3da6..25fa3f8999 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,16 +21,10 @@ repos: - id: trailing-whitespace - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.27.2 + rev: 0.27.3 hooks: - id: check-github-workflows - - repo: https://github.com/adamchainz/blacken-docs - rev: '1.16.0' - hooks: - - id: blacken-docs - additional_dependencies: [black==23.7.0] - - repo: https://github.com/codespell-project/codespell rev: 'v2.2.6' hooks: @@ -60,7 +54,7 @@ repos: - id: rst-inline-touching-normal - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.6 + rev: v0.1.8 hooks: - id: ruff types_or: [ python, jupyter ] diff --git a/docs/source/conf.py b/docs/source/conf.py index 3db3250e10..cc2d5cab1b 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -1,5 +1,3 @@ -#!/usr/bin/env python3 -# # Jupyter Notebook documentation build configuration file, created by # sphinx-quickstart on Mon Apr 13 09:51:11 2015. # @@ -73,7 +71,7 @@ ] try: - import enchant # type:ignore # noqa + import enchant # noqa: F401 extensions += ["sphinxcontrib.spelling"] except ImportError: @@ -97,7 +95,7 @@ # General information about the project. project = "Jupyter Notebook" -copyright = "2015, Jupyter Team, https://jupyter.org" # noqa +copyright = "2015, Jupyter Team, https://jupyter.org" author = "The Jupyter Team" # ghissue config @@ -109,7 +107,7 @@ # _version_py = os.path.join(here, "../../notebook/_version.py") version_ns = {} -exec(compile(open(_version_py).read(), _version_py, "exec"), version_ns) # noqa +exec(compile(open(_version_py).read(), _version_py, "exec"), version_ns) # noqa: S102, SIM115 # The short X.Y version. version = "%i.%i" % version_ns["version_info"][:2] # The full version, including alpha/beta/rc tags. diff --git a/notebook/__init__.py b/notebook/__init__.py index 8cb25b7c2b..ece3da96ff 100644 --- a/notebook/__init__.py +++ b/notebook/__init__.py @@ -2,8 +2,6 @@ from typing import Any -from ._version import __version__ # noqa - def _jupyter_server_extension_paths() -> list[dict[str, str]]: return [{"module": "notebook"}] diff --git a/notebook/_version.py b/notebook/_version.py index 599c8775a0..163acb184b 100644 --- a/notebook/_version.py +++ b/notebook/_version.py @@ -23,7 +23,7 @@ _version_fields = _version_regex.match(__version__).groupdict() # type:ignore[union-attr] -VersionInfo = namedtuple("VersionInfo", ["major", "minor", "micro", "releaselevel", "serial"]) +VersionInfo = namedtuple("VersionInfo", ["major", "minor", "micro", "releaselevel", "serial"]) # noqa: PYI024 version_info = VersionInfo( *[ diff --git a/notebook/app.py b/notebook/app.py index dffa397946..df155413db 100644 --- a/notebook/app.py +++ b/notebook/app.py @@ -4,7 +4,7 @@ import os import re import typing as t -from os.path import join as pjoin +from pathlib import Path from jupyter_client.utils import ensure_async # type:ignore[attr-defined] from jupyter_core.application import base_aliases @@ -36,11 +36,11 @@ from ._version import __version__ -HERE = os.path.dirname(__file__) +HERE = Path(__file__).parent.resolve() Flags = t.Dict[t.Union[str, t.Tuple[str, ...]], t.Tuple[t.Union[t.Dict[str, t.Any], Config], str]] -app_dir = get_app_dir() +app_dir = Path(get_app_dir()) version = __version__ # mypy: disable-error-code="no-untyped-call" @@ -72,7 +72,7 @@ def get_page_config(self) -> dict[str, t.Any]: server_root = self.settings.get("server_root_dir", "") server_root = server_root.replace(os.sep, "/") - server_root = os.path.normpath(os.path.expanduser(server_root)) + server_root = Path(server_root).expanduser().resolve() try: # Remove the server_root from pref dir if self.serverapp.preferred_dir != server_root: @@ -149,7 +149,7 @@ async def get(self, path: str = "") -> None: tpl = self.render_template("tree.html", page_config=page_config) return self.write(tpl) - elif await ensure_async(cm.file_exists(path)): + if await ensure_async(cm.file_exists(path)): # it's not a directory, we have redirecting to do model = await ensure_async(cm.get(path, content=False)) if model["type"] == "notebook": @@ -159,15 +159,15 @@ async def get(self, path: str = "") -> None: url = ujoin(self.base_url, "files", url_escape(path)) self.log.debug("Redirecting %s to %s", self.request.path, url) self.redirect(url) - else: - raise web.HTTPError(404) + return None + raise web.HTTPError(404) class ConsoleHandler(NotebookBaseHandler): """A console page handler.""" @web.authenticated - def get(self, path: str | None = None) -> t.Any: + def get(self, path: str | None = None) -> t.Any: # noqa: ARG002 """Get the console page.""" tpl = self.render_template("consoles.html", page_config=self.get_page_config()) return self.write(tpl) @@ -177,7 +177,7 @@ class TerminalHandler(NotebookBaseHandler): """A terminal page handler.""" @web.authenticated - def get(self, path: str | None = None) -> t.Any: + def get(self, path: str | None = None) -> t.Any: # noqa: ARG002 """Get the terminal page.""" tpl = self.render_template("terminals.html", page_config=self.get_page_config()) return self.write(tpl) @@ -187,7 +187,7 @@ class FileHandler(NotebookBaseHandler): """A file page handler.""" @web.authenticated - def get(self, path: str | None = None) -> t.Any: + def get(self, path: str | None = None) -> t.Any: # noqa: ARG002 """Get the file page.""" tpl = self.render_template("edit.html", page_config=self.get_page_config()) return self.write(tpl) @@ -197,7 +197,7 @@ class NotebookHandler(NotebookBaseHandler): """A notebook page handler.""" @web.authenticated - def get(self, path: str | None = None) -> t.Any: + def get(self, path: str | None = None) -> t.Any: # noqa: ARG002 """Get the notebook page.""" tpl = self.render_template("notebooks.html", page_config=self.get_page_config()) return self.write(tpl) @@ -214,13 +214,13 @@ def get(self) -> t.Any: page_config = self.get_page_config() custom_css_file = f"{page_config['jupyterConfigDir']}/custom/custom.css" - if not os.path.isfile(custom_css_file): + if not Path(custom_css_file).is_file(): static_path_root = re.match("^(.*?)static", page_config["staticDir"]) if static_path_root is not None: custom_dir = static_path_root.groups()[0] custom_css_file = f"{custom_dir}custom/custom.css" - with open(custom_css_file) as css_f: + with Path(custom_css_file).open() as css_f: return self.write(css_f.read()) @@ -269,23 +269,23 @@ class JupyterNotebookApp(NotebookConfigShimMixin, LabServerApp): # type:ignore[ @default("static_dir") def _default_static_dir(self) -> str: - return os.path.join(HERE, "static") + return str(HERE / "static") @default("templates_dir") def _default_templates_dir(self) -> str: - return os.path.join(HERE, "templates") + return str(HERE / "templates") @default("app_settings_dir") def _default_app_settings_dir(self) -> str: - return pjoin(app_dir, "settings") + return str(app_dir / "settings") @default("schemas_dir") def _default_schemas_dir(self) -> str: - return pjoin(app_dir, "schemas") + return str(app_dir / "schemas") @default("themes_dir") def _default_themes_dir(self) -> str: - return pjoin(app_dir, "themes") + return str(app_dir / "themes") @default("user_settings_dir") def _default_user_settings_dir(self) -> str: @@ -343,7 +343,7 @@ def initialize_handlers(self) -> None: self.handlers.append(("/custom/custom.css", CustomCssHandler)) super().initialize_handlers() - def initialize(self, argv: list[str] | None = None) -> None: + def initialize(self, argv: list[str] | None = None) -> None: # noqa: ARG002 """Subclass because the ExtensionApp.initialize() method does not take arguments""" super().initialize() diff --git a/pyproject.toml b/pyproject.toml index c7a5b01cb4..bdec1d591f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -231,38 +231,52 @@ source = ["notebook"] files = "notebook" python_version = "3.8" strict = true -hide_error_codes = false enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] warn_unreachable = true [tool.ruff] line-length = 100 +[tool.ruff.format] +docstring-code-format = true + [tool.ruff.lint] -select = [ - "A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "N", - "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP", - "W", "YTT", +extend-select = [ + "B", # flake8-bugbear + "I", # isort + "ARG", # flake8-unused-arguments + "C4", # flake8-comprehensions + "EM", # flake8-errmsg + "ICN", # flake8-import-conventions + "G", # flake8-logging-format + "PGH", # pygrep-hooks + "PIE", # flake8-pie + "PL", # pylint + "PTH", # flake8-use-pathlib + "PT", # flake8-pytest-style + "RET", # flake8-return + "RUF", # Ruff-specific + "SIM", # flake8-simplify + "T20", # flake8-print + "UP", # pyupgrade + "YTT", # flake8-2020 + "EXE", # flake8-executable + "PYI", # flake8-pyi + "S", # flake8-bandit ] ignore = [ -# Q000 Single quotes found but double quotes preferred -"Q000", -# FBT001 Boolean positional arg in function definition -"FBT001", "FBT002", "FBT003", -# C408 Unnecessary `dict` call (rewrite as a literal) -"C408", "C416", -# RUF012 Mutable class attributes should be annotated with `typing.ClassVar` -"RUF012", + "PLR", # Design related pylint codes + "C408", "C416", # Unnecessary `dict` call (rewrite as a literal) + "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` ] [tool.ruff.lint.per-file-ignores] # S101 Use of `assert` detected # F841 Local variable `foo` is assigned to but never used -# PLR2004 Magic value used in comparison -"tests/*" = ["S101", "F841", "PLR2004"] -# undefined name 'c' +"tests/*" = ["S101", "F841", "ARG", "PTH"] +"docs/source/conf.py" = ["PTH"] "ui-tests/test/jupyter_server_config.py" = ["F821"] -"*.ipynb" = ["E402", "B018", "E501", "T201"] +"*.ipynb" = ["E402", "B018", "E501", "T201", "RET"] [tool.interrogate] ignore-init-module=true @@ -275,4 +289,4 @@ fail-under=100 exclude = ["tests", "ui-tests", "docs", "node_modules", "setup.py"] [tool.repo-review] -ignore = ["PY007", "GH102", "PC180"] +ignore = ["GH102", "PC180", "PC111"] diff --git a/tests/conftest.py b/tests/conftest.py index bd80e70bf4..1376bd60d5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -32,8 +32,8 @@ def mkdir(tmp_path, *parts): labextensions_dir = pytest.fixture(lambda tmp_path: mkdir(tmp_path, "labextensions_dir")) -@pytest.fixture -def make_notebook_app( # noqa PLR0913 +@pytest.fixture() +def make_notebook_app( # PLR0913 jp_root_dir, jp_template_dir, app_settings_dir, @@ -92,7 +92,7 @@ def _make_notebook_app(**kwargs): ) # Copy the schema files. - test_data = str(files("jupyterlab_server.test_data")._paths[0]) # type: ignore + test_data = str(files("jupyterlab_server.test_data")._paths[0]) src = pathlib.PurePath(test_data, "schemas", "@jupyterlab") dst = pathlib.PurePath(str(schemas_dir), "@jupyterlab") if os.path.exists(dst): @@ -131,7 +131,7 @@ def _make_notebook_app(**kwargs): return _make_notebook_app -@pytest.fixture +@pytest.fixture() def notebookapp(jp_serverapp, make_notebook_app): app = make_notebook_app() app._link_jupyter_server_extension(jp_serverapp) diff --git a/tests/test_app.py b/tests/test_app.py index 3ec12b207a..86a3b994c7 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -6,7 +6,7 @@ from notebook.app import JupyterNotebookApp, TreeHandler -@pytest.fixture +@pytest.fixture() def notebooks(jp_create_notebook, notebookapp): nbpaths = ( "notebook1.ipynb", @@ -48,7 +48,7 @@ def redirect(self, url): nonlocal redirected_url redirected_url = url - TreeHandler.redirect = redirect # type:ignore + TreeHandler.redirect = redirect await jp_fetch("tree", "notebook1.ipynb") assert redirected_url == "/a%40b/notebooks/notebook1.ipynb" From ef9f19fbf56880d853c50a37d3995afc92877032 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 15 Dec 2023 06:43:34 -0600 Subject: [PATCH 2/2] cleanup --- notebook/__init__.py | 2 ++ notebook/app.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/notebook/__init__.py b/notebook/__init__.py index ece3da96ff..8eedd89778 100644 --- a/notebook/__init__.py +++ b/notebook/__init__.py @@ -2,6 +2,8 @@ from typing import Any +from ._version import __version__ # noqa: F401 + def _jupyter_server_extension_paths() -> list[dict[str, str]]: return [{"module": "notebook"}] diff --git a/notebook/app.py b/notebook/app.py index df155413db..832bb1f5bb 100644 --- a/notebook/app.py +++ b/notebook/app.py @@ -72,7 +72,7 @@ def get_page_config(self) -> dict[str, t.Any]: server_root = self.settings.get("server_root_dir", "") server_root = server_root.replace(os.sep, "/") - server_root = Path(server_root).expanduser().resolve() + server_root = os.path.normpath(Path(server_root).expanduser()) try: # Remove the server_root from pref dir if self.serverapp.preferred_dir != server_root: