mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-10-06 09:24:40 +01:00
Add BasedPyright + Makefile commands (#858)
This commit is contained in:
@@ -30,6 +30,12 @@ jobs:
|
||||
- name: Check backend formatting
|
||||
run: uv run ruff format --check shelfmark
|
||||
|
||||
- name: Typecheck backend
|
||||
run: uv run basedpyright
|
||||
|
||||
- name: Check backend dead code
|
||||
run: uv run vulture shelfmark
|
||||
|
||||
- name: Run tests
|
||||
run: uv run pytest tests/ -x --tb=short
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.PHONY: help install install-python-dev dev build preview typecheck frontend-test clean up up down docker-build refresh restart build-serve python-lint python-lint-fix python-format python-format-check
|
||||
.PHONY: help install install-python-dev dev build preview typecheck frontend-test clean up up down docker-build refresh restart build-serve python-lint python-lint-fix python-format python-format-check python-typecheck python-dead-code python-checks
|
||||
|
||||
# Frontend directory
|
||||
FRONTEND_DIR := src/frontend
|
||||
@@ -23,6 +23,9 @@ help:
|
||||
@echo " python-lint-fix - Run Ruff with safe auto-fixes"
|
||||
@echo " python-format - Format Python backend code with Ruff"
|
||||
@echo " python-format-check - Check Python backend formatting with Ruff"
|
||||
@echo " python-typecheck - Run BasedPyright against Python backend code"
|
||||
@echo " python-dead-code - Run Vulture against Python backend code"
|
||||
@echo " python-checks - Run all Python static analysis checks"
|
||||
@echo " clean - Remove node_modules and build artifacts"
|
||||
@echo ""
|
||||
@echo "Backend (Docker):"
|
||||
@@ -86,6 +89,16 @@ python-format-check:
|
||||
@echo "Checking Python backend formatting with Ruff..."
|
||||
uv run ruff format --check shelfmark
|
||||
|
||||
python-typecheck:
|
||||
@echo "Running BasedPyright..."
|
||||
uv run basedpyright
|
||||
|
||||
python-dead-code:
|
||||
@echo "Running Vulture..."
|
||||
uv run vulture shelfmark
|
||||
|
||||
python-checks: python-lint python-format-check python-typecheck python-dead-code
|
||||
|
||||
# Run frontend unit tests
|
||||
frontend-test:
|
||||
@echo "Running frontend unit tests..."
|
||||
|
||||
+3
-2
@@ -35,10 +35,11 @@ browser = [
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"pyright>=1.1.408",
|
||||
"basedpyright>=1.39.0",
|
||||
"pytest",
|
||||
"pytest-xdist>=3.8.0",
|
||||
"ruff==0.15.10",
|
||||
"vulture>=2.14",
|
||||
]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
@@ -77,7 +78,7 @@ select = [
|
||||
]
|
||||
ignore = ["UP035", "TRY003", "E501"]
|
||||
|
||||
[tool.pyright]
|
||||
[tool.basedpyright]
|
||||
include = ["shelfmark"]
|
||||
exclude = [".local", "tests", "**/__pycache__", "**/node_modules"]
|
||||
pythonVersion = "3.14"
|
||||
|
||||
@@ -221,6 +221,10 @@ Log level is configurable via Settings or `LOG_LEVEL` environment variable.
|
||||
## Development
|
||||
|
||||
```bash
|
||||
# Python tooling
|
||||
make install-python-dev # Sync Python runtime + dev tools with uv
|
||||
make python-checks # Run Ruff, BasedPyright, and Vulture
|
||||
|
||||
# Frontend development
|
||||
make install # Install dependencies
|
||||
make dev # Start Vite dev server (localhost:5173)
|
||||
|
||||
@@ -789,20 +789,18 @@ class ExternalClientHandler(DownloadHandler, ABC):
|
||||
status_callback=status_callback,
|
||||
)
|
||||
|
||||
# Clean up on success
|
||||
if result:
|
||||
self._on_download_complete(task)
|
||||
self._cleanup_refs[task.task_id] = (client, download_id, protocol)
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("Error during download polling")
|
||||
status_callback("error", str(e))
|
||||
self._safe_remove_download(client, download_id, protocol, "polling exception")
|
||||
return None
|
||||
else:
|
||||
return result
|
||||
|
||||
# Clean up on success
|
||||
if result:
|
||||
self._on_download_complete(task)
|
||||
self._cleanup_refs[task.task_id] = (client, download_id, protocol)
|
||||
|
||||
return result
|
||||
|
||||
def _handle_completed_file(
|
||||
self,
|
||||
|
||||
@@ -251,7 +251,7 @@ def html_get_page(
|
||||
heartbeat_thread: Thread | None = None
|
||||
if status_callback:
|
||||
|
||||
def _heartbeat(stop_event: Event = heartbeat_stop) -> None:
|
||||
def _heartbeat() -> None:
|
||||
# Keep the download "alive" during long bypass operations so the orchestrator
|
||||
# doesn't flag it as stalled.
|
||||
if cancel_flag and cancel_flag.is_set():
|
||||
|
||||
+4
-1
@@ -6,11 +6,14 @@ This directory contains the test suite for Shelfmark. Tests are organized by sco
|
||||
|
||||
```bash
|
||||
# Sync the local Python environment once
|
||||
uv sync --locked --extra browser
|
||||
make install-python-dev
|
||||
|
||||
# Run all unit tests locally (fast, no external dependencies)
|
||||
uv run pytest tests/ -v -m "not integration and not e2e"
|
||||
|
||||
# Run Python static analysis
|
||||
make python-checks
|
||||
|
||||
# Run E2E API tests against a running app stack
|
||||
uv run pytest tests/e2e/ -v -m e2e
|
||||
|
||||
|
||||
@@ -41,6 +41,18 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/53/23/b65f568ed0c22f1efacb744d2db1a33c8068f384b8c9b482b52ebdbc3ef6/authlib-1.6.9-py2.py3-none-any.whl", hash = "sha256:f08b4c14e08f0861dc18a32357b33fbcfd2ea86cfe3fe149484b4d764c4a0ac3", size = 244197, upload-time = "2026-03-02T07:44:00.307Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "basedpyright"
|
||||
version = "1.39.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "nodejs-wheel-binaries" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ac/f4/4a77cc1ffb3dab7391642cde30163961d8ee973e9e6b6740c7d15aa3d3ba/basedpyright-1.39.0.tar.gz", hash = "sha256:6666f51c378c7ac45877c4c1c7041ee0b5b83d755ebc82f898f47b6fafe0cc4f", size = 25357403, upload-time = "2026-04-01T12:27:41.92Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/97/47/08145d1bcc3083ed20059bdecbde404bd767f91b91e2764ec01cffec9f4b/basedpyright-1.39.0-py3-none-any.whl", hash = "sha256:91b8ad50bc85ee4a985b928f9368c35c99eee5a56c44e99b2442fa12ecc3d670", size = 12353868, upload-time = "2026-04-01T12:27:38.495Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "beautifulsoup4"
|
||||
version = "4.14.3"
|
||||
@@ -573,12 +585,19 @@ wheels = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodeenv"
|
||||
version = "1.10.0"
|
||||
name = "nodejs-wheel-binaries"
|
||||
version = "24.14.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f1/87/e5755ad739daafce2e152ab609293d65e6c663b399e28a4bbcd0f4af1f45/nodejs_wheel_binaries-24.14.1.tar.gz", hash = "sha256:d00ae0c86d7e1bfa798e8f8ad282db751af157cdcaa1208a1b9a2cf2a85ac821", size = 8056, upload-time = "2026-03-31T14:07:27Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/b7/9765d9a5d3b95475829ef5965d4a4f6f4badb034ee4e18c2d5f8b9b65d6f/nodejs_wheel_binaries-24.14.1-py2.py3-none-macosx_13_0_arm64.whl", hash = "sha256:d9e856ba0f2d3d2659869e6e0f4cae6874faeeeca7f879131a88451356373ac4", size = 54945603, upload-time = "2026-03-31T14:06:58.526Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/15/bc2fa51ee31ce597b2af1905081e5a5add07fe0cf619bfa531d7df2f1f1b/nodejs_wheel_binaries-24.14.1-py2.py3-none-macosx_13_0_x86_64.whl", hash = "sha256:634f57829ebfdfe95d096f32a50c5cdd3a6c72a94dcf2b92a8bef9868cccb13e", size = 55119951, upload-time = "2026-03-31T14:07:02.597Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/dd/92ff0831262af4bbb5473d4e7964fd27afb0901a2690a6ff7bc3d220d97f/nodejs_wheel_binaries-24.14.1-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:404b563467129e6a0ea7006a38b3d8af0ebfbc340b31a6a0af2c59ea3af90b7c", size = 59487620, upload-time = "2026-03-31T14:07:06.198Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/36/bbbee3adf6afd00944e5a86ebd64987dea90bd347090155a4989dc3e8594/nodejs_wheel_binaries-24.14.1-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:7863c62f8a3946b727831f71375a9ae00205b3258478476034b49c3a1d57ac12", size = 59986044, upload-time = "2026-03-31T14:07:09.846Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/16/119e4168bf7ed17ad7961d122701c75ac86135fa243a958b960a3f1b7055/nodejs_wheel_binaries-24.14.1-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a3f64daa1235fa6a83c778ded98d5fe4e74979ca54aa2ffb807f0805c57c3abe", size = 61489823, upload-time = "2026-03-31T14:07:13.378Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/a6/d581996827b9d1133094dc347f1c4e3d2a70557973ce7a427a03337b1427/nodejs_wheel_binaries-24.14.1-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:810a48ce096925ead0690f7d143e48fb902ebfc9212097e8f6cb3ac6cbe8f314", size = 62069740, upload-time = "2026-03-31T14:07:17.006Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/27/da/396d1a48cbf3d5899461bda12fa97ae4010d7e4013e7f28230cb04af5818/nodejs_wheel_binaries-24.14.1-py2.py3-none-win_amd64.whl", hash = "sha256:7a087b6a727fb9242d1cc83c8b121711bd0e9686408d27de48b34b23dfb26ac5", size = 41400067, upload-time = "2026-03-31T14:07:20.513Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/b7/adb21cf549934579e98934531e7f9b038d583fc9c2dd4b82ea01cc31bdd2/nodejs_wheel_binaries-24.14.1-py2.py3-none-win_arm64.whl", hash = "sha256:978fdfe76624c48111ab99ed0f99f9d4c1c682e420b0212ac9e1daee52f20283", size = 39096873, upload-time = "2026-03-31T14:07:23.977Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -836,19 +855,6 @@ version = "0.2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/cb/04/2ba023d5f771b645f7be0c281cdacdcd939fe13d1deb331fc5ed1a6b3a98/PyRect-0.2.0.tar.gz", hash = "sha256:f65155f6df9b929b67caffbd57c0947c5ae5449d3b580d178074bffb47a09b78", size = 17219, upload-time = "2022-03-16T04:45:52.36Z" }
|
||||
|
||||
[[package]]
|
||||
name = "pyright"
|
||||
version = "1.1.408"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "nodeenv" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/74/b2/5db700e52554b8f025faa9c3c624c59f1f6c8841ba81ab97641b54322f16/pyright-1.1.408.tar.gz", hash = "sha256:f28f2321f96852fa50b5829ea492f6adb0e6954568d1caa3f3af3a5f555eb684", size = 4400578, upload-time = "2026-01-08T08:07:38.795Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/82/a2c93e32800940d9573fb28c346772a14778b84ba7524e691b324620ab89/pyright-1.1.408-py3-none-any.whl", hash = "sha256:090b32865f4fdb1e0e6cd82bf5618480d48eecd2eb2e70f960982a3d9a4c17c1", size = 6399144, upload-time = "2026-01-08T08:07:37.082Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyscreeze"
|
||||
version = "1.0.1"
|
||||
@@ -1273,10 +1279,11 @@ browser = [
|
||||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "pyright" },
|
||||
{ name = "basedpyright" },
|
||||
{ name = "pytest" },
|
||||
{ name = "pytest-xdist" },
|
||||
{ name = "ruff" },
|
||||
{ name = "vulture" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
@@ -1309,10 +1316,11 @@ provides-extras = ["browser"]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "pyright", specifier = ">=1.1.408" },
|
||||
{ name = "basedpyright", specifier = ">=1.39.0" },
|
||||
{ name = "pytest" },
|
||||
{ name = "pytest-xdist", specifier = ">=3.8.0" },
|
||||
{ name = "ruff", specifier = "==0.15.10" },
|
||||
{ name = "vulture", specifier = ">=2.14" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1463,6 +1471,15 @@ socks = [
|
||||
{ name = "pysocks" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vulture"
|
||||
version = "2.16"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/66/3e/4d08c5903b2c0c70cad583c170cc4a663fc6a61e2ad00b711fcda61358cd/vulture-2.16.tar.gz", hash = "sha256:f8d9f6e2af03011664a3c6c240c9765b3f392917d3135fddca6d6a68d359f717", size = 52680, upload-time = "2026-03-25T14:41:27.141Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/be/f935130312330614811dae2ea9df3f395f6d63889eb6c2e68c14507152ee/vulture-2.16-py3-none-any.whl", hash = "sha256:6e0f1c312cef1c87856957e5c2ca9608834a7c794c2180477f30bf0e4cc58eee", size = 26993, upload-time = "2026-03-25T14:41:26.21Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "websocket-client"
|
||||
version = "1.9.0"
|
||||
|
||||
Reference in New Issue
Block a user