Skip to content

SDK drift: EventMatchResult extends UnifiedEvent in TypeScript but is a standalone dataclass in Python #498

@realfishsam

Description

@realfishsam

Drift

Same structural pattern as MatchResult (#497): In TypeScript, EventMatchResult extends Readonly<UnifiedEvent>, giving all event fields (id, title, slug, markets, etc.) as first-class typed properties. In Python it is a plain dataclass with event: UnifiedEvent and __getattr__ delegation — event fields are invisible to type checkers.

TypeScript SDK

sdks/typescript/pmxt/models.ts, lines 844–851:

/** A cross-venue event match with constituent market matches.
 *  Event properties (title, slug, url, etc.) are accessible directly on the result. */
export interface EventMatchResult extends Readonly<UnifiedEvent> {
    event: UnifiedEvent;
    marketMatches: MatchResult[];
}

All UnifiedEvent fields (id, title, description, slug, markets, url, volume24h, etc.) are statically typed on EventMatchResult.

Python SDK

sdks/python/pmxt/models.py, lines 626–637:

@dataclass
class EventMatchResult:
    event: UnifiedEvent
    market_matches: List[MatchResult]

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

Only event and market_matches are declared dataclass fields. UnifiedEvent fields are delegated at runtime and invisible to type checkers and IDEs.

Expected

Both SDKs should expose the same statically-typed surface for EventMatchResult. Python should either declare the event fields explicitly or document the dynamic delegation gap so users know mypy/pyright will report false errors.

Impact

Mypy reports error: "EventMatchResult" has no attribute "title" (or id, slug, markets, etc.) despite those attributes working at runtime. Users migrating from TypeScript expect result.title and result.markets to be typed; in Python they silently fall through __getattr__.


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