Skip to content

Commit bb13eaa

Browse files
authored
doc: add dataclass reflection guide and update related docs (#494)
## Summary Add a comprehensive guide for the dataclass-style reflection system (`ObjectDef`, field traits, auto-init, deep copy, repr, hashing, comparison) and update the Sphinx documentation configuration and cross-references. ## Changes ### New documentation - **`docs/guides/dataclass_reflection.rst`** — A 467-line guide covering: - Quick start: defining a C++ object with `ObjectDef`, using it from Python with full dataclass semantics. - Auto-generated constructors: how `__ffi_init__` is synthesized from reflected fields, including positional, optional, and keyword-only parameter ordering. - Field traits reference: `refl::default_()`, `refl::default_factory()`, `refl::kw_only()`, `refl::init()`, `refl::repr()`, `refl::hash()`, `refl::compare()`, `refl::Metadata`. - Dataclass operations: `DeepCopy`, `ReprPrint`, `RecursiveHash`, `RecursiveEq` with behavioral details (iterative DFS, cycle handling, DAG caching). - Custom hooks via `TypeAttrDef` for hash, equality, comparison, and repr overrides. - Python `c_class` decorator and `@register_object` delegation. - Inheritance semantics for field composition across parent/child object hierarchies. ### Sphinx configuration updates (`docs/conf.py`) - Exclude `tvm::ffi::reflection::default_` and `tvm::ffi::reflection::default_factory` from Doxygen symbol output (these are user-facing helpers that cause Doxygen parse noise). - Fix `_link_inherited_members` to rewrite `.CObject` references as `.Object` in cross-reference links, correcting broken autodoc inherited-member links. - Add `_move`, `__move_handle_from__`, and `__init_handle_by_constructor__` to `_autodoc_always_show`, ensuring these low-level Object lifecycle methods appear in auto-generated API docs. ### Cross-reference fixes in existing docs - **`docs/concepts/object_and_class.rst`**: Update `refl::DefaultValue(0)` to `refl::default_(0)` to match the current preferred API name. - **`docs/guides/export_func_cls.rst`**: Replace broken `:cpp:class:\`tvm::ffi::reflection::init\`` Sphinx cross-reference with inline code literal `` ``init<Args...>()`` `` (the template alias does not resolve as a Doxygen class). ### TOC integration - **`docs/index.rst`**: Insert `guides/dataclass_reflection.rst` into the Guides toctree between `export_func_cls` and `kernel_library_guide`. ## Behavioral changes None. This is a documentation-only change with no code modifications. ## Test evidence Documentation-only PR; no runtime behavior is affected. The guide's code examples are consistent with the existing C++ reflection API (`ObjectDef`, field traits) and Python `c_class`/`register_object` implementations validated by the existing test suite (`tests/python/test_dataclass.py`, `tests/cpp/test_reflection.cc`). ### Untested corner cases - Sphinx build with the new RST file has not been verified in CI yet (will be validated by the doc-build CI job). - The `.CObject` -> `.Object` rewrite in `_link_inherited_members` is a string replacement; edge cases where a class legitimately contains "CObject" in its qualified name would be incorrectly rewritten (none exist in the current codebase).
1 parent dad4c40 commit bb13eaa

File tree

5 files changed

+477
-3
lines changed

5 files changed

+477
-3
lines changed

docs/concepts/object_and_class.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ to register reflection metadata for object type ``T``:
393393
refl::ObjectDef<MyObjectObj>()
394394
.def_rw("value", &MyObjectObj::value,
395395
"The numeric value", // docstring
396-
refl::DefaultValue(0), // default value
396+
refl::default_(0), // default value
397397
refl::Metadata{{"min", 0}, {"max", 100}}) // custom metadata
398398
.def("add_to_value", &MyObjectObj::AddToValue,
399399
"Add a value to the object's value field");

docs/conf.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@
9292
TVM_FFI_EXTRA_CXX_API= TVM_FFI_WEAK= TVM_FFI_DOXYGEN_MODE \
9393
__cplusplus=201703
9494
EXCLUDE_SYMBOLS += *details* *TypeTraits* std \
95-
*use_default_type_traits_v* *is_optional_type_v* *operator*
95+
*use_default_type_traits_v* *is_optional_type_v* *operator* \
96+
tvm::ffi::reflection::default_ tvm::ffi::reflection::default_factory
9697
EXCLUDE_PATTERNS += */function_details.h */container_details.h
9798
ENABLE_PREPROCESSING = YES
9899
MACRO_EXPANSION = YES
@@ -292,6 +293,8 @@ def _link_inherited_members(app, what, name, obj, options, lines) -> None: # no
292293
if base in _py_native_classes or getattr(base, "__module__", "") == "builtins":
293294
return
294295
owner_fq = f"{base.__module__}.{base.__qualname__}".replace("tvm_ffi.core.", "tvm_ffi.")
296+
if owner_fq.endswith(".CObject"):
297+
owner_fq = owner_fq.removesuffix(".CObject") + ".Object"
295298
role = "attr" if what in {"attribute", "property"} else "meth"
296299
lines.clear()
297300
lines.append(
@@ -338,6 +341,9 @@ def _import_cls(cls_name: str) -> type | None:
338341
"__ffi_init__",
339342
"__from_extern_c__",
340343
"__from_mlir_packed_safe_call__",
344+
"_move",
345+
"__move_handle_from__",
346+
"__init_handle_by_constructor__",
341347
}
342348
# If a member method comes from one of these native types, hide it in the docs
343349
_py_native_classes: tuple[type, ...] = (

0 commit comments

Comments
 (0)