diff --git a/stubs/WTForms/@tests/test_cases/check_form.py b/stubs/WTForms/@tests/test_cases/check_form.py new file mode 100644 index 000000000..250e400a1 --- /dev/null +++ b/stubs/WTForms/@tests/test_cases/check_form.py @@ -0,0 +1,16 @@ +from __future__ import annotations + +from typing_extensions import assert_type + +from wtforms import Form, StringField +from wtforms.fields.core import UnboundField + + +class MyForm(Form): + name = StringField() + + +form = MyForm() +assert_type(form, MyForm) +assert_type(form.name, StringField) +assert_type(MyForm.name, UnboundField[StringField]) diff --git a/stubs/WTForms/wtforms/form.pyi b/stubs/WTForms/wtforms/form.pyi index e18306611..1705e5420 100644 --- a/stubs/WTForms/wtforms/form.pyi +++ b/stubs/WTForms/wtforms/form.pyi @@ -1,11 +1,12 @@ from _typeshed import SupportsItems from collections.abc import Iterable, Iterator, Mapping, Sequence -from typing import Any, ClassVar, Protocol, overload +from typing import Any, ClassVar, Protocol, TypeVar, overload from typing_extensions import TypeAlias from wtforms.fields.core import Field, UnboundField from wtforms.meta import DefaultMeta, _MultiDictLike +_T = TypeVar("_T") _FormErrors: TypeAlias = dict[str | None, Sequence[str] | _FormErrors] # _unbound_fields will always be a list on an instance, but on a @@ -55,7 +56,7 @@ class BaseForm: class FormMeta(type): def __init__(cls, name: str, bases: Sequence[type[object]], attrs: Mapping[str, Any]) -> None: ... - def __call__(cls, *args: Any, **kwargs: Any) -> Any: ... + def __call__(cls: type[_T], *args: Any, **kwargs: Any) -> _T: ... def __setattr__(cls, name: str, value: object) -> None: ... def __delattr__(cls, name: str) -> None: ...