From ee0df07a4a28029344b7b59692f1fbf630a2886a Mon Sep 17 00:00:00 2001 From: trick77 Date: Mon, 25 May 2026 15:52:31 +0200 Subject: [PATCH 1/2] chore: use basedpyright for type checking --- .pre-commit-config.yaml | 6 +++--- AGENTS.md | 6 +++--- pyproject.toml | 8 ++++---- uv.lock | 45 +++++++++++++++++++++++++++-------------- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 27003eb..c4377f5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,10 +17,10 @@ repos: args: [--fix] - id: ruff-format - - repo: https://github.com/RobertCraigie/pyright-python - rev: v1.1.391 + - repo: https://github.com/DetachHead/basedpyright-prek-mirror + rev: v1.39.6 hooks: - - id: pyright + - id: basedpyright - repo: https://github.com/astral-sh/uv-pre-commit rev: 0.5.13 diff --git a/AGENTS.md b/AGENTS.md index 1f56756..dc145b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,7 +12,7 @@ uv run pytest tests/test_parsers.py # one file uv run pytest -k test_revert # one test by keyword uv run ruff check . && uv run ruff format --check . # lint + format check uv run ruff format . # auto-format -uv run pyright # type-check (strict mode for src/) +uv run basedpyright # type-check (strict mode for src/) RIPTIDE_DB_URL=... uv run alembic upgrade head # apply migrations RIPTIDE_DB_URL=... uv run alembic downgrade base # tear down podman-compose up # local dev: Postgres + migrations + app on :8000 @@ -44,9 +44,9 @@ If `docker ps` fails, ask the user to start OrbStack. - Single Python package, `riptide_collector` (flat top-level, not a namespace package). Future suite components (e.g. `riptide-api`, `riptide-dashboard`) get their own top-level package, e.g. `riptide_dashboard` — leave architectural room for them. - Webhook routers are factories that return an `APIRouter`. Bitbucket needs the config for automation detection (`make_router(config, session_factory, auth_dep)`); Pipeline, ArgoCD, and Noergler don't, so they take just `(session_factory, auth_dep)`. They're wired up in `src/riptide_collector/main.py::create_app`. Add the config only when a router actually needs `automation` rules or team metadata. - Pydantic schemas: **strict** for `/webhooks/pipeline` and `/webhooks/argocd` (we own the contract — invalid payloads must 422); **permissive raw-dict parsing** for Bitbucket (its payload shapes vary; we best-effort extract). -- Use `_as_dict()` / `_as_list()` helpers in `routers/bitbucket.py` to coerce arbitrary JSON shapes — pyright strict won't accept chained `.get()` on `Optional[dict]`. +- Use `_as_dict()` / `_as_list()` helpers in `routers/bitbucket.py` to coerce arbitrary JSON shapes — basedpyright strict won't accept chained `.get()` on `Optional[dict]`. - Tests use real Postgres via testcontainers, never SQLite. The `client` fixture in `tests/conftest.py` depends on `session_factory` which truncates tables per test. -- `.pre-commit-config.yaml` runs ruff + pyright + uv-lock-check; expect CI to enforce the same. +- `.pre-commit-config.yaml` runs ruff + basedpyright + uv-lock-check; expect CI to enforce the same. ## Logging & Splunk diff --git a/pyproject.toml b/pyproject.toml index aa1c196..ae691c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dev = [ "testcontainers[postgres]>=4.9", "httpx>=0.28", "ruff>=0.8", - "pyright>=1.1.391", + "basedpyright>=1.39.6", "pre-commit>=4.0", ] @@ -49,7 +49,7 @@ ignore = ["E501"] "migrations/**" = ["E", "F", "I", "B", "UP", "SIM", "RUF"] "tests/**" = ["B"] -[tool.pyright] +[tool.basedpyright] pythonVersion = "3.13" include = ["src", "tests", "migrations"] exclude = ["**/__pycache__", "**/.venv"] @@ -61,12 +61,12 @@ reportUnknownMemberType = false reportUnknownVariableType = false reportUnknownArgumentType = false -[[tool.pyright.executionEnvironments]] +[[tool.basedpyright.executionEnvironments]] root = "tests" reportPrivateUsage = false reportUnknownLambdaType = false -[[tool.pyright.executionEnvironments]] +[[tool.basedpyright.executionEnvironments]] root = "migrations" reportPrivateUsage = false diff --git a/uv.lock b/uv.lock index d937063..58dc918 100644 --- a/uv.lock +++ b/uv.lock @@ -78,6 +78,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3c/d7/8fb3044eaef08a310acfe23dae9a8e2e07d305edc29a53497e52bc76eca7/asyncpg-0.31.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd4107bb7cdd0e9e65fae66a62afd3a249663b844fa34d479f6d5b3bef9c04c3", size = 706062, upload-time = "2025-11-24T23:26:44.086Z" }, ] +[[package]] +name = "basedpyright" +version = "1.39.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodejs-wheel-binaries" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/1a/48296b4479ccc9051eb9617a6507a69a68f5b68693fb6a118cfe08199270/basedpyright-1.39.6.tar.gz", hash = "sha256:d00ec5f8ba4e1a67dfc2fa3a9474229c89f61f207d14c02d320db78f57aa16ef", size = 25504244, upload-time = "2026-05-24T07:44:41.864Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/07/6d1b3192715d42e8c9887876684a941eff28ec5d79c23a0f3758377e2182/basedpyright-1.39.6-py3-none-any.whl", hash = "sha256:5e0b9befbae6b26d0fbcc6645ac26923725e749d1224539e24f05ab07f9365ad", size = 13182122, upload-time = "2026-05-24T07:44:47.086Z" }, +] + [[package]] name = "certifi" version = "2026.4.22" @@ -509,6 +521,22 @@ 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" }, ] +[[package]] +name = "nodejs-wheel-binaries" +version = "24.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/70/a1e4f4d5986768ab90cc860b1cc3660fd2ded74ca175a900a5c29f839c7d/nodejs_wheel_binaries-24.15.0.tar.gz", hash = "sha256:b43f5c4f6e5768d8845b2ae4682eb703a19bf7aadc84187e2d903ed3a611c859", size = 8057, upload-time = "2026-04-19T15:48:16.899Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/66/54051d14853d6ab4fb85f8be9b042b530be653357fb9a19557498bc91ab7/nodejs_wheel_binaries-24.15.0-py2.py3-none-macosx_13_0_arm64.whl", hash = "sha256:a6232fa8b754220941f52388c8ead923f7c1c7fdf0ea0d98f657523bd9a81ef4", size = 55173485, upload-time = "2026-04-19T15:47:34.561Z" }, + { url = "https://files.pythonhosted.org/packages/ad/5f/66acada164da5ca10a0824db021aa7394ae18396c550cd9280e839a43126/nodejs_wheel_binaries-24.15.0-py2.py3-none-macosx_13_0_x86_64.whl", hash = "sha256:001a6b62c69d9109c1738163cca00608dd2722e8663af59300054ea02610972d", size = 55348100, upload-time = "2026-04-19T15:47:40.521Z" }, + { url = "https://files.pythonhosted.org/packages/0d/2d/0cbd5ff40c9bb030ca1735d8f8793bd74f08a4cbd49100a1d19313ea57ab/nodejs_wheel_binaries-24.15.0-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:0fbc48765e60ed0ff30d43898dbf5cadbadf2e5f1e7f204afc2b01493b7ebce6", size = 59668206, upload-time = "2026-04-19T15:47:46.848Z" }, + { url = "https://files.pythonhosted.org/packages/da/d5/91ac63951ec75927a486b83b8cafe650e360fa70ac01dc94adfb32b93b97/nodejs_wheel_binaries-24.15.0-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:20ee0536809795da8a4942fc1ab4cbdebbcaaf29383eab67ba8874268fb00008", size = 60206736, upload-time = "2026-04-19T15:47:52.668Z" }, + { url = "https://files.pythonhosted.org/packages/db/72/dc22776974d928869c0c30d23ee98ed7df254243c2df68f09f5963e8e8b8/nodejs_wheel_binaries-24.15.0-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1fade6c214285e72472ca40a631e98ff36559671cd5eefc8bf009471d67f04b4", size = 61720456, upload-time = "2026-04-19T15:47:58.325Z" }, + { url = "https://files.pythonhosted.org/packages/01/0a/34461b9050cb45ee371dccdefc622aef6351506ea2691b08fc761ca67150/nodejs_wheel_binaries-24.15.0-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3984cb8d87766567aee67a49743227ab40ede6f47734ec990ff90e50b74e7740", size = 62326172, upload-time = "2026-04-19T15:48:04.094Z" }, + { url = "https://files.pythonhosted.org/packages/c9/17/09252bf35672dba926649d59dfe51443a0f6955ad13784e91131d5ec82a2/nodejs_wheel_binaries-24.15.0-py2.py3-none-win_amd64.whl", hash = "sha256:a437601956b532dcb3082046e6978e622733f90edc0932cbb9adb3bb97a16501", size = 41543461, upload-time = "2026-04-19T15:48:09.332Z" }, + { url = "https://files.pythonhosted.org/packages/0a/7e/b649777d148e1e0c2ce349156603cdb12f7ed99921b95d93717393650193/nodejs_wheel_binaries-24.15.0-py2.py3-none-win_arm64.whl", hash = "sha256:bdf4a431e08321a32efc604111c6f23941f87055d796a537e8c4110daecad23f", size = 39233248, upload-time = "2026-04-19T15:48:13.326Z" }, +] + [[package]] name = "packaging" version = "26.2" @@ -646,19 +674,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] -[[package]] -name = "pyright" -version = "1.1.409" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/51/4e/3aa27f74211522dba7e9cbc3e74de779c6d4b654c54e50a4840623be8014/pyright-1.1.409.tar.gz", hash = "sha256:986ee05beca9e077c165758ad123667c679e050059a2546aa02473930394bc93", size = 4430434, upload-time = "2026-04-23T11:02:03.799Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/6b/330d8ebae582b30c2959a1ef4c3bc344ebde48c2ff0c3f113c4710735e11/pyright-1.1.409-py3-none-any.whl", hash = "sha256:aa3ea228cab90c845c7a60d28db7a844c04315356392aa09fafcee98c8c22fb3", size = 6438161, upload-time = "2026-04-23T11:02:01.309Z" }, -] - [[package]] name = "pytest" version = "9.0.3" @@ -805,10 +820,10 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "basedpyright" }, { name = "coverage" }, { name = "httpx" }, { name = "pre-commit" }, - { name = "pyright" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, @@ -831,10 +846,10 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "basedpyright", specifier = ">=1.39.6" }, { name = "coverage", extras = ["toml"], specifier = ">=7.6" }, { name = "httpx", specifier = ">=0.28" }, { name = "pre-commit", specifier = ">=4.0" }, - { name = "pyright", specifier = ">=1.1.391" }, { name = "pytest", specifier = ">=8.3" }, { name = "pytest-asyncio", specifier = ">=0.25" }, { name = "pytest-cov", specifier = ">=6.0" }, From 9d720cbe0245f72ed8ea53ca403734030129c73e Mon Sep 17 00:00:00 2001 From: trick77 Date: Mon, 25 May 2026 15:58:06 +0200 Subject: [PATCH 2/2] ci: run basedpyright in lint job --- .github/workflows/ci.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 45ffa43..de5a721 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -26,8 +26,8 @@ jobs: run: uv run ruff check . - name: ruff format run: uv run ruff format --check . - - name: pyright - run: uv run pyright + - name: basedpyright + run: uv run basedpyright test: runs-on: ubuntu-latest @@ -64,4 +64,3 @@ jobs: name: coverage-xml path: coverage.xml if-no-files-found: ignore -