blob: c5b773ac8a3c7e66a72ed164dd57e7665c450846 [file]
# 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.
"""Testing utilities."""
# ruff: noqa: D102
# tvm-ffi-stubgen(begin): import-section
# fmt: off
# isort: off
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Mapping, Sequence
from tvm_ffi import Device, dtype
from typing import Any
# isort: on
# fmt: on
# tvm-ffi-stubgen(end)
import sys
from typing import Any, ClassVar
import pytest
from tvm_ffi import Object, get_global_func
from tvm_ffi.dataclasses import c_class
from .. import _ffi_api
from .. import core as tvm_ffi_core
requires_py39 = pytest.mark.skipif(
sys.version_info < (3, 9),
reason="requires Python 3.9+",
)
requires_py310 = pytest.mark.skipif(
sys.version_info < (3, 10),
reason="requires Python 3.10+",
)
requires_py312 = pytest.mark.skipif(
sys.version_info < (3, 12),
reason="requires Python 3.12+",
)
requires_py313 = pytest.mark.skipif(
sys.version_info < (3, 13),
reason="requires Python 3.13+",
)
@c_class("testing.TestObjectBase")
class TestObjectBase(Object):
"""Test object base class."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestObjectBase
# fmt: off
v_i64: int
v_f64: float
v_str: str
if TYPE_CHECKING:
def __init__(self, v_i64: int = ..., v_f64: float = ..., v_str: str = ...) -> None: ...
def __ffi_init__(self, v_i64: int = ..., v_f64: float = ..., v_str: str = ...) -> None: ... # ty: ignore[invalid-method-override]
def add_i64(self, _1: int, /) -> int: ...
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestIntPair")
class TestIntPair(Object):
"""Test Int Pair."""
__test__: ClassVar[bool] = False
# tvm-ffi-stubgen(begin): object/testing.TestIntPair
# fmt: off
a: int
b: int
if TYPE_CHECKING:
def __init__(self, a: int, b: int) -> None: ...
def __ffi_init__(self, _0: int, _1: int, /) -> None: ... # ty: ignore[invalid-method-override]
def sum(self, /) -> int: ...
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestObjectDerived")
class TestObjectDerived(TestObjectBase):
"""Test object derived class."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestObjectDerived
# fmt: off
v_map: Mapping[Any, Any]
v_array: Sequence[Any]
if TYPE_CHECKING:
def __init__(self, v_map: Mapping[Any, Any], v_array: Sequence[Any], v_i64: int = ..., v_f64: float = ..., v_str: str = ...) -> None: ...
def __ffi_init__(self, v_map: Mapping[Any, Any], v_array: Sequence[Any], v_i64: int = ..., v_f64: float = ..., v_str: str = ...) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestNonCopyable")
class TestNonCopyable(Object):
"""Test object with deleted copy constructor."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestNonCopyable
# fmt: off
value: int
if TYPE_CHECKING:
def __init__(self, value: int) -> None: ...
def __ffi_init__(self, _0: int, /) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.SchemaAllTypes")
class _SchemaAllTypes:
# tvm-ffi-stubgen(ty-map): testing.SchemaAllTypes -> testing._SchemaAllTypes
# tvm-ffi-stubgen(begin): object/testing.SchemaAllTypes
# fmt: off
v_bool: bool
v_int: int
v_float: float
v_device: Device
v_dtype: dtype
v_string: str
v_bytes: bytes
v_opt_int: int | None
v_opt_str: str | None
v_arr_int: Sequence[int]
v_arr_str: Sequence[str]
v_map_str_int: Mapping[str, int]
v_map_str_arr_int: Mapping[str, Sequence[int]]
v_variant: str | Sequence[int] | Mapping[str, int]
v_opt_arr_variant: Sequence[int | str] | None
if TYPE_CHECKING:
def add_int(self, _1: int, /) -> int: ...
def append_int(self, _1: Sequence[int], _2: int, /) -> Sequence[int]: ...
def maybe_concat(self, _1: str | None, _2: str | None, /) -> str | None: ...
def merge_map(self, _1: Mapping[str, Sequence[int]], _2: Mapping[str, Sequence[int]], /) -> Mapping[str, Sequence[int]]: ...
@staticmethod
def make_with(_0: int, _1: float, _2: str, /) -> _SchemaAllTypes: ...
# fmt: on
# tvm-ffi-stubgen(end)
def create_object(type_key: str, **kwargs: Any) -> Object:
"""Make an object by reflection.
Parameters
----------
type_key
The type key of the object.
kwargs
The keyword arguments to the object.
Returns
-------
obj
The created object.
Note
----
This function is only used for testing purposes and should
not be used in other cases.
"""
args = [type_key]
for k, v in kwargs.items():
args.append(k)
args.append(v)
return _ffi_api.MakeObjectFromPackedArgs(*args)
def make_unregistered_object() -> Object:
"""Return an object whose type is not registered on the Python side."""
return get_global_func("testing.make_unregistered_object")()
def add_one(x: int) -> int:
"""Add one to the input integer."""
return get_global_func("testing.add_one")(x)
@c_class("testing.TestCompare")
class TestCompare(Object):
"""Test object with Compare(false) on ignored_field."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestCompare
# fmt: off
key: int
name: str
ignored_field: int
if TYPE_CHECKING:
def __init__(self, key: int, name: str, ignored_field: int) -> None: ...
def __ffi_init__(self, _0: int, _1: str, _2: int, /) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestHash")
class TestHash(Object):
"""Test object with Hash(false) on hash_ignored."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestHash
# fmt: off
key: int
name: str
hash_ignored: int
if TYPE_CHECKING:
def __init__(self, key: int, name: str, hash_ignored: int) -> None: ...
def __ffi_init__(self, _0: int, _1: str, _2: int, /) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCustomHash")
class TestCustomHash(Object):
"""Test object with custom __ffi_hash__ hook (hashes only key)."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestCustomHash
# fmt: off
key: int
label: str
if TYPE_CHECKING:
def __init__(self, key: int, label: str) -> None: ...
def __ffi_init__(self, _0: int, _1: str, /) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCustomCompare")
class TestCustomCompare(Object):
"""Test object with custom __ffi_eq__/__ffi_compare__ hooks (compares only key)."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestCustomCompare
# fmt: off
key: int
label: str
if TYPE_CHECKING:
def __init__(self, key: int, label: str) -> None: ...
def __ffi_init__(self, _0: int, _1: str, /) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestEqWithoutHash")
class TestEqWithoutHash(Object):
"""Test object with __ffi_eq__ but no __ffi_hash__ (exercises hash guard)."""
__test__ = False
# tvm-ffi-stubgen(begin): object/testing.TestEqWithoutHash
# fmt: off
key: int
label: str
if TYPE_CHECKING:
def __init__(self, key: int, label: str) -> None: ...
def __ffi_init__(self, _0: int, _1: str, /) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxClassBase")
class _TestCxxClassBase(Object):
# tvm-ffi-stubgen(ty-map): testing.TestCxxClassBase -> testing._TestCxxClassBase
# tvm-ffi-stubgen(begin): object/testing.TestCxxClassBase
# fmt: off
v_i64: int
v_i32: int
if TYPE_CHECKING:
def __init__(self, v_i64: int, v_i32: int) -> None: ...
def __ffi_init__(self, v_i64: int, v_i32: int) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
not_field_1 = 1
not_field_2: ClassVar[int] = 2
def __init__(self, v_i64: int, v_i32: int) -> None:
ti = getattr(type(self), "__tvm_ffi_type_info__")
ffi_init = tvm_ffi_core._lookup_type_attr(ti.type_index, "__ffi_init__")
self.__init_handle_by_constructor__(ffi_init, v_i64 + 1, v_i32 + 2)
@c_class("testing.TestCxxClassDerived", eq=True, order=True, unsafe_hash=True)
class _TestCxxClassDerived(_TestCxxClassBase):
# tvm-ffi-stubgen(ty-map): testing.TestCxxClassDerived -> testing._TestCxxClassDerived
# tvm-ffi-stubgen(begin): object/testing.TestCxxClassDerived
# fmt: off
v_f64: float
v_f32: float
if TYPE_CHECKING:
def __init__(self, v_i64: int, v_i32: int, v_f64: float, v_f32: float = ...) -> None: ...
def __ffi_init__(self, v_i64: int, v_i32: int, v_f64: float, v_f32: float = ...) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxClassDerivedDerived")
class _TestCxxClassDerivedDerived(_TestCxxClassDerived):
# tvm-ffi-stubgen(ty-map): testing.TestCxxClassDerivedDerived -> testing._TestCxxClassDerivedDerived
# tvm-ffi-stubgen(begin): object/testing.TestCxxClassDerivedDerived
# fmt: off
v_str: str
v_bool: bool
if TYPE_CHECKING:
def __init__(self, v_i64: int, v_i32: int, v_f64: float, v_bool: bool, v_f32: float = ..., v_str: str = ...) -> None: ...
def __ffi_init__(self, v_i64: int, v_i32: int, v_f64: float, v_bool: bool, v_f32: float = ..., v_str: str = ...) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxInitSubset")
class _TestCxxInitSubset(Object):
# tvm-ffi-stubgen(ty-map): testing.TestCxxInitSubset -> testing._TestCxxInitSubset
# tvm-ffi-stubgen(begin): object/testing.TestCxxInitSubset
# fmt: off
required_field: int
optional_field: int
note: str
if TYPE_CHECKING:
def __init__(self, required_field: int) -> None: ...
def __ffi_init__(self, required_field: int) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxKwOnly")
class _TestCxxKwOnly(Object):
# tvm-ffi-stubgen(ty-map): testing.TestCxxKwOnly -> testing._TestCxxKwOnly
# tvm-ffi-stubgen(begin): object/testing.TestCxxKwOnly
# fmt: off
x: int
y: int
z: int
w: int
if TYPE_CHECKING:
def __init__(self, *, x: int, y: int, z: int, w: int = ...) -> None: ...
def __ffi_init__(self, *, x: int, y: int, z: int, w: int = ...) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxAutoInit")
class _TestCxxAutoInit(Object):
"""Test object with init(false) on b and KwOnly(true) on c."""
__test__ = False
# tvm-ffi-stubgen(ty-map): testing.TestCxxAutoInit -> testing._TestCxxAutoInit
# tvm-ffi-stubgen(begin): object/testing.TestCxxAutoInit
# fmt: off
a: int
b: int
c: int
d: int
if TYPE_CHECKING:
def __init__(self, a: int, d: int = ..., *, c: int) -> None: ...
def __ffi_init__(self, a: int, d: int = ..., *, c: int) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxAutoInitSimple")
class _TestCxxAutoInitSimple(Object):
"""Test object with all fields positional (no init/KwOnly traits)."""
__test__ = False
# tvm-ffi-stubgen(ty-map): testing.TestCxxAutoInitSimple -> testing._TestCxxAutoInitSimple
# tvm-ffi-stubgen(begin): object/testing.TestCxxAutoInitSimple
# fmt: off
x: int
y: int
if TYPE_CHECKING:
def __init__(self, x: int, y: int) -> None: ...
def __ffi_init__(self, x: int, y: int) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxAutoInitAllInitOff")
class _TestCxxAutoInitAllInitOff(Object):
"""Test object with all fields excluded from auto-init (init(false))."""
__test__ = False
# tvm-ffi-stubgen(ty-map): testing.TestCxxAutoInitAllInitOff -> testing._TestCxxAutoInitAllInitOff
# tvm-ffi-stubgen(begin): object/testing.TestCxxAutoInitAllInitOff
# fmt: off
x: int
y: int
z: int
if TYPE_CHECKING:
def __init__(self) -> None: ...
def __ffi_init__(self) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxAutoInitKwOnlyDefaults")
class _TestCxxAutoInitKwOnlyDefaults(Object):
"""Test object with mixed positional/kw-only/default/init=False fields."""
__test__ = False
# tvm-ffi-stubgen(ty-map): testing.TestCxxAutoInitKwOnlyDefaults -> testing._TestCxxAutoInitKwOnlyDefaults
# tvm-ffi-stubgen(begin): object/testing.TestCxxAutoInitKwOnlyDefaults
# fmt: off
p_required: int
p_default: int
k_required: int
k_default: int
hidden: int
if TYPE_CHECKING:
def __init__(self, p_required: int, p_default: int = ..., *, k_required: int, k_default: int = ...) -> None: ...
def __ffi_init__(self, p_required: int, p_default: int = ..., *, k_required: int, k_default: int = ...) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxNoAutoInit", init=False)
class _TestCxxNoAutoInit(Object):
"""Test object with init(false) at class level — no __ffi_init__ generated."""
__test__ = False
# tvm-ffi-stubgen(ty-map): testing.TestCxxNoAutoInit -> testing._TestCxxNoAutoInit
# tvm-ffi-stubgen(begin): object/testing.TestCxxNoAutoInit
# fmt: off
x: int
y: int
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxAutoInitParent")
class _TestCxxAutoInitParent(Object):
"""Parent object for inheritance auto-init tests."""
__test__ = False
# tvm-ffi-stubgen(ty-map): testing.TestCxxAutoInitParent -> testing._TestCxxAutoInitParent
# tvm-ffi-stubgen(begin): object/testing.TestCxxAutoInitParent
# fmt: off
parent_required: int
parent_default: int
if TYPE_CHECKING:
def __init__(self, parent_required: int, parent_default: int = ...) -> None: ...
def __ffi_init__(self, parent_required: int, parent_default: int = ...) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)
@c_class("testing.TestCxxAutoInitChild")
class _TestCxxAutoInitChild(_TestCxxAutoInitParent):
"""Child object for inheritance auto-init tests."""
__test__ = False
# tvm-ffi-stubgen(ty-map): testing.TestCxxAutoInitChild -> testing._TestCxxAutoInitChild
# tvm-ffi-stubgen(begin): object/testing.TestCxxAutoInitChild
# fmt: off
child_required: int
child_kw_only: int
if TYPE_CHECKING:
def __init__(self, parent_required: int, child_required: int, parent_default: int = ..., *, child_kw_only: int) -> None: ...
def __ffi_init__(self, parent_required: int, child_required: int, parent_default: int = ..., *, child_kw_only: int) -> None: ... # ty: ignore[invalid-method-override]
# fmt: on
# tvm-ffi-stubgen(end)