Skip to content

fix: add typed structs and inheritance to Python models.py - #579

Closed
realfishsam wants to merge 1 commit into
mainfrom
fix/467-500-501-497-498-models-py
Closed

realfishsam wants to merge 1 commit into
mainfrom
fix/467-500-501-497-498-models-py

Conversation

@realfishsam

Copy link
Copy Markdown
Contributor

Fixes #467
Fixes #500
Fixes #501
Fixes #497
Fixes #498

@realfishsam

Copy link
Copy Markdown
Contributor Author

PR Review: FAIL

What This Does

Refactors Python SDK models: adds SubscriptionOption, CreateOrderParams, and TxPayload typed structs, types BuiltOrder.params and BuiltOrder.tx more precisely, moves the TypedDict/Callable import to the top of the file, and changes MatchResult/EventMatchResult from __getattr__ delegation to dataclass inheritance from UnifiedMarket/UnifiedEvent.

Blast Radius

  • Python SDK: sdks/python/pmxt/models.py, sdks/python/pmxt/__init__.py
  • Router client: sdks/python/pmxt/router.py constructs MatchResult/EventMatchResult via _parse_match_result -- this will break

Findings

  1. CRITICAL: MatchResult constructor breakage. The PR changes MatchResult to inherit from UnifiedMarket, which has ~20 required positional fields (market_id, title, outcomes, volume_24h, liquidity, url). The existing _parse_match_result() in router.py (line 45) constructs MatchResult(market=..., relation=..., confidence=..., ...) -- it does NOT supply the parent UnifiedMarket required fields. This will raise TypeError at runtime for every fetch_market_matches / fetch_matches / compare_market_prices call.

  2. CRITICAL: EventMatchResult constructor breakage. Same problem -- EventMatchResult now inherits from UnifiedEvent which requires id, title, description, slug, markets, url as positional args. The EventMatchResult(event=..., market_matches=...) constructor in router.py line 253 will fail.

  3. Mutation in __post_init__. The setattr(self, field, ...) calls inside __post_init__ mutate the object after construction. Per project rules, this should use immutable patterns. More importantly, it silently overwrites fields that happen to be None -- but None may be a legitimate value for optional fields (e.g., description=None), creating subtle data corruption.

  4. market: UnifiedMarket = None # type: ignore[assignment] -- this sets a required-looking field to None by default while silencing the type checker. If downstream code accesses result.market expecting a real UnifiedMarket, it will get None.

  5. Minor: SubscriptionOption, CreateOrderParams, TxPayload additions are clean and correctly match the TS SDK types. No issues there.

PMXT Pipeline Check

  • Field propagation: ISSUE (inheritance model duplicates fields and breaks construction)
  • OpenAPI sync: N/A (no core changes)
  • Type safety: ISSUE (type: ignore suppression, None defaults for required fields)

Semver Impact

major -- breaks existing MatchResult/EventMatchResult construction API

Risk

  • router.py is not updated, so all match-related Router calls will crash at runtime. This PR must either (a) update _parse_match_result and EventMatchResult construction in router.py to supply parent fields, or (b) revert the inheritance approach and keep __getattr__ delegation.

@realfishsam
realfishsam deleted the fix/467-500-501-497-498-models-py branch May 24, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment