Skip to content

[python-types] client.py: Exchange.__init__ missing -> None, _auto_convert untyped cls/**overrides, bare dict/list variable annotations #728

@realfishsam

Description

@realfishsam

File

sdks/python/pmxt/client.py

Note: This is a supplement to #227, which covers params: Optional[dict], missing return types on private helpers, and Optional[Any] usage. The items below are distinct gaps not covered by that issue.

Missing Return Types

Line 278 — Exchange.__init__ (CRITICAL — public constructor)

def __init__(
    self,
    exchange_name: str,
    ...
):

The base Exchange constructor is missing -> None. PEP 484 requires __init__ to be explicitly annotated. Without it, disallow_untyped_defs = true (tracked in #246) will reject it at CI.

Line 1759 — _require_ws_transport (HIGH — called by every streaming method)

def _require_ws_transport(self, method_name: str):

Returns a SidecarWsClient on success and raises PmxtError on failure. Missing return type → should be -> "SidecarWsClient".

Missing Parameter Types

Line 90 — _auto_convert (HIGH — called by every converter function)

def _auto_convert(cls, raw: Dict[str, Any], **overrides):
  • cls is untyped → should be Type[Any] (or a TypeVar bound to a dataclass)
  • **overrides is untyped → should be **overrides: Any
  • Return type missing → should be -> Any (or the bound TypeVar)

Bare Built-in Variable Annotations (MEDIUM — widespread)

Every generated method body uses inline bare types:

body: dict = {"args": args}   # should be Dict[str, Any]

Affected methods (18 total in the # BEGIN GENERATED METHODS block):
fetch_markets, fetch_markets_paginated, fetch_events, fetch_market, fetch_event, fetch_order_book, fetch_order_books, cancel_order, fetch_order, fetch_open_orders, fetch_my_trades, fetch_closed_orders, fetch_all_orders, fetch_positions, fetch_balance, fetch_market_matches, fetch_matches, fetch_event_matches, compare_market_prices, fetch_related_markets, fetch_matched_markets, fetch_matched_prices, fetch_hedges, fetch_arbitrage

Bare list annotations also appear in streaming methods:

  • Line 1982 (watch_all_order_books): args: list = [effective_venues] if effective_venues else []
  • Line 2075 (watch_address): args: list = [address]
  • Line 2079 (watch_address): body: dict = {"args": args}

Impact

  • Exchange.__init__ missing -> None affects every user constructing any exchange subclass (Polymarket, Kalshi, Router, etc.). IDEs cannot infer the constructor return type, which causes incomplete hover documentation.
  • _auto_convert is the single shared converter that builds every model object returned by the SDK. An untyped cls parameter means the return type cannot be inferred by static analysis.
  • Bare body: dict / args: list annotations with disallow_untyped_defs = true enabled ([python-types] pyproject.toml: disallow_untyped_defs = false allows all type gaps to silently pass #246) will cause mypy errors across all 24+ generated methods at once.

Suggested Fix

# Line 278
def __init__(self, exchange_name: str, ...) -> None:

# Line 90
def _auto_convert(cls: Type[Any], raw: Dict[str, Any], **overrides: Any) -> Any:

# Line 1759
def _require_ws_transport(self, method_name: str) -> "SidecarWsClient":

# Generated methods — replace body: dict with:
body: Dict[str, Any] = {"args": args}

# Streaming methods — replace args: list with:
args: List[Any] = [...]

Found by automated Python type hints audit

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions