This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new b7cb28b5 ci(lint): run hooks through the uv development environment
(#669)
b7cb28b5 is described below
commit b7cb28b51fbb05a5cd5b1c8a4c9407005e6fe151
Author: Junru Shao <[email protected]>
AuthorDate: Wed Jul 15 15:21:40 2026 -0700
ci(lint): run hooks through the uv development environment (#669)
## Summary
- Convert the pre-commit configuration to local system hooks whose
executables come from the uv development dependency group.
- Pin the hook toolchain in `pyproject.toml`, align the Ruff D102 test
exemption, and remove redundant per-file suppressions.
- Run pre-commit explicitly through uv in GitHub Actions so CI uses the
environment provisioned by `uv sync`.
## Architecture
- The uv `dev` dependency group is the single source of truth for hook
tool versions.
- Pre-commit remains the orchestration layer, while hook processes
execute from the active project environment instead of isolated
repository environments.
- The CI lint job now provisions and consumes the same environment,
eliminating the runtime boundary that caused `pre-commit/action` to miss
the pinned executables.
## Public Interfaces
- No runtime API, ABI, schema, or CLI behavior changes.
- The development dependency group now requires Python 3.10 or newer.
## UI/UX
- None.
## Behavioral Changes
- Ruff, ty, clang-format, YAML, Cython, shell, and CMake checks resolve
from the uv development environment.
- CI invokes `uv run --no-sync pre-commit run --show-diff-on-failure
--color=always --all-files` after provisioning that environment.
- The D102 exemption is applied centrally, and redundant test-file
suppressions are removed.
- Hooks not supplied by the development environment are no longer
configured.
## Breaking Changes and Migration
- No runtime breaking changes.
- Contributors running hooks outside an activated development
environment should use `uv run --no-sync pre-commit ...` after syncing
the `dev` dependency group.
## Docs
- No user-facing documentation changes are required; the development and
CI configuration directly records the workflow.
## Tests
- `uv run --no-sync pre-commit validate-config .pre-commit-config.yaml`
- `uv run --no-sync ruff check tests/python/test_dataclass_common.py
tests/python/test_dataclass_copy.py
tests/python/test_dataclass_frozen.py
tests/python/test_dataclass_init.py
tests/python/test_dataclass_py_class.py`
- `uv sync --group dev --no-install-project`
- `uv run --no-sync pre-commit run --show-diff-on-failure --color=always
--all-files` — all configured hooks passed.
- `git diff --check` and `git diff --cached --check` — passed.
## Untested Edge Cases
- Fresh development-environment provisioning on every supported platform
has not been exercised locally.
- The GitHub-hosted Ubuntu runner execution is left to CI; risk is low
because the exact workflow command passed against the provisioned uv
environment.
## Commits
- `a385ed3d` — centralize system hooks in the uv development
environment.
- `338e8b4a` — invoke pre-commit through uv in CI.
---
.github/workflows/ci_test.yml | 3 +-
.pre-commit-config.yaml | 141 +++++++++++++++++---------------
pyproject.toml | 11 ++-
tests/python/test_dataclass_common.py | 2 +-
tests/python/test_dataclass_copy.py | 2 +-
tests/python/test_dataclass_frozen.py | 2 +-
tests/python/test_dataclass_init.py | 1 -
tests/python/test_dataclass_py_class.py | 2 +-
8 files changed, 91 insertions(+), 73 deletions(-)
diff --git a/.github/workflows/ci_test.yml b/.github/workflows/ci_test.yml
index b63c965c..6be07081 100644
--- a/.github/workflows/ci_test.yml
+++ b/.github/workflows/ci_test.yml
@@ -75,7 +75,8 @@ jobs:
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 #
v8.2.0
- name: Set up Python environment
run: uv sync --group dev --no-install-project
- - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #
v3.0.1
+ - name: Run pre-commit
+ run: uv run --no-sync pre-commit run --show-diff-on-failure
--color=always --all-files
clang-tidy:
needs: [prepare]
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index a2cabf28..e2934785 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -23,106 +23,117 @@ repos:
- id: check-asf-header
name: check ASF Header
entry: python tests/lint/check_asf_header.py --check
- language: python
- language_version: python3
+ language: system
pass_filenames: false
verbose: false
- - repo: local
- hooks:
- id: check-file-type
name: check file types
entry: python tests/lint/check_file_type.py
- language: python
- language_version: python3
+ language: system
pass_filenames: false
verbose: false
- - repo: local
- hooks:
- id: check-version-consistency
name: check version consistency
entry: python tests/lint/check_version.py --cpp # TODO: add `--rust`
once Rust binding matures
- language: python
- language_version: python3
- additional_dependencies:
- - setuptools-scm
- - packaging
- - tomli
+ language: system
pass_filenames: false
verbose: false
- - repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v6.0.0
- hooks:
- id: check-added-large-files
+ name: check added large files
+ entry: check-added-large-files
+ language: system
- id: check-case-conflict
+ name: check case conflict
+ entry: check-case-conflict
+ language: system
- id: check-merge-conflict
+ name: check merge conflict
+ entry: check-merge-conflict
+ language: system
+ types: [text]
- id: check-symlinks
+ name: check symlinks
+ entry: check-symlinks
+ language: system
+ types: [symlink]
- id: end-of-file-fixer
+ name: fix end of files
+ entry: end-of-file-fixer
+ language: system
+ types: [text]
- id: mixed-line-ending
+ name: mixed line ending
+ entry: mixed-line-ending
+ language: system
+ types: [text]
- id: requirements-txt-fixer
+ name: fix requirements.txt
+ entry: requirements-txt-fixer
+ language: system
+ files: (^|/)requirements.*\.txt$
- id: trailing-whitespace
+ name: trim trailing whitespace
+ entry: trailing-whitespace-fixer
+ language: system
+ types: [text]
- id: check-yaml
+ name: check yaml
+ entry: check-yaml
+ language: system
+ types: [yaml]
- id: check-toml
- - repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.14.9
- hooks:
+ name: check toml
+ entry: check-toml
+ language: system
+ types: [toml]
- id: ruff-check
+ name: ruff check
+ entry: ruff check --fix
+ language: system
types_or: [python, pyi, jupyter]
- args: [--fix]
- id: ruff-format
+ name: ruff format
+ entry: ruff format
+ language: system
types_or: [python, pyi, jupyter]
- - repo: local
- hooks:
- id: ty
name: ty check
- entry: uvx [email protected] check --error-on-warning
+ entry: uv run --no-sync ty check --error-on-warning
language: system
pass_filenames: false
types: [python]
- - repo: https://github.com/pre-commit/mirrors-clang-format
- rev: "v21.1.7"
- hooks:
- id: clang-format
- - repo: https://github.com/adrienverge/yamllint
- rev: v1.37.1
- hooks:
+ name: clang-format
+ entry: clang-format -i
+ language: system
+ files: \.(c|cc|cpp|cxx|h|hh|hpp|hxx|cu|cuh|m|mm)$
- id: yamllint
- args:
- - --config-file
- - .yamllint.yaml
- - repo: https://github.com/ComPWA/taplo-pre-commit
- rev: v0.9.3
- hooks:
- - id: taplo-format
- - repo: https://github.com/MarcoGorelli/cython-lint
- rev: v0.18.1
- hooks:
+ name: yamllint
+ entry: yamllint --config-file .yamllint.yaml
+ language: system
+ types: [yaml]
- id: cython-lint
- args: [--max-line-length=120]
+ name: cython-lint
+ entry: cython-lint --max-line-length=120
+ language: system
+ files: \.(pyx|pxd|pxi)$
- id: double-quote-cython-strings
- - repo: https://github.com/scop/pre-commit-shfmt
- rev: v3.12.0-2
- hooks:
- - id: shfmt
- args: [--indent=2]
- - repo: https://github.com/shellcheck-py/shellcheck-py
- rev: v0.11.0.1
- hooks:
+ name: double quote cython strings
+ entry: double-quote-cython-strings
+ language: system
+ files: \.(pyx|pxd|pxi)$
- id: shellcheck
- - repo: https://github.com/DavidAnson/markdownlint-cli2
- rev: v0.20.0
- hooks:
- - id: markdownlint-cli2
- - repo: https://github.com/rstcheck/rstcheck
- rev: v6.2.5
- hooks:
- - id: rstcheck
- additional_dependencies:
- - rstcheck[sphinx]
- args:
- - --config
- - docs/.rstcheck.cfg
- - repo: https://github.com/cheshirekow/cmake-format-precommit
- rev: v0.6.13
- hooks:
+ name: shellcheck
+ entry: shellcheck
+ language: system
+ types: [shell]
- id: cmake-format
+ name: cmake-format
+ entry: cmake-format -i
+ language: system
+ files: (^|/)(CMakeLists\.txt|.*\.cmake)$
- id: cmake-lint
+ name: cmake-lint
+ entry: cmake-lint
+ language: system
+ files: (^|/)(CMakeLists\.txt|.*\.cmake)$
diff --git a/pyproject.toml b/pyproject.toml
index 8cae0f0f..919b9706 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -53,17 +53,22 @@ test = [{ include-group = "torch" }, "pytest",
"pytest-xdist"]
dev = [
{ include-group = "test" },
"pre-commit",
- "ruff",
+ "pre-commit-hooks==6.0.0",
+ "ruff==0.14.9",
"ty==0.0.15",
- "clang-format",
+ "clang-format==21.1.7",
"clang-tidy",
+ "cmakelang==0.6.13",
"ipdb",
"ipython",
"cython>=3.0",
+ "cython-lint==0.18.1",
"cmake",
"scikit-build-core",
+ "shellcheck-py==0.11.0.1",
"tomli",
"setuptools-scm",
+ "yamllint==1.37.1",
]
docs = [
"autodocsumm",
@@ -217,6 +222,7 @@ unfixable = []
"E741", # pycodestyle: ambiguous-variable-name
"D100", # pydocstyle: undocumented-public-module
"D101", # pydocstyle: undocumented-public-class
+ "D102", # pydocstyle: undocumented-public-method
"D103", # pydocstyle: undocumented-public-function
"D107", # pydocstyle: undocumented-public-init
"D205", # pydocstyle: missing-blank-line-after-summary
@@ -294,6 +300,7 @@ allowed-unresolved-imports = [
exclude-newer = "14 days"
[tool.uv.dependency-groups]
+dev = { requires-python = ">=3.10" }
docs = { requires-python = ">=3.13" }
[tool.setuptools_scm]
diff --git a/tests/python/test_dataclass_common.py
b/tests/python/test_dataclass_common.py
index 8de63371..95beee03 100644
--- a/tests/python/test_dataclass_common.py
+++ b/tests/python/test_dataclass_common.py
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-# ruff: noqa: D102, UP006, UP035, UP045
+# ruff: noqa: UP006, UP035, UP045
"""Tests for :func:`tvm_ffi.dataclasses.is_dataclass`, :func:`fields`,
:func:`replace`."""
from __future__ import annotations
diff --git a/tests/python/test_dataclass_copy.py
b/tests/python/test_dataclass_copy.py
index 861d8376..52e0aa26 100644
--- a/tests/python/test_dataclass_copy.py
+++ b/tests/python/test_dataclass_copy.py
@@ -14,7 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-# ruff: noqa: D102, UP006, UP035, UP045
+# ruff: noqa: UP006, UP035, UP045
"""Tests for __copy__, __deepcopy__, and __replace__ on FFI objects."""
from __future__ import annotations
diff --git a/tests/python/test_dataclass_frozen.py
b/tests/python/test_dataclass_frozen.py
index 4d28ef2a..c197d00c 100644
--- a/tests/python/test_dataclass_frozen.py
+++ b/tests/python/test_dataclass_frozen.py
@@ -16,7 +16,7 @@
# under the License.
"""Tests for frozen support in ``@py_class``."""
-# ruff: noqa: D102, UP006, UP035, UP045
+# ruff: noqa: UP006, UP035, UP045
from __future__ import annotations
import copy
diff --git a/tests/python/test_dataclass_init.py
b/tests/python/test_dataclass_init.py
index 639c1803..6280d152 100644
--- a/tests/python/test_dataclass_init.py
+++ b/tests/python/test_dataclass_init.py
@@ -26,7 +26,6 @@ This file exercises:
7. re-initialization, isinstance checks, and instance isolation
"""
-# ruff: noqa: D102
from __future__ import annotations
import copy
diff --git a/tests/python/test_dataclass_py_class.py
b/tests/python/test_dataclass_py_class.py
index 6b9bbdd4..99bfcbb2 100644
--- a/tests/python/test_dataclass_py_class.py
+++ b/tests/python/test_dataclass_py_class.py
@@ -16,7 +16,7 @@
# under the License.
"""Tests for Python-defined TVM-FFI types: ``@py_class`` decorator and
low-level Field API."""
-# ruff: noqa: D102, PLR0124, PLW1641, UP006, UP035, UP045
+# ruff: noqa: PLR0124, PLW1641, UP006, UP035, UP045
from __future__ import annotations
import copy