Skip to content

Async-first codegen: single source of truth with sync generation#13

Merged
arshka merged 2 commits intomainfrom
refactor/async-codegen
Mar 19, 2026
Merged

Async-first codegen: single source of truth with sync generation#13
arshka merged 2 commits intomainfrom
refactor/async-codegen

Conversation

@arshka
Copy link
Owner

@arshka arshka commented Mar 19, 2026

Summary

  • Makes _async/ the single hand-written source of truth for all domain and client modules (9 files)
  • Adds scripts/generate_sync.py that deterministically produces _sync/ via regex transforms (async defdef, await removal, asyncio.sleeptime.sleep, httpx.AsyncClientClient, AsyncXX class renames)
  • Replaces 10 top-level modules with thin re-export facades preserving all existing import paths
  • Fixes pyproject.toml package discovery to include _async and _sync subpackages

Details

Generator (scripts/generate_sync.py):

  • --write mode for development, --check mode for CI (exits non-zero on drift)
  • Explicit allowlist with validation against unexpected files in _async/
  • Supports phased migration (skips missing modules)

Net result: ~1,200 lines of previously hand-duplicated sync/async code are now maintained in one place. The sync variant is always derivable.

Test plan

  • All 275 unit tests pass (pytest tests/ --ignore=tests/integration)
  • python scripts/generate_sync.py --check exits 0
  • Golden test tests/test_codegen.py passes
  • All import paths verified (from pykalshi import ..., from pykalshi.client import ..., etc.)
  • Output is deterministic (re-running --write produces no diff)
  • setuptools.find_packages(include=["pykalshi*"]) discovers pykalshi._async and pykalshi._sync

🤖 Generated with Claude Code

Make _async/ the sole hand-written source for all domain and client
modules. A deterministic generator (scripts/generate_sync.py) produces
_sync/ via regex transforms (async def→def, await removal, asyncio→time,
httpx.AsyncClient→Client, class renames). Top-level modules become thin
facades preserving all existing import paths.

- Create pykalshi/_async/ with 9 standalone async modules
- Create scripts/generate_sync.py (--write / --check modes, allowlist
  validation, stale-file detection)
- Replace 10 top-level modules with re-export facades
- Add tests/test_codegen.py golden test
- Fix pyproject.toml package discovery to include subpackages
- Update mock paths in test_portfolio.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@arshka arshka force-pushed the refactor/async-codegen branch from 576f724 to 7246b14 Compare March 19, 2026 00:08
Minor bump: async classes no longer inherit from sync counterparts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@arshka arshka merged commit 1d81357 into main Mar 19, 2026
5 of 6 checks passed
@arshka arshka deleted the refactor/async-codegen branch March 19, 2026 00:34
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.

1 participant