Skip to content

refactor(python): move the launcher's argv config-path scan to its own module - #1047

Merged
thekevinscott merged 2 commits into
mainfrom
claude/tackle-1042-py12
Sep 5, 2026
Merged

thekevinscott merged 2 commits into
mainfrom
claude/tackle-1042-py12

Conversation

@thekevinbot

Copy link
Copy Markdown
Collaborator

Part of #1042.

Moves the launcher's argv config-path scan out of packages/python/dirsql/cli/resolve_config_extensions.py into its own module, clearing that file's one-function-per-file violation at max_lines = 12 (Kevin's chosen target for the campaign).

_config_paths_from_argv becomes config_paths_from_argv in packages/python/dirsql/cli/config_paths_from_argv.py; with_resolved_extensions stays in the module named for it and imports the scan relatively. The underscore drops because the symbol is now imported across modules; it stays out of every barrel, so nothing about the public API changes.

Mirrors #1039. That PR made exactly this call on the TypeScript twin — moved configPathsFromArgv into packages/ts/src/cli/config-paths-from-argv.ts and kept withResolvedExtensions where it was. Same shape here, so the two launchers keep matching. PR C is doing the remaining TypeScript splits concurrently.

No testing-conventions.toml touched. This is a pure refactor; a separate PR sets the ceilings once every split has landed.

packages/python/dirsql/resolve_config_extensions.py (the non-cli one) violates only at max_lines = 10, so it is out of scope at 12 and untouched.

Verification

testing-conventions@0.0.111 pinned by hand (the workflows call the reusable workflow at @v0 and pin no npm version), against a copy of packages/python/testing-conventions.toml with max_lines = 12:

Before:

packages/python/dirsql/cli/resolve_config_extensions.py:49: one-function-per-file — `with_resolved_extensions` runs 18 lines, and `_config_paths_from_argv` already holds this file; move it to its own module
error: 1 function(s) sharing a file with another function over the 12-line threshold

After: no output — zero violations.

just preflight: 0 failing pair(s), 3 skipped (the three packaging pairs, which need a built artifact). Python unit mutation: no surviving mutants — every mutation was caught (47 mutant(s) tested). Python unit coverage: clean at the 100% floor.

Tests

Behaviour-preserving refactor, so red/green does not apply — there is no new behaviour to fail a test first. The existing cases were split by which unit they actually exercise:

  • The 13 argv-parsing cases relocate (not duplicate) out of resolve_config_extensions_test.py into a colocated config_paths_from_argv_test.py that calls the function directly.
  • resolve_config_extensions_test.py keeps the launcher's own plumbing — the init and native-config guards, --extension flag construction — and now mocks the scan as a collaborator (mock.patch.object(..., autospec=True)), alongside the resolver it already mocked, satisfying unit lint isolation.

Manual exercise

Built the binary (cargo build -p dirsql --features cli) and the extension module (uv run maturin develop), staged the repo's testext cdylib fixture as an installed package manualext, and ran the CLI path that resolves a config extension by package name:

$ cat .dirsql.toml
[[dirsql.extension]]
path = "manualext"

$ PYTHONPATH=/tmp/.../pkgs dirsql query "SELECT dirsql_testext_answer() AS answer" -c ./.dirsql.toml --format json
[{"answer":42}]

The 42 proves the whole chain through the moved code: the launcher scanned -c ./.dirsql.toml out of argv with config_paths_from_argv, the shared resolver turned manualext into the loadable's literal path, the launcher appended --extension, and the binary loaded it.

E2E Verification

  • Ran e2e suites locally for every affected SDK
  • Python SDK e2e: pass (37 passed)
  • TypeScript SDK e2e: N/A - no TypeScript change
  • Rust core e2e (if applicable): N/A - no Rust change
  • packages/python/e2e-attestations/<branch>.json receipt written if packages/python changed (just e2e-attest-python)
  • packages/ts/e2e-attestations/<branch>.json receipt written if packages/ts changed (just e2e-attest-ts) — not required, packages/ts untouched
  • Command(s) run: just test-e2e, then just e2e-attest-python
  • Result summary: 37 passed in 13.57s; receipt at packages/python/e2e-attestations/claude-tackle-1042-py12.json (exit 0).

Per #1041, testing-conventions e2e attest (local CLI 0.0.85) pruned 14 unrelated receipts and auto-committed the deletions. The attest commit was rewritten to add the one new receipt and nothing else; git show --stat on it reads 1 file changed, 7 insertions(+).

Changelog / Migrations

  • Changelog fragment added under <root>/<pkg>/changelog.d/ for each changed package (or: skip-changelog trailer on a commit with reason) — packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md
  • Migration fragment added under <root>/<pkg>/migrations.d/ (or: not required -- additive/bugfix only)

Migration: not required. The moved symbol was module-private (_config_paths_from_argv), is exported from no barrel, and appears in no documented surface. with_resolved_extensions keeps its name and module, and its only call site (dirsql/cli/main.py) is unchanged. No public API breaks, no deprecation is removed, and runtime behaviour is identical — the manual exercise and the 37-case e2e suite both confirm it.

PARITY.md: no change. Neither config_paths_from_argv nor with_resolved_extensions appears in PARITY.md, packages/python/dirsql/__init__.py, or packages/ts/src/index.ts. No drift introduced, none restored.

`config_paths_from_argv` moves out of `dirsql/cli/resolve_config_extensions.py`
into `dirsql/cli/config_paths_from_argv.py`, leaving `with_resolved_extensions`
alone in the module named for it. Mirrors #1039, which made the same call on
the TypeScript twin.

Behaviour-preserving: the symbol is package-internal and appears in no barrel,
so the published API and the CLI are unchanged. The argv-parsing test cases
relocate to the new module's colocated test file; the launcher's own tests now
mock the scan as a collaborator.

Part of #1042.
@thekevinscott
thekevinscott merged commit 44af683 into main Sep 5, 2026
47 checks passed
@thekevinscott
thekevinscott deleted the claude/tackle-1042-py12 branch September 5, 2026 00:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants