Skip to content

Commit 5b3f366

Browse files
authored
Add more ci checks (#42)
1 parent dd46a84 commit 5b3f366

File tree

11 files changed

+71
-11
lines changed

11 files changed

+71
-11
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ jobs:
4747
steps:
4848
- uses: actions/checkout@v3
4949
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
50+
- name: Install Dependencies
51+
run: |
52+
sudo apt-get update
53+
sudo apt-get install enchant-2 # for spell checking
5054
- run: hatch run docs:build
5155

5256
test_lint:
@@ -59,7 +63,7 @@ jobs:
5963
run: |
6064
hatch run typing:test
6165
hatch run lint:style
62-
pipx run 'validate-pyproject[all]' pyproject.toml
66+
pipx run interrogate -v .
6367
pipx run doc8 --max-line-length=200 --ignore-path=docs/source/other/full-config.rst
6468
6569
test_minimum_versions:

.pre-commit-config.yaml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ repos:
55
- repo: https://github.com/pre-commit/pre-commit-hooks
66
rev: v4.4.0
77
hooks:
8-
- id: end-of-file-fixer
98
- id: check-case-conflict
9+
- id: check-ast
10+
- id: check-docstring-first
1011
- id: check-executables-have-shebangs
11-
- id: requirements-txt-fixer
1212
- id: check-added-large-files
1313
- id: check-case-conflict
14+
- id: check-merge-conflict
15+
- id: check-json
1416
- id: check-toml
1517
- id: check-yaml
1618
- id: debug-statements
17-
- id: forbid-new-submodules
18-
- id: check-builtin-literals
19+
- id: end-of-file-fixer
1920
- id: trailing-whitespace
2021

2122
- repo: https://github.com/python-jsonschema/check-jsonschema
@@ -34,7 +35,7 @@ repos:
3435
- id: black
3536

3637
- repo: https://github.com/charliermarsh/ruff-pre-commit
37-
rev: v0.0.165
38+
rev: v0.0.189
3839
hooks:
3940
- id: ruff
4041
args: ["--fix"]

docs/conf.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232
"sphinx.ext.autodoc",
3333
]
3434

35+
try:
36+
import enchant # type:ignore # noqa
37+
38+
extensions += ["sphinxcontrib.spelling"]
39+
except ImportError:
40+
pass
41+
42+
3543
# Autodoc fixtures
3644
# If true, the current module name will be prepended to all description
3745
# unit titles (such as .. function::).

