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 b5dd851 fix(c_class): Fix mypy warnings on `dataclasses.field(...)`
(#43)
b5dd851 is described below
commit b5dd851f7019f4f63a19d9dce074ba62706f16e7
Author: Junru Shao <[email protected]>
AuthorDate: Mon Sep 22 16:38:23 2025 -0700
fix(c_class): Fix mypy warnings on `dataclasses.field(...)` (#43)
Previously when defining a `c_class`, when RHS invokes a
`dataclasses.field(...)`, as exemplified below:
```python
v_str: str = field(default_factory=lambda: "default")
```
we will get a warning saying
```
error: Incompatible types in assignment (expression has type "Field",
variable has type "str") [assignment]
```
This PR fixes this issue
---
pyproject.toml | 2 +-
python/tvm_ffi/dataclasses/field.py | 22 +++++++++++++++++-----
python/tvm_ffi/testing.py | 4 ++--
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index c7e43db..d51698f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -32,7 +32,7 @@ classifiers = [
]
keywords = ["machine learning", "inference"]
requires-python = ">=3.9"
-dependencies = []
+dependencies = ["typing-extensions"]
[project.urls]
Homepage = "https://github.com/apache/tvm-ffi"
diff --git a/python/tvm_ffi/dataclasses/field.py
b/python/tvm_ffi/dataclasses/field.py
index f1a582e..2a62d66 100644
--- a/python/tvm_ffi/dataclasses/field.py
+++ b/python/tvm_ffi/dataclasses/field.py
@@ -18,8 +18,10 @@
from __future__ import annotations
-from dataclasses import MISSING
-from typing import Any, Callable
+from dataclasses import _MISSING_TYPE, MISSING
+from typing import Any, Callable, TypeVar, cast
+
+_FieldValue = TypeVar("_FieldValue")
class Field:
@@ -37,13 +39,22 @@ class Field:
__slots__ = ("default_factory", "name")
- def __init__(self, *, name: str | None = None, default_factory:
Callable[[], Any]) -> None:
+ def __init__(
+ self,
+ *,
+ name: str | None = None,
+ default_factory: Callable[[], _FieldValue] | _MISSING_TYPE = MISSING,
+ ) -> None:
"""Do not call directly; use :func:`field` instead."""
self.name = name
self.default_factory = default_factory
-def field(*, default: Any = MISSING, default_factory: Any = MISSING) -> Field:
+def field(
+ *,
+ default: _FieldValue | _MISSING_TYPE = MISSING, # type: ignore[assignment]
+ default_factory: Callable[[], _FieldValue] | _MISSING_TYPE = MISSING, #
type: ignore[assignment]
+) -> _FieldValue:
"""(Experimental) Declare a dataclass-style field on a :func:`c_class`
proxy.
Use this helper exactly like :func:`dataclasses.field` when defining the
@@ -86,7 +97,8 @@ def field(*, default: Any = MISSING, default_factory: Any =
MISSING) -> Field:
raise ValueError("Cannot specify both `default` and `default_factory`")
if default is not MISSING:
default_factory = _make_default_factory(default)
- return Field(default_factory=default_factory)
+ ret = Field(default_factory=default_factory)
+ return cast(_FieldValue, ret)
def _make_default_factory(value: Any) -> Callable[[], Any]:
diff --git a/python/tvm_ffi/testing.py b/python/tvm_ffi/testing.py
index 9769158..f74abc2 100644
--- a/python/tvm_ffi/testing.py
+++ b/python/tvm_ffi/testing.py
@@ -103,5 +103,5 @@ class _TestCxxClassDerived(_TestCxxClassBase):
@c_class("testing.TestCxxClassDerivedDerived")
class _TestCxxClassDerivedDerived(_TestCxxClassDerived):
- v_str: str = field(default_factory=lambda: "default") # type:
ignore[assignment]
- v_bool: bool # type: ignore[misc]
+ v_str: str = field(default_factory=lambda: "default")
+ v_bool: bool # type: ignore[misc] # Suppress: Attributes without a
default cannot follow attributes with one