BREAKING(v3): CommunicationsResource sub-namespaces (rfqs/quotes) + standardize list_all_<noun> naming#377
Conversation
…dization Reorganize `CommunicationsResource` (sync + async) into sub-namespaces matching the OpenAPI v3.18.0 tag structure: `client.communications.rfqs.*` and `client.communications.quotes.*`. The misc `get_id()` endpoint stays at the top level because it has no sub-noun. Add `RFQsResource`, `QuotesResource`, `AsyncRFQsResource`, `AsyncQuotesResource` constructed by the parent's `__init__` against the same transport. The new shape gives callers `rfqs.list/list_all/get/create/delete` and `quotes.list/list_all/get/create/delete/accept/confirm` — twelve flat methods collapse into two clean noun-scoped namespaces (#348). Rename `MarketsResource.list_trades_all` to `list_all_trades` on both sync and async, aligning with the `list_all_<noun>` form already used by communications, subaccounts, etc. (#349). Every renamed symbol is kept as a `typing_extensions.deprecated` thin forwarder that delegates to the new implementation. Each call emits exactly one `DeprecationWarning` (recognized by type checkers per PEP 702) and is documented `.. deprecated:: 3.0.0` in its docstring. Both names work in v3.0.0; the deprecated aliases are scheduled for removal in a future release. Forwarders preserve zero behavioral divergence — they call the underlying `_build_*_body` and transport methods through the new sub-resource impls. Update `tests/_contract_support.py` to register the 13 new public methods in `METHOD_ENDPOINT_MAP` plus matching cursor exclusions and `_MAX_PAGES_FQNS` entries, so `test_every_public_method_has_entry` and `test_exclusions_bootstrap_has_cursor_entries` remain green. Add a `TestV3DeprecationAliases` class to `tests/test_communications.py` exercising both the new sub-namespace shape and each deprecated flat forwarder under `pytest.warns(DeprecationWarning)`. Add `test_issue_349_list_all_trades_works` and `test_issue_349_list_trades_all_emits_deprecation_warning` to `tests/test_markets.py` and `tests/test_async_markets.py`. Rewrite `docs/resources/communications.md` around the new sub-namespace shape with a BEFORE/AFTER migration table; mark `list_trades_all` deprecated in `docs/resources/markets.md`. Closes #348, #349
Code Review — PR #377OverviewClean, well-scoped breaking-change stack. Two surface renames (#348 sub-namespaces, #349 naming convention) with deprecated thin forwarders, solid docs updates, and contract-support wiring. The approach is correct and the implementation is careful. A few items below are worth a look before merge. Issues1. Async deprecation warnings not exercised in tests (gap)
This means a regression where the async 2.
|
|
Round-2 review addressed in b187b97: added async deprecation-warning test covering 12 forwarders; narrowed type:ignore codes on create_rfq/create_quote forwarders (all three codes verified required via per-code mypy probe; |
Code Review — PR #377OverviewTwo clean v3.0.0 surface renames with backward-compatible deprecated forwarders:
The architecture is sound: sub-resources share the same transport, logic lives in the canonical implementation only, and forwarders are pure pass-throughs. Nothing here changes wire behavior. Strengths
Issues / Suggestions1. Possible missing cursor exclusion for The diff adds: ("kalshi.resources.markets.MarketsResource.list_all_trades", "cursor"): Exclusion(...)but I don't see a corresponding entry for 2. Deprecation messages leave removal version open-ended The current message is:
Giving a concrete target (e.g., "v4.0.0") is more actionable for users planning migrations. If the removal timeline isn't decided yet, even "v3.x" is better than "a future release". Minor, but users planning upgrades will appreciate the specificity. 3. Async sub-namespace happy-path test is wiring-only
4. return self.rfqs.create( # type: ignore[call-overload, no-any-return, misc]The comment explaining "mypy's too many union combinations overload limit" is correct and sufficient. This is an acceptable trade-off for the compat layer — just flagging it's present and expected, not a concern. No issues found with
VerdictApprove with minor notes. The one item worth confirming before merge is the |
Summary
Two breaking surface renames targeting v3.0.0:
CommunicationsResourcereorganized into sub-namespaces matchingthe OpenAPI tag structure:
client.communications.rfqs.*andclient.communications.quotes.*. The miscget_id()endpoint stays atthe top level because it has no sub-noun.
MarketsResource.list_trades_allrenamed tolist_all_trades, aligning with the SDK-widelist_all_<noun>conventionalready used by communications, subaccounts, etc.
Every renamed method is kept as a
@typing_extensions.deprecatedthinforwarder that delegates to the new implementation and emits exactly one
DeprecationWarningper call. Both names work in v3.0.0; the deprecatedaliases are scheduled for removal in a future release.
Issues closed
rfqs,quotes) replace prefix-style method names onCommunicationsResource.list_trades_all→list_all_tradesstandardizes on thelist_all_<noun>form.Migration — BEFORE / AFTER
Communications (#348)
client.communications.list_rfqs(...)client.communications.rfqs.list(...)client.communications.list_all_rfqs(...)client.communications.rfqs.list_all(...)client.communications.get_rfq(rfq_id)client.communications.rfqs.get(rfq_id)client.communications.create_rfq(...)client.communications.rfqs.create(...)client.communications.delete_rfq(rfq_id)client.communications.rfqs.delete(rfq_id)client.communications.list_quotes(...)client.communications.quotes.list(...)client.communications.list_all_quotes(...)client.communications.quotes.list_all(...)client.communications.get_quote(quote_id)client.communications.quotes.get(quote_id)client.communications.create_quote(...)client.communications.quotes.create(...)client.communications.delete_quote(quote_id)client.communications.quotes.delete(quote_id)client.communications.accept_quote(quote_id, accepted_side="yes")client.communications.quotes.accept(quote_id, accepted_side="yes")client.communications.confirm_quote(quote_id)client.communications.quotes.confirm(quote_id)client.communications.get_id()is unchanged.Markets (#349)
client.markets.list_trades_all(...)client.markets.list_all_trades(...)list_trades(...)(single-page paginator) is unchanged.Behavioral changes
DeprecationWarningonce percall (via
typing_extensions.deprecated, recognized by type checkers perPEP 702). The wire request is identical — forwarders delegate to the new
implementation with zero behavioral divergence.
RFQsResource,QuotesResource,AsyncRFQsResource,AsyncQuotesResourceclasses (reachable via the parent's.rfqs/.quotesattributes; the parent's
__init__constructs them with the same transport).Tests
tests/test_communications.py— newTestV3DeprecationAliasesclass:test_issue_348_rfqs_sub_namespace_works— exercisesrfqs.list/get/create.test_issue_348_quotes_sub_namespace_works— exercisesquotes.list/create/accept.test_issue_348_async_rfqs_sub_namespace_class—isinstancewiring on async.test_issue_348_flat_names_still_work_emit_deprecation_warning— every oldflat method (12 of them) under
pytest.warns(DeprecationWarning)withresponse-shape assertions.
tests/test_markets.py:test_issue_349_list_all_trades_works— new name returns the right shape.test_issue_349_list_trades_all_emits_deprecation_warning— old name stillworks, emits one
DeprecationWarning.tests/test_async_markets.py:test_issue_349_*tests for the async resource.tests/_contract_support.py—METHOD_ENDPOINT_MAPextended with 13 newentries for the sub-namespace methods +
list_all_trades; matching cursorexclusions and
_MAX_PAGES_FQNSentries added so the existingtest_every_public_method_has_entryandtest_exclusions_bootstrap_has_cursor_entriescontract guards remain green.All existing tests that exercise the flat methods continue to pass; they now
emit
DeprecationWarning(visible in the test report) without failing —pyproject.toml'sfilterwarningsdoes not escalate to error.Verification (run in worktree CWD):
Source
Round-3 independent audit closure plan, wave W4 (BREAKING — v3.0.0).