Skip to content

fix(packaging): ship py.typed with the four broker distributions - #264

Merged
eaitbrahim merged 1 commit into
mainfrom
chore/py-typed-markers
Aug 13, 2026
Merged

fix(packaging): ship py.typed with the four broker distributions#264
eaitbrahim merged 1 commit into
mainfrom
chore/py-typed-markers

Conversation

@eaitbrahim

Copy link
Copy Markdown
Contributor

What

Adds an empty py.typed to keel_broker_api, keel_broker_coinbase, keel_broker_fake and keel_broker_robinhood, plus a packaging test that keeps them there.

Why

All four are checked with strict = true, but none shipped a PEP 561 marker — so every wheel through 0.7.0 carried its annotations invisibly.

Inside this repo it never showed, because mypy reads the source tree. Off it, a consumer sees:

error: Skipping analyzing "keel_broker_api": module is installed, but missing library stubs or py.typed marker

and falls back to Any for every symbol crossing the boundary. The wheel still builds, still installs, still imports — the type contract is just gone. Same silent shape as an unpinned sibling, which is why this lands as a test rather than a note.

keel_broker_api is the one that costs most: the port's types are the contract every adapter and every consumer codes against.

The test

test_strictly_typed_packages_ship_a_py_typed_marker derives its subject list from the [tool.mypy] strict overrides instead of naming packages, so tightening a package into strict mode brings it under the rule with no edit here.

Scoped to strict modules deliberately — keel.* and keel_core.* are still ignore_errors, and a marker on unchecked code promises a guarantee nothing verifies. keel_core carries one anyway for historical reasons; the rule is a floor, not an equality, so that stays legal.

Verification

  • Confirmed the test fails when a marker is removed, not just that it passes now.
  • Checked the built wheel, not only the source tree: unzip -l keel_broker_api-0.7.0-py3-none-any.whl now lists keel_broker_api/py.typed.
  • ruff check keel tests packages clean; mypy clean (224 files); pytest 2721 passed, 1 skipped.

🤖 Generated with Claude Code

mypy checks `keel_broker_api`, `keel_broker_coinbase`, `keel_broker_fake` and
`keel_broker_robinhood` with `strict = true`, but none of them shipped a PEP 561
marker, so all four wheels through 0.7.0 carried their annotations invisibly. In
this repo it never showed: mypy reads the source tree. Off it, a consumer gets
`module is installed, but missing library stubs or py.typed marker` and falls
back to `Any` for every symbol crossing the boundary -- the wheel still builds,
still installs, still imports, and the type contract is simply gone. That is the
same silent shape as an unpinned sibling, which is why this lands as a test and
not a note.

`keel_broker_api` is the one that costs most: the port's types are the contract
every adapter and every consumer codes against.

The test derives its subject list from the `[tool.mypy]` strict overrides rather
than naming packages, so tightening a package into strict mode brings it under
the rule automatically. It stays scoped to strict modules on purpose -- `keel.*`
and `keel_core.*` are still `ignore_errors`, and a marker on unchecked code
promises a guarantee nothing verifies. `keel_core` has one anyway, historically;
the rule is a floor, not an equality, so that stays legal.

Verified against a built wheel, not just the source tree:
`unzip -l keel_broker_api-0.7.0-py3-none-any.whl` now lists `py.typed`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@eaitbrahim
eaitbrahim merged commit 1ce4119 into main Aug 13, 2026
1 check passed
@eaitbrahim
eaitbrahim deleted the chore/py-typed-markers branch August 13, 2026 06:02
@eaitbrahim eaitbrahim mentioned this pull request Aug 17, 2026
4 tasks
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