diff --git a/stubs/WTForms/@tests/test_cases/check_choices.py b/stubs/WTForms/@tests/test_cases/check_choices.py new file mode 100644 index 000000000..41204023a --- /dev/null +++ b/stubs/WTForms/@tests/test_cases/check_choices.py @@ -0,0 +1,67 @@ +from __future__ import annotations + +from wtforms import SelectField + +# any way we can specify the choices inline with a literal should work + +# tuple of tuples +SelectField(choices=(("", ""),)) +SelectField(choices=((1, "1"),)) +SelectField(choices=(("", "", {}),)) +SelectField(choices=((True, "t", {}),)) +SelectField(choices=((True, "t"), (False, "f", {}))) + +# list of tuples +SelectField(choices=[("", "")]) +SelectField(choices=[(1, "1")]) +SelectField(choices=[("", "", {})]) +SelectField(choices=[(True, "t", {})]) +SelectField(choices=[(True, "t"), (False, "f", {})]) + +# dict of tuple of tuples +SelectField(choices={"a": (("", ""),)}) +SelectField(choices={"a": ((1, "1"),)}) +SelectField(choices={"a": (("", "", {}),)}) +SelectField(choices={"a": ((True, "t", {}),)}) +SelectField(choices={"a": ((True, "t"), (False, "f", {}))}) +SelectField(choices={"a": ((True, "", {}),), "b": ((False, "f"),)}) + +# dict of list of tuples +SelectField(choices={"a": [("", "")]}) +SelectField(choices={"a": [(1, "1")]}) +SelectField(choices={"a": [("", "", {})]}) +SelectField(choices={"a": [(True, "t", {})]}) +SelectField(choices={"a": [(True, "t"), (False, "f", {})]}) +SelectField(choices={"a": [(True, "", {})], "b": [(False, "f")]}) + +# the same should be true for lambdas + +# tuple of tuples +SelectField(choices=lambda: (("", ""),)) +SelectField(choices=lambda: ((1, "1"),)) +SelectField(choices=lambda: (("", "", {}),)) +SelectField(choices=lambda: ((True, "t", {}),)) +SelectField(choices=lambda: ((True, "t"), (False, "f", {}))) + +# list of tuples +SelectField(choices=lambda: [("", "")]) +SelectField(choices=lambda: [(1, "1")]) +SelectField(choices=lambda: [("", "", {})]) +SelectField(choices=lambda: [(True, "t", {})]) +SelectField(choices=lambda: [(True, "t"), (False, "f", {})]) + +# dict of tuple of tuples +SelectField(choices=lambda: {"a": (("", ""),)}) +SelectField(choices=lambda: {"a": ((1, "1"),)}) +SelectField(choices=lambda: {"a": (("", "", {}),)}) +SelectField(choices=lambda: {"a": ((True, "t", {}),)}) +SelectField(choices=lambda: {"a": ((True, "t"), (False, "f", {}))}) +SelectField(choices=lambda: {"a": ((True, "", {}),), "b": ((False, "f"),)}) + +# dict of list of tuples +SelectField(choices=lambda: {"a": [("", "")]}) +SelectField(choices=lambda: {"a": [(1, "1")]}) +SelectField(choices=lambda: {"a": [("", "", {})]}) +SelectField(choices=lambda: {"a": [(True, "t", {})]}) +SelectField(choices=lambda: {"a": [(True, "t"), (False, "f", {})]}) +SelectField(choices=lambda: {"a": [(True, "", {})], "b": [(False, "f")]}) diff --git a/stubs/WTForms/METADATA.toml b/stubs/WTForms/METADATA.toml index 0a1f052cb..d9080fa07 100644 --- a/stubs/WTForms/METADATA.toml +++ b/stubs/WTForms/METADATA.toml @@ -1,3 +1,3 @@ -version = "3.0.*" +version = "3.1.*" upstream_repository = "https://github.com/wtforms/wtforms" requires = ["MarkupSafe"] diff --git a/stubs/WTForms/wtforms/fields/choices.pyi b/stubs/WTForms/wtforms/fields/choices.pyi index f5c076c49..5a2eff87a 100644 --- a/stubs/WTForms/wtforms/fields/choices.pyi +++ b/stubs/WTForms/wtforms/fields/choices.pyi @@ -7,9 +7,10 @@ from wtforms.form import BaseForm from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext # technically this allows a list, but we're more strict for type safety -_Choice: TypeAlias = tuple[Any, str] -_GroupedChoices: TypeAlias = dict[str, Iterable[_Choice]] -_FullChoice: TypeAlias = tuple[Any, str, bool] # value, label, selected +_Choice: TypeAlias = tuple[Any, str] | tuple[Any, str, dict[str, Any]] +# it's too difficult to get type safety here due to to nested partially invariant collections +_GroupedChoices: TypeAlias = dict[str, Any] # Any should be Collection[_Choice] +_FullChoice: TypeAlias = tuple[Any, str, bool, dict[str, Any]] # value, label, selected, render_kw _FullGroupedChoices: TypeAlias = tuple[str, Iterable[_FullChoice]] _Option: TypeAlias = SelectFieldBase._Option @@ -50,7 +51,7 @@ class SelectField(SelectFieldBase): label: str | None = None, validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, coerce: Callable[[Any], Any] = ..., - choices: Iterable[_Choice] | _GroupedChoices | None = None, + choices: Iterable[_Choice] | _GroupedChoices | Callable[[], Iterable[_Choice] | _GroupedChoices] | None = None, validate_choice: bool = True, *, filters: Sequence[_Filter] = (), diff --git a/stubs/WTForms/wtforms/fields/datetime.pyi b/stubs/WTForms/wtforms/fields/datetime.pyi index 58d9135cd..4b181bc15 100644 --- a/stubs/WTForms/wtforms/fields/datetime.pyi +++ b/stubs/WTForms/wtforms/fields/datetime.pyi @@ -95,6 +95,26 @@ class MonthField(DateField): _meta: DefaultMeta | None = None, ) -> None: ... +class WeekField(DateField): + def __init__( + self, + label: str | None = None, + validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None, + format: str | list[str] = "%Y-W%W", # only difference is the default value + *, + filters: Sequence[_Filter] = (), + description: str = "", + id: str | None = None, + default: time | Callable[[], time] | None = None, + widget: _Widget[Self] | None = None, + render_kw: dict[str, Any] | None = None, + name: str | None = None, + _form: BaseForm | None = None, + _prefix: str = "", + _translations: _SupportsGettextAndNgettext | None = None, + _meta: DefaultMeta | None = None, + ) -> None: ... + class DateTimeLocalField(DateTimeField): def __init__( self, diff --git a/stubs/WTForms/wtforms/fields/simple.pyi b/stubs/WTForms/wtforms/fields/simple.pyi index dce59077c..0fa58d5fe 100644 --- a/stubs/WTForms/wtforms/fields/simple.pyi +++ b/stubs/WTForms/wtforms/fields/simple.pyi @@ -62,3 +62,4 @@ class SearchField(StringField): ... class TelField(StringField): ... class URLField(StringField): ... class EmailField(StringField): ... +class ColorField(StringField): ... diff --git a/stubs/WTForms/wtforms/validators.pyi b/stubs/WTForms/wtforms/validators.pyi index 9f71afd4d..e6d22833c 100644 --- a/stubs/WTForms/wtforms/validators.pyi +++ b/stubs/WTForms/wtforms/validators.pyi @@ -99,7 +99,7 @@ class MacAddress(Regexp): class URL(Regexp): validate_hostname: HostnameValidation - def __init__(self, require_tld: bool = True, message: str | None = None) -> None: ... + def __init__(self, require_tld: bool = True, allow_ip: bool = True, message: str | None = None) -> None: ... def __call__(self, form: BaseForm, field: StringField) -> None: ... # type: ignore[override] class UUID: @@ -143,6 +143,12 @@ class HostnameValidation: def __init__(self, require_tld: bool = True, allow_ip: bool = False) -> None: ... def __call__(self, hostname: str) -> bool: ... +class ReadOnly: + def __call__(self, form: BaseForm, field: Field) -> None: ... + +class Disabled: + def __call__(self, form: BaseForm, field: Field) -> None: ... + email = Email equal_to = EqualTo ip_address = IPAddress @@ -156,3 +162,5 @@ regexp = Regexp url = URL any_of = AnyOf none_of = NoneOf +readonly = ReadOnly +disabled = Disabled