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]

Reply via email to