Skip to content

SDK drift: MatchResult extends UnifiedMarket in TypeScript but is a standalone dataclass in Python #497

@realfishsam

Description

@realfishsam

Drift

In TypeScript, MatchResult extends Readonly<UnifiedMarket>, meaning all UnifiedMarket fields (marketId, title, outcomes, volume24h, etc.) are first-class typed properties of MatchResult. In Python, MatchResult is a standalone dataclass that holds a market: UnifiedMarket field and uses __getattr__ to delegate attribute access at runtime. The public static-typed API surface is therefore different: TypeScript users get full type-checked access to every market field directly on MatchResult; Python users only see the explicit dataclass fields in type checkers.

TypeScript SDK

sdks/typescript/pmxt/models.ts, lines 820–841:

/** A cross-venue market match with relation classification.
 *  Market properties (title, slug, url, etc.) are accessible directly on the result. */
export interface MatchResult extends Readonly<UnifiedMarket> {
    market: UnifiedMarket;
    relation: MatchRelation;
    confidence: number;
    reasoning?: string;
    bestBid?: number;
    bestAsk?: number;
    sourceMarket?: UnifiedMarket;
}

All UnifiedMarket fields (marketId, title, slug, outcomes, volume24h, liquidity, url, resolutionDate, etc.) are statically typed on MatchResult.

Python SDK

sdks/python/pmxt/models.py, lines 597–623:

@dataclass
class MatchResult:
    market: UnifiedMarket
    relation: MatchRelation
    confidence: float
    reasoning: Optional[str] = None
    best_bid: Optional[float] = None
    best_ask: Optional[float] = None
    source_market: Optional[UnifiedMarket] = None

    def __getattr__(self, name: str) -> Any:
        return getattr(self.market, name)

The dataclass fields are: market, relation, confidence, reasoning, best_bid, best_ask, source_market. UnifiedMarket fields are delegated via __getattr__ at runtime but are invisible to type checkers, IDEs, and hasattr.

Expected

Both SDKs should expose the same typed public surface for MatchResult. Either Python adds explicit typed fields mirroring UnifiedMarket, or the discrepancy is documented. The TypeScript pattern of inheriting/spreading all market fields makes result.title, result.marketId, etc. statically typed; the Python __getattr__ approach makes them invisible to mypy/pyright.

Impact

Python users get no IDE autocompletion or type-checker support for market fields on MatchResult. Code that does match.title or match.market_id works at runtime (via __getattr__) but mypy reports error: "MatchResult" has no attribute "title". Users coming from TypeScript where those fields are first-class will be confused by the type errors.


Found by automated SDK cross-language drift 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