gemini-code-assist[bot] commented on code in PR #427: URL: https://github.com/apache/tvm-ffi/pull/427#discussion_r2768085497
########## docs/packaging/stubgen.rst: ########## @@ -0,0 +1,400 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. _sec-stubgen: + +Stub Generation +=============== + +TVM-FFI provides ``tvm-ffi-stubgen``, a tool that generates Python type stubs from C++ +reflection metadata. It turns registered global functions and classes into proper Python +type hints, enabling IDE auto-completion and static type checking. + +.. admonition:: Prerequisite + :class: hint + + This tutorial uses `examples/python_packaging <https://github.com/apache/tvm-ffi/tree/main/examples/python_packaging>`_ + as a running example. The package registers global functions (``my_ffi_extension.add_one``, + ``my_ffi_extension.raise_error``) and an object type (``my_ffi_extension.IntPair``). + +.. _sec-stubgen-cmake: + +CMake-based Generation +---------------------- + +The recommended approach is to use CMake's ``tvm_ffi_configure_target`` function. +This runs stub generation automatically after each build. + +.. code-block:: cmake + + tvm_ffi_configure_target(<target> + STUB_DIR <dir> + [STUB_INIT ON|OFF] + [STUB_PKG <pkg>] + [STUB_PREFIX <prefix>] + ) + +From the example's +`CMakeLists.txt <https://github.com/apache/tvm-ffi/blob/main/examples/python_packaging/CMakeLists.txt>`_: + +.. code-block:: cmake + + add_library(my_ffi_extension SHARED src/extension.cc) + tvm_ffi_configure_target(my_ffi_extension STUB_DIR "./python" STUB_INIT ON) + +STUB_DIR + Required. Directory containing Python source files, relative to ``CMAKE_CURRENT_SOURCE_DIR``. + +STUB_INIT (default: ``OFF``) + Optional. When ``OFF``, fills in existing inline directives without creating + new ones. When ``ON``, generates new files and directives. + +``STUB_INIT`` is ``OFF`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +The tool fills in existing inline directives only. It scans files for directive markers +and regenerates the content within those blocks: + +- Class fields and methods (``object/<type_key>``) + + .. code-block:: python + + @tvm_ffi.register_object("my_ffi_extension.IntPair") + class IntPair(tvm_ffi.Object): + # tvm-ffi-stubgen(begin): object/my_ffi_extension.IntPair + a: int + b: int + if TYPE_CHECKING: + @staticmethod + def __c_ffi_init__(_0: int, _1: int, /) -> Object: ... Review Comment:  The generated constructor stub `__c_ffi_init__` is an implementation detail. For user-facing documentation, it's better to show the Python `__init__` method with meaningful argument names, as it is shown in other examples in this document (e.g., lines 322-323). This will make the documentation more consistent and easier for users to understand. ```suggestion def __init__(self, a: int, b: int) -> None: ... ``` ########## docs/packaging/stubgen.rst: ########## @@ -0,0 +1,400 @@ +.. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + +.. http://www.apache.org/licenses/LICENSE-2.0 + +.. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. _sec-stubgen: + +Stub Generation +=============== + +TVM-FFI provides ``tvm-ffi-stubgen``, a tool that generates Python type stubs from C++ +reflection metadata. It turns registered global functions and classes into proper Python +type hints, enabling IDE auto-completion and static type checking. + +.. admonition:: Prerequisite + :class: hint + + This tutorial uses `examples/python_packaging <https://github.com/apache/tvm-ffi/tree/main/examples/python_packaging>`_ + as a running example. The package registers global functions (``my_ffi_extension.add_one``, + ``my_ffi_extension.raise_error``) and an object type (``my_ffi_extension.IntPair``). + +.. _sec-stubgen-cmake: + +CMake-based Generation +---------------------- + +The recommended approach is to use CMake's ``tvm_ffi_configure_target`` function. +This runs stub generation automatically after each build. + +.. code-block:: cmake + + tvm_ffi_configure_target(<target> + STUB_DIR <dir> + [STUB_INIT ON|OFF] + [STUB_PKG <pkg>] + [STUB_PREFIX <prefix>] + ) + +From the example's +`CMakeLists.txt <https://github.com/apache/tvm-ffi/blob/main/examples/python_packaging/CMakeLists.txt>`_: + +.. code-block:: cmake + + add_library(my_ffi_extension SHARED src/extension.cc) + tvm_ffi_configure_target(my_ffi_extension STUB_DIR "./python" STUB_INIT ON) + +STUB_DIR + Required. Directory containing Python source files, relative to ``CMAKE_CURRENT_SOURCE_DIR``. + +STUB_INIT (default: ``OFF``) + Optional. When ``OFF``, fills in existing inline directives without creating + new ones. When ``ON``, generates new files and directives. + +``STUB_INIT`` is ``OFF`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +The tool fills in existing inline directives only. It scans files for directive markers +and regenerates the content within those blocks: + +- Class fields and methods (``object/<type_key>``) + + .. code-block:: python + + @tvm_ffi.register_object("my_ffi_extension.IntPair") + class IntPair(tvm_ffi.Object): + # tvm-ffi-stubgen(begin): object/my_ffi_extension.IntPair + a: int + b: int + if TYPE_CHECKING: + @staticmethod + def __c_ffi_init__(_0: int, _1: int, /) -> Object: ... + def sum(self, /) -> int: ... + # tvm-ffi-stubgen(end) + +- Global functions (``global/<prefix>``) + + .. code-block:: python + + # tvm-ffi-stubgen(begin): global/my_ffi_extension + tvm_ffi.init_ffi_api("my_ffi_extension", __name__) + if TYPE_CHECKING: + def add_one(_0: int, /) -> int: ... + def raise_error(_0: str, /) -> None: ... + # tvm-ffi-stubgen(end) + +- Import sections, ``__all__`` lists, and exports (``import-section``, ``__all__``, ``export/<module>``) + +See :ref:`sec-stubgen-directives` for a complete reference of all inline directives. + +.. important:: + + No new files or directives are created. Use this mode after you have customized the + generated files and want to preserve your changes. + +``STUB_INIT`` is ``ON`` +~~~~~~~~~~~~~~~~~~~~~~~ + +The tool generates new files (``_ffi_api.py``, ``__init__.py``) and new directives from +scratch. This is the recommended starting point for new projects. Two additional options +are available: + +STUB_PKG (default: ``SKBUILD_PROJECT_NAME`` or CMake target name) + Python package name. Determines the directory structure (``<STUB_DIR>/<STUB_PKG>/``) and + generates the library loading code in ``_ffi_api.py``: + + .. code-block:: python + + LIB = tvm_ffi.libinfo.load_lib_module("<STUB_PKG>", "<cmake-target-name>") + + This uses :py:func:`tvm_ffi.libinfo.load_lib_module` to load the shared library. + +STUB_PREFIX (default: ``<STUB_PKG>.``) + Registry prefix filter. Only functions and classes whose registered names start with this + prefix are included. The tool generates: + + - ``global/<prefix>`` directives for global functions. In ``<STUB_DIR>/<STUB_PKG>/_ffi_api.py``: + + .. code-block:: python + + # tvm-ffi-stubgen(begin): global/<STUB_PREFIX> + ... + # tvm-ffi-stubgen(end) + + Functions in nested namespaces (e.g., ``<STUB_PREFIX>submodule.func``) are placed in + corresponding subdirectories. + + - ``object/<type_key>`` directives for each registered class. For a class with type key + ``<STUB_PREFIX>IntPair``: + + .. code-block:: python + + @tvm_ffi.register_object("<STUB_PREFIX>IntPair") + class IntPair(_ffi_Object): + # tvm-ffi-stubgen(begin): object/<STUB_PREFIX>IntPair + a: int + b: int + if TYPE_CHECKING: + @staticmethod + def __c_ffi_init__(_0: int, _1: int, /) -> Object: ... Review Comment:  Similar to the previous comment, `__c_ffi_init__` should be replaced with the user-facing `__init__` for consistency and clarity in the documentation. Using meaningful parameter names like `a` and `b` instead of `_0` and `_1` would also improve readability. ```suggestion def __init__(self, a: int, b: int) -> None: ... ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
