Skip to content

Commit

Permalink
Update ruff and typing (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 authored Dec 1, 2023
1 parent dd5dfff commit 5c95f94
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 56 deletions.
9 changes: 5 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.27.1
rev: 0.27.2
hooks:
- id: check-github-workflows

Expand Down Expand Up @@ -52,7 +52,7 @@ repos:
args: ["-L", "sur,nd"]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.6.1"
rev: "v1.7.1"
hooks:
- id: mypy
files: "^jupyter_events"
Expand All @@ -77,7 +77,7 @@ repos:
- id: rst-inline-touching-normal

- 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 @@ -86,7 +86,8 @@ 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]"]
args: ["--ignore", "GH102"]
9 changes: 4 additions & 5 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@


# -- Project information -----------------------------------------------------

from typing import List
from __future__ import annotations

project = "jupyter_events"
copyright = "2019, Project Jupyter" # noqa
copyright = "2019, Project Jupyter"
author = "Project Jupyter"


Expand All @@ -29,10 +28,10 @@
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions: List = ["myst_parser", "jupyterlite_sphinx"]
extensions: list = ["myst_parser", "jupyterlite_sphinx"]

try:
import enchant # type:ignore # noqa
import enchant # noqa: F401

extensions += ["sphinxcontrib.spelling"]
except ImportError:
Expand Down
2 changes: 2 additions & 0 deletions docs/demo/demo-notebook.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"metadata": {},
"outputs": [],
"source": [
"from __future__ import annotations\n",
"\n",
"import piplite\n",
"\n",
"await piplite.install(\"jupyter_events\")"
Expand Down
7 changes: 4 additions & 3 deletions jupyter_events/_version.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
"""
store the current version info of jupyter-events.
"""
from __future__ import annotations

import re
from typing import List

# Version string must appear intact for hatch versioning
__version__ = "0.9.0"

# Build up version_info tuple for backwards compatibility
pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)"
match = re.match(pattern, __version__)
assert match is not None # noqa
parts: List[object] = [int(match[part]) for part in ["major", "minor", "patch"]]
assert match is not None
parts: list[object] = [int(match[part]) for part in ["major", "minor", "patch"]]
if match["rest"]:
parts.append(match["rest"])
version_info = tuple(parts)
Expand Down
3 changes: 2 additions & 1 deletion jupyter_events/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""The cli for jupyter events."""
from __future__ import annotations

import json
import pathlib
import platform
Expand Down Expand Up @@ -46,7 +48,6 @@ def main() -> None:
https://raw.githubusercontent.com/jupyter/jupyter_events/main/jupyter_events/schemas/event-metaschema.yml
"""
pass


@click.command()
Expand Down
8 changes: 3 additions & 5 deletions jupyter_events/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ class EventLogger(LoggingConfigurable):

async def gather_listeners(self) -> list[t.Any]:
"""Gather all of the active listeners."""
return await asyncio.gather( # type:ignore[no-any-return]
*self._active_listeners, return_exceptions=True
)
return await asyncio.gather(*self._active_listeners, return_exceptions=True)

@default("schemas")
def _default_schemas(self) -> SchemaRegistry:
Expand All @@ -120,8 +118,8 @@ def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
def _load_config(
self,
cfg: Config,
section_names: list[str] | None = None,
traits: list[str] | None = None, # type:ignore[override]
section_names: list[str] | None = None, # noqa: ARG002
traits: list[str] | None = None, # type:ignore[override] # noqa: ARG002
) -> None:
"""Load EventLogger traits from a Config object, patching the
handlers trait in the Config object to avoid deepcopy errors.
Expand Down
16 changes: 5 additions & 11 deletions jupyter_events/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import json
from pathlib import Path, PurePath
from typing import Any, Union
from typing import Any, Dict, Union

from jsonschema import FormatChecker, validators
from referencing import Registry
Expand All @@ -18,25 +18,19 @@
from .validators import draft7_format_checker, validate_schema


class EventSchemaUnrecognized(Exception): # noqa
class EventSchemaUnrecognized(Exception):
"""An error for an unrecognized event schema."""

pass


class EventSchemaLoadingError(Exception):
"""An error for an event schema loading error."""

pass


class EventSchemaFileAbsent(Exception): # noqa
class EventSchemaFileAbsent(Exception):
"""An error for an absent event schema file."""

pass


SchemaType = Union[dict, str, PurePath]
SchemaType = Union[Dict[str, Any], str, PurePath]


class EventSchema:
Expand Down Expand Up @@ -141,7 +135,7 @@ def _load_schema(schema: SchemaType) -> dict[str, Any]:
raise EventSchemaUnrecognized(msg)

@property
def id(self) -> str: # noqa
def id(self) -> str:
"""Schema $id field."""
return self._schema["$id"] # type:ignore[no-any-return]

Expand Down
2 changes: 1 addition & 1 deletion jupyter_events/schema_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .schema import EventSchema


class SchemaRegistryException(Exception): # noqa: N818
class SchemaRegistryException(Exception):
"""Exception class for Jupyter Events Schema Registry Errors."""


Expand Down
6 changes: 3 additions & 3 deletions jupyter_events/traits.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ def validate(self, obj: t.Any, value: t.Any) -> t.Any:
return out
# If a list, check it's elements to verify
# that each element is a logging handler instance.
elif isinstance(value, list):
if isinstance(value, list):
self.validate_elements(obj, value)
return value
else:
self.error(obj, value)
self.error(obj, value)
return None # type:ignore[unreachable]
50 changes: 33 additions & 17 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -152,35 +152,49 @@ source = ["jupyter_events"]
files = "jupyter_events"
python_version = "3.8"
strict = true
show_error_codes = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true

[tool.ruff]
line-length = 100

[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",
# E501 Line too long (158 > 100 characters)
"E501",
# SIM105 Use `contextlib.suppress(...)`
"SIM105",
"E501", # E501 Line too long (158 > 100 characters)
"SIM105", # SIM105 Use `contextlib.suppress(...)`
"PLR", # Design related pylint codes
"S101", # Use of `assert` detected
]
unfixable = [
# Don't touch print statements
"T201",
# Don't touch noqa lines
"RUF100",
]
isort.required-imports = ["from __future__ import annotations"]

[tool.ruff.lint.per-file-ignores]
# B011 Do not call assert False since python -O removes these calls
Expand All @@ -192,11 +206,16 @@ unfixable = [
# N802 Function name `assertIn` should be lowercase
# F841 Local variable `t` is assigned to but never used
# S101 Use of `assert` detected
"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "F841", "S101"]
"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802", "F841", "S101", "ARG", "PGH"]
# C901 Function is too complex
"jupyter_events/logger.py" = ["C901"] # `emit` is too complex (12 > 10)
"docs/demo/demo-notebook.ipynb" = ["PLE1142", "E402", "T201"]

[tool.ruff.lint.flake8-pytest-style]
fixture-parentheses = false
mark-parentheses = false
parametrize-names-type = "csv"

[tool.interrogate]
ignore-init-module=true
ignore-private=true
Expand All @@ -206,6 +225,3 @@ ignore-nested-functions=true
ignore-nested-classes=true
fail-under=100
exclude = ["docs", "tests"]

[tool.repo-review]
ignore = ["PY007", "GH102"]
2 changes: 2 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from __future__ import annotations

pytest_plugins = ["jupyter_events.pytest_plugin"]
2 changes: 2 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import os

import pytest
Expand Down
4 changes: 3 additions & 1 deletion tests/test_listeners.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import io
import logging

Expand Down Expand Up @@ -42,7 +44,7 @@ async def test_listener_function_str_annotations(jp_event_logger, schema):
event_logger = jp_event_logger
listener_was_called = False

async def my_listener(logger: "EventLogger", schema_id: "str", data: "dict") -> "None":
async def my_listener(logger: EventLogger, schema_id: str, data: dict) -> None:
nonlocal listener_was_called
listener_was_called = True

Expand Down
5 changes: 3 additions & 2 deletions tests/test_logger.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import io
import json
import logging
Expand Down Expand Up @@ -40,8 +42,7 @@ def get_config_from_file(path, content):

# Load written file.
loader = PyFileConfigLoader(filename, path=str(path))
cfg = loader.load_config()
return cfg
return loader.load_config()


def test_good_config_file(tmp_path):
Expand Down
2 changes: 2 additions & 0 deletions tests/test_modifiers.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import pytest

from jupyter_events.schema import EventSchema
Expand Down
8 changes: 5 additions & 3 deletions tests/test_schema.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import os
from pathlib import Path

Expand Down Expand Up @@ -31,7 +33,7 @@ def test_bad_validations(schema_file, validation_error_msg):
a redactionPolicies field.
"""
# Read the schema file
with open(SCHEMA_PATH / "bad" / schema_file) as f:
with Path.open(SCHEMA_PATH / "bad" / schema_file) as f:
schema = yaml.loads(f)
# Assert that the schema files for a known reason.
with pytest.raises(ValidationError) as err:
Expand All @@ -49,7 +51,7 @@ def test_string_intended_as_path():
"""Ensure EventSchema returns a helpful error message if user passes a
string intended as a Path."""
expected_msg_contents = "Paths to schema files must be explicitly wrapped in a Pathlib object."
str_path = os.path.join(SCHEMA_PATH, "good", "some_schema.yaml")
str_path = os.path.join(SCHEMA_PATH, "good", "some_schema.yaml") # noqa: PTH118
with pytest.raises(EventSchemaLoadingError) as e:
EventSchema(str_path)

Expand Down Expand Up @@ -79,7 +81,7 @@ def test_valid_json():
def test_good_validations(schema_file):
"""Ensure validation passes for good schemas."""
# Read the schema file
with open(SCHEMA_PATH / "good" / schema_file) as f:
with Path.open(SCHEMA_PATH / "good" / schema_file) as f:
schema = yaml.loads(f)
# assert that no exception gets raised
validate_schema(schema)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_traits.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import logging

import pytest
Expand Down
2 changes: 2 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import io
import json
import logging
Expand Down

0 comments on commit 5c95f94

Please sign in to comment.