The GitHub Actions job "mainline-only" on tvm-ffi.git/main has failed. Run started by GitHub user junrushao (triggered by junrushao).
Head commit for run: bc8f30d77b49f5386bc2d43a0cf4ec053fa0e05a / Junru Shao <[email protected]> feat(python): add `@py_class` decorator for Python-defined FFI dataclasses (#506) ## Summary Add `@py_class`, a new decorator that lets users define TVM FFI Object types entirely in Python with dataclass-style field annotations. This complements `@c_class` (which wraps C++-backed types) by enabling pure-Python FFI types that participate in the same object system -- type registry, reference counting, cross-language serialization, and packed-function interop. ### Motivation Currently, defining a new FFI-visible type requires either writing C++ (`ObjectDef<T>`) or using `@c_class` which expects C++ reflection metadata. `@py_class` removes the C++ requirement entirely: annotate fields with Python types, and the decorator handles type-index allocation, field registration, and dunder generation. ### Usage ```python from tvm_ffi.dataclasses import py_class, field from tvm_ffi import Object @py_class class Point(Object): x: float y: float @py_class("my.namespace.Line", eq=True) class Line(Object): start: Point end: Point label: str = "default" ``` ## Architecture Registration is split into two phases to handle forward and mutual references: - **Phase 1** (`_phase1_register_type`): Allocates a C-level type index and inserts the class into the global type registry. Runs eagerly so that self-referential and mutually-referential annotations can be resolved. - **Phase 2** (`_phase2_register_fields`): Resolves string annotations via `typing.get_type_hints`, converts them to `TypeSchema`/`Field` objects, validates field ordering, registers fields with the Cython layer, and installs `__init__`/`__repr__`/`__eq__`/etc. When `get_type_hints` raises `NameError` (forward reference not yet defined), the class is deferred to a pending list and retried after each successful phase-2. A temporary `__init__` triggers lazy completion on first instantiation. Failed phase-2 rolls back phase-1 so the type key can be reused. ## Public Interfaces | Symbol | Location | Description | |--------|----------|-------------| | `@py_class` | `tvm_ffi.dataclasses.py_class` | Main decorator (bare, string-key, and kwarg calling conventions) | | Parameters | `type_key`, `init`, `repr`, `eq`, `order`, `unsafe_hash`, `kw_only`, `slots` | Mirrors `dataclasses.dataclass` semantics | ## Test Plan - [x] 246 tests across 47 test classes (`tests/python/test_dataclass_py_class.py`, 3533 lines) - [x] Coverage includes: basic registration, field parsing, defaults/factories, kw_only, ClassVar, init generation, post_init, repr, equality, ordering, hashing, copy/deepcopy, single/multi-level inheritance, forward/mutual references, dunder preservation, registration rollback, type conversion errors, getter/setter corner cases, memory lifetime, bool alignment, optional fields, Any fields, FFI global function interop - [x] All 1817 Python tests pass (25 skipped, 3 xfailed) -- no regressions - [x] All pre-commit hooks pass ### Untested Edge Cases - Thread safety of the pending-class flush mechanism - Interaction with `importlib.reload()` on modules containing `@py_class`-decorated types - Deeply nested generic type annotations (e.g. `List[Optional[Map[str, Array[int]]]]`) Report URL: https://github.com/apache/tvm-ffi/actions/runs/23389552989 With regards, GitHub Actions via GitBox --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
