The GitHub Actions job "CI" on tvm-ffi.git/main has succeeded. Run started by GitHub user tqchen (triggered by tqchen).
Head commit for run: b87196f998868b2dfb76a7bf2be8795f75b099b8 / Junru Shao <[email protected]> feat(python): expose recursive compare to Python with comprehensive tests (#484) ## Summary - Expose `RecursiveEq`, `RecursiveLt`, `RecursiveLe`, `RecursiveGt`, `RecursiveGe` C++ comparison functions to Python via `_ffi_api` typed stubs - Add three new testing dataclasses (`TestCompare`, `TestCustomCompare`, `TestEqWithoutHash`) to `tvm_ffi.testing` - Add comprehensive `test_dataclass_compare.py` (1272 lines, 101 test cases) covering recursive structural comparison end-to-end from Python ## Architecture - **Python FFI surface**: `_ffi_api.py` gains five `Recursive{Eq,Lt,Le,Gt,Ge}` typed stubs plus `GetKwargsObject` and `MakeInit` (from upstream stub regeneration). These delegate to the C++ `ffi.Recursive*` global functions already registered in the runtime. - **Testing infrastructure**: `tvm_ffi.testing` gains `TestCompare` (field-level `Compare(false)` opt-out), `TestCustomCompare` (custom `__ffi_eq__`/`__ffi_compare__` hooks comparing only `key`), and `TestEqWithoutHash` (equality without hash — exercises the hash-guard path where ordering falls back to reflection). All three are `@register_object`-decorated with C++ reflection stubs. ## Public Interfaces - No public API changes. `RecursiveEq`/`RecursiveLt`/etc. are internal `_ffi_api` symbols used by tests; the C++ functions were already registered on `main`. ## Behavioral Changes - No runtime behavioral changes. This PR adds Python-side bindings and tests only. ## Test Plan 101 tests in `test_dataclass_compare.py` covering: - **Primitives**: int (including int64 extremes where naive subtraction overflows), float (signed zero, infinity), NaN (equality-only; ordering raises `TypeError`; payload-insensitive), bool, string (SmallStr/Str heap boundary, embedded NUL), bytes (SmallBytes/Bytes boundary, embedded NUL, high-bit) - **Special values**: `None` ordering (less than any non-None), type-mismatch (eq returns `False`, ordering raises `TypeError`) - **Inline types**: `DataType`, `Device` - **Containers**: `Array`, `List`, `Map`, `Dict`, `Shape` — equality, lexicographic ordering, empty/prefix/length-mismatch, nested composition (3-level deep) - **Reflected objects**: `TestIntPair` field-by-field structural comparison, `TestCompare` with `Compare(false)` field exclusion, `TestCustomCompare` with custom `__ffi_eq__`/`__ffi_compare__` hooks, cross-type object comparison, inherited fields (2- and 3-level inheritance) - **Cycle detection**: same-pointer identity (returns `True`), distinct cyclic `List`/`Dict` under equality (returns `True` via on-stack pair memoization), distinct cyclic structures under ordering (raises `ValueError`) - **Ordering laws**: trichotomy (exactly one of lt/eq/gt), derived-operator consistency (le ↔ lt∨eq, ge ↔ gt∨eq, lt ↔ ¬ge, gt ↔ ¬le), antisymmetry, and O(n³) transitivity for Lt and Le over `TestIntPair` values - **Advanced**: `CompareOff` flag inside containers and nested objects, `EqWithoutHash` hash guard (eq-only hook with reflection fallback for ordering), `Function` objects (no reflected fields → always equal), depth-1000 nested singleton arrays (iterative stack) ``` uv run pytest -vvs tests/python/test_dataclass_compare.py # 101 passed, 0 failed ``` ## Untested Edge Cases - Asymmetric cycles (`a → b → a` where the two sides have different cycle structure). The C++ `on_stack_` set tracks `(lhs, rhs)` pairs so this should terminate correctly, but no explicit test covers it. Risk: low. - `Tuple` and `Variant` containers are not exercised (no Python constructor surface for `Variant` in `tvm_ffi`). Report URL: https://github.com/apache/tvm-ffi/actions/runs/22509298188 With regards, GitHub Actions via GitBox --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