pyproject.toml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ docs = [
3838
"myst_parser",
3939
"pydata_sphinx_theme",
4040
"Sphinx",
41+
"sphinxcontrib-spelling"
4142
]
4243
client = [
4344
"jupyter_client>=7.4.0",
@@ -52,9 +53,9 @@ test = [
5253
"pytest-timeout"
5354
]
5455
lint = [
55-
"black>=22.6.0",
56+
"black[jupyter]==22.10.0",
5657
"mdformat>0.7",
57-
"ruff>=0.0.156",
58+
"ruff==0.0.189",
5859
]
5960
typing = [
6061
"mypy>=0.990"
@@ -216,3 +217,13 @@ unfixable = [
216217
# B007 Loop control variable `i` not used within the loop body.
217218
# N802 Function name `assertIn` should be lowercase
218219
"tests/*" = ["B011", "F841", "C408", "E402", "T201", "B007", "N802"]
220+
221+
[tool.interrogate]
222+
ignore-init-module=true
223+
ignore-private=true
224+
ignore-semiprivate=true
225+
ignore-property-decorators=true
226+
ignore-nested-functions=true
227+
ignore-nested-classes=true
228+
fail-under=100
229+
exclude = ["docs", "tests"]

pytest_jupyter/_version.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Version info for pytest_jupyter."""
12
# Copyright (c) Jupyter Development Team.
23
# Distributed under the terms of the Modified BSD License.
34

pytest_jupyter/echo_kernel.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""A simple echo kernel."""
12
# Copyright (c) Jupyter Development Team.
23
# Distributed under the terms of the Modified BSD License.
34

@@ -8,6 +9,8 @@
89

910

1011
class EchoKernel(Kernel):
12+
"""An echo kernel."""
13+
1114
implementation = "Echo"
1215
implementation_version = "1.0"
1316
language = "echo"
@@ -22,6 +25,7 @@ class EchoKernel(Kernel):
2225
def do_execute(
2326
self, code, silent, store_history=True, user_expressions=None, allow_stdin=False
2427
):
28+
"""Execute code on the kernel."""
2529
if not silent:
2630
stream_content = {"name": "stdout", "text": code}
2731
self.send_response(self.iopub_socket, "stream", stream_content)
@@ -45,6 +49,8 @@ def do_execute(
4549

4650

4751
class EchoKernelApp(IPKernelApp):
52+
"""An app for the echo kernel."""
53+
4854
kernel_class = EchoKernel
4955

5056

pytest_jupyter/jupyter_client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Fixtures for use with jupyter_client and downstream."""
12
# Copyright (c) Jupyter Development Team.
23
# Distributed under the terms of the Modified BSD License.
34

@@ -24,6 +25,7 @@
2425

2526
@pytest.fixture
2627
def jp_zmq_context():
28+
"""Get a zmq context."""
2729
import zmq
2830

2931
ctx = zmq.asyncio.Context()
@@ -33,10 +35,12 @@ def jp_zmq_context():
3335

3436
@pytest.fixture
3537
def jp_start_kernel(jp_environ, jp_asyncio_loop):
38+
"""Get a function to a kernel and clean up resources when done."""
3639
kms = []
3740
kcs = []
3841

3942
async def inner(kernel_name=NATIVE_KERNEL_NAME, **kwargs):
43+
"""A function used to start a kernel."""
4044
km, kc = await start_new_async_kernel(kernel_name=kernel_name, **kwargs)
4145
kms.append(km)
4246
kcs.append(kc)

pytest_jupyter/jupyter_core.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Fixtures for use with jupyter core and downstream."""
12
# Copyright (c) Jupyter Development Team.
23
# Distributed under the terms of the Modified BSD License.
34
import asyncio
@@ -35,6 +36,7 @@
3536

3637
@pytest.fixture
3738
def jp_asyncio_loop():
39+
"""Get an asyncio loop."""
3840
if os.name == "nt":
3941
asyncio.set_event_loop_policy(
4042
asyncio.WindowsSelectorEventLoopPolicy() # type:ignore[attr-defined]
@@ -51,6 +53,7 @@ def io_loop(jp_asyncio_loop):
5153
if tornado is not installed."""
5254

5355
async def get_tornado_loop():
56+
"""Asynchronously get a tornado loop."""
5457
try:
5558
from tornado.ioloop import IOLoop
5659

@@ -111,11 +114,13 @@ def jp_env_config_path(tmp_path):
111114

112115
@pytest.fixture()
113116
def jp_kernel_dir(jp_data_dir):
117+
"""Get the directory for kernel specs."""
114118
return mkdir(jp_data_dir, "kernels")
115119

116120

117121
@pytest.fixture
118122
def echo_kernel_spec(jp_kernel_dir):
123+
"""Install a kernel spec for the echo kernel."""
119124
test_dir = Path(jp_kernel_dir) / "echo"
120125
test_dir.mkdir(parents=True, exist_ok=True)
121126
argv = [sys.executable, "-m", "pytest_jupyter.echo_kernel", "-f", "{connection_file}"]

pytest_jupyter/jupyter_server.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""Fixtures for use with jupyter server and downstream."""
12
# Copyright (c) Jupyter Development Team.
23
# Distributed under the terms of the Modified BSD License.
34

@@ -59,6 +60,7 @@ def http_server(io_loop, http_server_port, jp_web_app):
5960
"""Start a tornado HTTP server that listens on all available interfaces."""
6061

6162
async def get_server():
63+
"""Get a server asynchronously."""
6264
server = tornado.httpserver.HTTPServer(jp_web_app)
6365
server.add_socket(http_server_port[0])
6466
return server
@@ -385,6 +387,7 @@ def inner(nbpath):
385387

386388
@pytest.fixture(autouse=True)
387389
def jp_server_cleanup(jp_asyncio_loop):
390+
"""Automatically cleans up server resources."""
388391
yield
389392
app: ServerApp = ServerApp.instance()
390393
try:
@@ -422,6 +425,7 @@ async def _(url, **fetch_kwargs):
422425

423426
@pytest.fixture
424427
def jp_server_auth_core_resources():
428+
"""The core auth resources for use with a server."""
425429
modules = []
426430
for mod_name in JUPYTER_SERVICE_HANDLERS.values():
427431
if mod_name:
@@ -438,10 +442,13 @@ def jp_server_auth_core_resources():
438442

439443
@pytest.fixture
440444
def jp_server_auth_resources(jp_server_auth_core_resources):
445+
"""The auth resources used by the server."""
441446
return jp_server_auth_core_resources
442447

443448

444449
class _Authorizer(Authorizer):
450+
"""A custom authorizer class for testing."""
451+
445452
# Set these class attributes from within a test
446453
# to verify that they match the arguments passed
447454
# by the REST API.
@@ -484,6 +491,7 @@ def normalize_url(self, path):
484491
return path
485492

486493
def is_authorized(self, handler, user, action, resource):
494+
"""Test if a request is authorized."""
487495
# Parse Request
488496
if isinstance(handler, WebSocketHandler):
489497
method = "WEBSOCKET"
@@ -511,6 +519,7 @@ def is_authorized(self, handler, user, action, resource):
511519

512520
@pytest.fixture
513521
def jp_server_authorizer(jp_server_auth_resources):
522+
"""An authorizer for the server."""
514523
auth_klass = _Authorizer
515524
auth_klass._default_regex_mapping = jp_server_auth_resources
516525
return auth_klass

pytest_jupyter/pytest_tornasync.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Vendored fork of pytest_tornasync from
2-
# https://github.com/eukaryote/pytest-tornasync/blob/9f1bdeec3eb5816e0183f975ca65b5f6f29fbfbb/src/pytest_tornasync/plugin.py
3-
1+
"""Vendored fork of pytest_tornasync from
2+
https://github.com/eukaryote/pytest-tornasync/blob/9f1bdeec3eb5816e0183f975ca65b5f6f29fbfbb/src/pytest_tornasync/plugin.py
3+
"""
44
from contextlib import closing
55
from inspect import iscoroutinefunction
66

@@ -16,12 +16,14 @@
1616

1717
@pytest.hookimpl(tryfirst=True)
1818
def pytest_pycollect_makeitem(collector, name, obj):
19+
"""Custom pytest collection hook."""
1920
if collector.funcnamefilter(name) and iscoroutinefunction(obj):
2021
return list(collector._genfunctions(name, obj))
2122

2223

2324
@pytest.hookimpl(tryfirst=True)
2425
def pytest_pyfunc_call(pyfuncitem):
26+
"""Custom pytest function call hook."""
2527
funcargs = pyfuncitem.funcargs
2628
testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames}
2729

@@ -53,6 +55,7 @@ def http_server_client(http_server, io_loop):
5355
"""
5456

5557
async def get_client():
58+
"""Get a client."""
5659
return AsyncHTTPServerClient(http_server=http_server)
5760

5861
client = io_loop.run_sync(get_client)
@@ -61,7 +64,10 @@ async def get_client():
6164

6265

6366
class AsyncHTTPServerClient(SimpleAsyncHTTPClient):
67+
"""An async http server client."""
68+
6469
def initialize(self, *, http_server=None):
70+
"""Initialize the client."""
6571
super().initialize()
6672
self._http_server = http_server
6773

@@ -73,11 +79,14 @@ def fetch(self, path, **kwargs):
7379
return super().fetch(self.get_url(path), **kwargs)
7480

7581
def get_protocol(self):
82+
"""Get the protocol for the client."""
7683
return "http"
7784

7885
def get_http_port(self):
86+
"""Get a port for the client."""
7987
for sock in self._http_server._sockets.values():
8088
return sock.getsockname()[1]
8189

8290
def get_url(self, path):
91+
"""Get the url for the client."""
8392
return f"{self.get_protocol()}://127.0.0.1:{self.get_http_port()}{path}"

0 commit comments

Comments
 (0)