The async modules are the source of truth for most endpoint, client,
middleware, and service implementations. The sync modules listed in
scripts/gen_sync.py are generated from those async sources.
Generated files start with:
# Generated by scripts/gen_sync.py from src/ksef2/_clients/async_auth.py.
# DO NOT EDIT BY HAND - edit the async source and run `just gen-sync`.Change a generated pair
-
Edit the async source module.
$EDITOR src/ksef2/_clients/async_auth.pybash -
Generate the matching sync module.
just gen-syncbashFor a focused pass, use the generator directly:
uv run python scripts/gen_sync.py --only src/ksef2/_clients/async_auth.pybash -
Review both the async source and generated sync target.
git diff -- src/ksef2/_clients/async_auth.py src/ksef2/_clients/auth.pybash -
Run the generated-sync check before opening a PR.
just check-gen-syncbash
just release-check also runs check-gen-sync, so stale generated sync files
block releases.
Check one pair
Use --only with either the async source or sync target:
uv run python scripts/gen_sync.py --check --diff --only src/ksef2/_clients/auth.pyThis is useful when you are iterating on one generated pair and want a compact diff.
Know the boundaries
Not every sync/async pair is generated. Some modules are intentionally shared or structurally different:
src/ksef2/_core/polling.pycontains shared sync and async polling helpers.src/ksef2/_core/response_errors.pycontains shared response error mapping.src/ksef2/_clients/base.pyandsrc/ksef2/_clients/async_base.pydiffer in root-client ownership and lifecycle.src/ksef2/_core/http.pyandsrc/ksef2/_core/async_http.pydiffer in transport ownership and close semantics.
The generator keeps the explicit pair list and exclusions in scripts/gen_sync.py.
Update that list when a module becomes generated or intentionally divergent.
What the release gate proves
just release-check runs:
just lint
just format-check
just check-ksef-api-version
just check-gen-sync
just typecheck
just test
just test-runtime-checks
uv buildFor sync generation specifically, that means:
- generated targets match the async source transform;
- generated files still format with the repo config;
- sync and async public surfaces stay covered by parity tests;
- the package builds from the checked-in generated files.
