Skip to content

Commit e252fed

Browse files
authored
Adopt ruff and address lint (#69)
1 parent 26c2e83 commit e252fed

File tree

9 files changed

+115
-81
lines changed

9 files changed

+115
-81
lines changed

.github/dependabot.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
version: 2
22
updates:
3-
# Set update schedule for GitHub Actions
43
- package-ecosystem: "github-actions"
54
directory: "/"
65
schedule:
7-
# Check for updates to GitHub Actions every weekday
6+
interval: "weekly"
7+
- package-ecosystem: "pip"
8+
directory: "/"
9+
schedule:
810
interval: "weekly"

.github/workflows/test.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,18 @@ defaults:
1212
shell: bash -eux {0}
1313

1414
jobs:
15-
pre_commit:
15+
test_lint:
16+
name: Test Lint
1617
runs-on: ubuntu-latest
1718
steps:
1819
- uses: actions/checkout@v3
1920
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
20-
- uses: jupyterlab/maintainer-tools/.github/actions/pre-commit@v1
21+
- name: Run Linters
22+
run: |
23+
hatch run typing:test
24+
hatch run lint:style
25+
pipx run 'validate-pyproject[all]' pyproject.toml
26+
pipx run doc8 --max-line-length=200
2127
2228
test:
2329
runs-on: ${{ matrix.os }}
@@ -128,7 +134,7 @@ jobs:
128134
if: always()
129135
needs:
130136
- test
131-
- pre_commit
137+
- test_lint
132138
- test_docs
133139
- test_minimum_versions
134140
- test_prereleases

.pre-commit-config.yaml

Lines changed: 14 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
ci:
2+
autoupdate_schedule: monthly
3+
14
repos:
25
- repo: https://github.com/pre-commit/pre-commit-hooks
36
rev: v4.4.0
@@ -15,62 +18,25 @@ repos:
1518
- id: check-builtin-literals
1619
- id: trailing-whitespace
1720

18-
- repo: https://github.com/psf/black
19-
rev: 22.10.0
20-
hooks:
21-
- id: black
22-
args: ["--line-length", "100"]
23-
24-
- repo: https://github.com/PyCQA/isort
25-
rev: 5.10.1
26-
hooks:
27-
- id: isort
28-
files: \.py$
29-
args: [--profile=black]
30-
31-
- repo: https://github.com/abravalheri/validate-pyproject
32-
rev: v0.10.1
21+
- repo: https://github.com/python-jsonschema/check-jsonschema
22+
rev: 0.19.2
3323
hooks:
34-
- id: validate-pyproject
35-
stages: [manual]
24+
- id: check-github-workflows
3625

3726
- repo: https://github.com/executablebooks/mdformat
3827
rev: 0.7.16
3928
hooks:
4029
- id: mdformat
41-
42-
- repo: https://github.com/asottile/pyupgrade
43-
rev: v3.3.0
44-
hooks:
45-
- id: pyupgrade
46-
args: [--py38-plus]
47-
48-
- repo: https://github.com/PyCQA/doc8
49-
rev: v1.0.0
50-
hooks:
51-
- id: doc8
52-
args: [--max-line-length=200]
53-
stages: [manual]
54-
55-
- repo: https://github.com/john-hen/Flake8-pyproject
56-
rev: 1.2.2
57-
hooks:
58-
- id: Flake8-pyproject
59-
alias: flake8
6030
additional_dependencies:
61-
["flake8-bugbear==22.6.22", "flake8-implicit-str-concat==0.2.0"]
62-
stages: [manual]
31+
[mdformat-gfm, mdformat-frontmatter, mdformat-footnote]
6332

64-
- repo: https://github.com/pre-commit/mirrors-mypy
65-
rev: v0.991
33+
- repo: https://github.com/psf/black
34+
rev: 22.10.0
6635
hooks:
67-
- id: mypy
68-
exclude: jupyter_client/tests
69-
args: ["--config-file", "pyproject.toml"]
70-
additional_dependencies: [tornado, pytest, traitlets, jupyter_server>=2.0.0rc5, terminado]
71-
stages: [manual]
36+
- id: black
7237

73-
- repo: https://github.com/python-jsonschema/check-jsonschema
74-
rev: 0.19.2
38+
- repo: https://github.com/charliermarsh/ruff-pre-commit
39+
rev: v0.0.165
7540
hooks:
76-
- id: check-github-workflows
41+
- id: ruff
42+
args: ["--fix"]

jupyter_server_terminals/api_handlers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from jupyter_server.auth.decorator import authorized
1111
from jupyter_server.base.handlers import APIHandler
1212
except ModuleNotFoundError:
13-
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.")
13+
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.") from None
1414

1515

1616
AUTH_RESOURCE = "terminals"

jupyter_server_terminals/app.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
from .terminalmanager import TerminalManager
1010

1111
try:
12+
from jupyter_core.utils import ensure_async
1213
from jupyter_server.extension.application import ExtensionApp
1314
from jupyter_server.transutils import trans
14-
from jupyter_server.utils import ensure_async
1515
except ModuleNotFoundError:
16-
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.")
16+
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.") from None
1717

1818

1919
class TerminalsExtensionApp(ExtensionApp):
@@ -35,7 +35,9 @@ class TerminalsExtensionApp(ExtensionApp):
3535

3636
def initialize_settings(self):
3737
self.initialize_configurables()
38-
self.settings.update(dict(terminals_available=True, terminal_manager=self.terminal_manager))
38+
self.settings.update(
39+
{"terminals_available": True, "terminal_manager": self.terminal_manager}
40+
)
3941

4042
def initialize_configurables(self):
4143
if os.name == "nt":

jupyter_server_terminals/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
try:
22
from jupyter_server.extension.handler import ExtensionHandlerMixin
33
except ModuleNotFoundError:
4-
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.")
4+
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.") from None
55

66

77
class TerminalsMixin(ExtensionHandlerMixin):

jupyter_server_terminals/handlers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from jupyter_server.base.handlers import JupyterHandler
1313
from jupyter_server.base.websocket import WebSocketMixin
1414
except ModuleNotFoundError:
15-
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.")
15+
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.") from None
1616

1717
AUTH_RESOURCE = "terminals"
1818

@@ -44,7 +44,7 @@ def get(self, *args, **kwargs):
4444
elif not self.authorizer.is_authorized(self, user, "execute", self.auth_resource):
4545
raise web.HTTPError(403)
4646

47-
if not args[0] in self.term_manager.terminals:
47+
if args[0] not in self.term_manager.terminals:
4848
raise web.HTTPError(404)
4949
return super().get(*args, **kwargs)
5050

jupyter_server_terminals/terminalmanager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
TERMINAL_CURRENTLY_RUNNING_TOTAL,
1919
)
2020
except ModuleNotFoundError:
21-
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.")
21+
raise ModuleNotFoundError("Jupyter Server must be installed to use this extension.") from None
2222

2323

2424
class TerminalManager(LoggingConfigurable, NamedTermManager): # type:ignore[misc]
@@ -86,7 +86,7 @@ async def terminate(self, name, force=False):
8686

8787
async def terminate_all(self):
8888
"""Terminate all terminals."""
89-
terms = [name for name in self.terminals]
89+
terms = list(self.terminals)
9090
for term in terms:
9191
await self.terminate(term, force=True)
9292

pyproject.toml

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Homepage = "https://jupyter.org"
3636
[project.optional-dependencies]
3737
test = [
3838
"coverage",
39-
"jupyter_server>=2.0.0rc8",
39+
"jupyter_server>=2.0.0",
4040
"pytest-jupyter[server]>=0.5.3",
4141
"pytest>=7.0",
4242
"pytest-cov",
@@ -55,14 +55,20 @@ docs = [
5555
"sphinxcontrib_github_alt",
5656
"sphinxemoji",
5757
]
58+
lint = [
59+
"black[jupyter]>=22.6.0",
60+
"mdformat>0.7",
61+
"mdformat-gfm>=0.3.5",
62+
"ruff>=0.0.156"
63+
]
64+
typing = ["mypy>=0.990"]
5865

5966
[tool.hatch.version]
6067
path = "jupyter_server_terminals/_version.py"
6168

6269
[tool.hatch.build.targets.wheel.shared-data]
6370
"jupyter-config" = "etc/jupyter/jupyter_server_config.d"
6471

65-
6672
[tool.hatch.envs.docs]
6773
features = ["docs"]
6874
[tool.hatch.envs.docs.scripts]
@@ -81,6 +87,25 @@ dependencies = ["coverage", "pytest-cov"]
8187
test = "python -m pytest -vv --cov jupyter_server_terminals --cov-branch --cov-report term-missing:skip-covered {args}"
8288
nowarn = "test -W default {args}"
8389

90+
[tool.hatch.envs.typing]
91+
features = ["typing", "test"]
92+
[tool.hatch.envs.typing.scripts]
93+
test = "mypy --install-types --non-interactive {args:jupyter_server_terminals tests}"
94+
95+
[tool.hatch.envs.lint]
96+
features = ["lint"]
97+
[tool.hatch.envs.lint.scripts]
98+
style = [
99+
"ruff {args:.}",
100+
"black --check --diff {args:.}",
101+
"mdformat --check {args:docs *.md}"
102+
]
103+
fmt = [
104+
"black {args:.}",
105+
"ruff --fix {args:.}",
106+
"mdformat {args:docs *.md}"
107+
]
108+
84109
[tool.pytest.ini_options]
85110
addopts = "-raXs --durations 10 --color=yes --doctest-modules"
86111
testpaths = [
@@ -114,23 +139,56 @@ warn_redundant_casts = true
114139
warn_return_any = true
115140
warn_unused_ignores = true
116141

117-
[tool.flake8]
118-
ignore = "E501, W503, E402"
119-
builtins = "c, get_config"
120-
exclude = [
121-
".cache",
122-
".github",
123-
"docs",
124-
"setup.py",
142+
[tool.black]
143+
line-length = 100
144+
skip-string-normalization = true
145+
target-version = ["py37"]
146+
147+
[tool.ruff]
148+
target-version = "py37"
149+
line-length = 100
150+
select = [
151+
"A", "B", "C", "E", "F", "FBT", "I", "N", "Q", "RUF", "S", "T",
152+
"UP", "W", "YTT",
125153
]
126-
enable-extensions = "G"
127-
extend-ignore = [
128-
"G001", "G002", "G004", "G200", "G201", "G202",
129-
# black adds spaces around ':'
130-
"E203",
154+
ignore = [
155+
# Allow non-abstract empty methods in abstract base classes
156+
"B027",
157+
# Ignore McCabe complexity
158+
"C901",
159+
# Allow boolean positional values in function calls, like `dict.get(... True)`
160+
"FBT003",
161+
# Use of `assert` detected
162+
"S101",
163+
# Line too long
164+
"E501",
165+
# Relative imports are banned
166+
"I252",
167+
# Boolean ... in function definition
168+
"FBT001", "FBT002",
169+
# Module level import not at top of file
170+
"E402",
171+
# A001/A002/A003 .. is shadowing a python builtin
172+
"A001", "A002", "A003",
173+
# Possible hardcoded password
174+
"S105", "S106",
175+
# Q000 Single quotes found but double quotes preferred
176+
"Q000",
177+
# N806 Variable `B` in function should be lowercase
178+
"N806",
179+
# T201 `print` found
180+
"T201",
181+
# N802 Function name `CreateWellKnownSid` should be lowercase
182+
"N802", "N803"
131183
]
132-
per-file-ignores = [
133-
# B011: Do not call assert False since python -O removes these calls
134-
# F841 local variable 'foo' is assigned to but never used
135-
"tests/*: B011", "F841",
184+
unfixable = [
185+
# Don't touch print statements
186+
"T201",
187+
# Don't touch noqa lines
188+
"RUF100",
136189
]
190+
191+
[tool.ruff.per-file-ignores]
192+
# B011: Do not call assert False since python -O removes these calls
193+
# F841 local variable 'foo' is assigned to but never used
194+
"tests/*" = ["B011", "F841"]

0 commit comments

Comments
 (0)