mirror of
https://github.com/davidhalter/typeshed.git
synced 2025-12-09 21:46:42 +08:00
Add stubs for WTForms (#10557)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
41
stubs/WTForms/@tests/stubtest_allowlist.txt
Normal file
41
stubs/WTForms/@tests/stubtest_allowlist.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
# Error: is not present at runtime
|
||||
# =============================
|
||||
# This is hack to get around Field.__new__ not being able to return
|
||||
# UnboundField
|
||||
wtforms.Field.__get__
|
||||
wtforms.fields.Field.__get__
|
||||
wtforms.fields.core.Field.__get__
|
||||
# Since DefaultMeta can contain arbitrary values we added __getattr__
|
||||
# to let mypy know that arbitrary attribute access is possible
|
||||
wtforms.meta.DefaultMeta.__getattr__
|
||||
|
||||
# Error: variable differs from runtime
|
||||
# ======================
|
||||
# _unbound_fields has some weird semantics: due to the metaclass it
|
||||
# will be None until the form class has been instantiated at least
|
||||
# once and then will stick around until someone adds a new field
|
||||
# to the class, which clears it back to None. Which means on instances
|
||||
# it will always be there and on the class it depends, so maybe this
|
||||
# should use a dummy descriptor? For now we just pretend it's set.
|
||||
# The behavior is documented in FormMeta, so I think it's fine.
|
||||
wtforms.Form._unbound_fields
|
||||
wtforms.form.Form._unbound_fields
|
||||
|
||||
# widget is both used as a ClassVar and instance variable and does
|
||||
# not necessarily reflect an upper bound on Widget, so we always use
|
||||
# our Widget Protocol definition that's contravariant on Self
|
||||
wtforms.Field.widget
|
||||
wtforms.FormField.widget
|
||||
wtforms.SelectField.widget
|
||||
wtforms.SelectMultipleField.widget
|
||||
wtforms.TextAreaField.widget
|
||||
wtforms.fields.Field.widget
|
||||
wtforms.fields.FormField.widget
|
||||
wtforms.fields.SelectField.widget
|
||||
wtforms.fields.SelectMultipleField.widget
|
||||
wtforms.fields.TextAreaField.widget
|
||||
wtforms.fields.choices.SelectField.widget
|
||||
wtforms.fields.choices.SelectMultipleField.widget
|
||||
wtforms.fields.core.Field.widget
|
||||
wtforms.fields.form.FormField.widget
|
||||
wtforms.fields.simple.TextAreaField.widget
|
||||
49
stubs/WTForms/@tests/test_cases/check_filters.py
Normal file
49
stubs/WTForms/@tests/test_cases/check_filters.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from wtforms import Field, Form
|
||||
|
||||
|
||||
class Filter1:
|
||||
def __call__(self, value: object) -> None:
|
||||
...
|
||||
|
||||
|
||||
class Filter2:
|
||||
def __call__(self, input: None) -> None:
|
||||
...
|
||||
|
||||
|
||||
def not_a_filter(a: object, b: object) -> None:
|
||||
...
|
||||
|
||||
|
||||
def also_not_a_filter() -> None:
|
||||
...
|
||||
|
||||
|
||||
# we should accept any mapping of sequences, we can't really validate
|
||||
# the filter functions when it's this nested
|
||||
form = Form()
|
||||
form.process(extra_filters={"foo": (str.upper, str.strip, int), "bar": (Filter1(), Filter2())})
|
||||
form.process(extra_filters={"foo": [str.upper, str.strip, int], "bar": [Filter1(), Filter2()]})
|
||||
|
||||
# regardless of how we pass the filters into Field it should work
|
||||
field = Field(filters=(str.upper, str.lower, int))
|
||||
Field(filters=(Filter1(), Filter2()))
|
||||
Field(filters=[str.upper, str.lower, int])
|
||||
Field(filters=[Filter1(), Filter2()])
|
||||
field.process(None, extra_filters=(str.upper, str.lower, int))
|
||||
field.process(None, extra_filters=(Filter1(), Filter2()))
|
||||
field.process(None, extra_filters=[str.upper, str.lower, int])
|
||||
field.process(None, extra_filters=[Filter1(), Filter2()])
|
||||
|
||||
# but if we pass in some callables with an incompatible param spec
|
||||
# then we should get type errors
|
||||
Field(filters=(str.upper, str.lower, int, not_a_filter)) # type:ignore
|
||||
Field(filters=(Filter1(), Filter2(), also_not_a_filter)) # type:ignore
|
||||
Field(filters=[str.upper, str.lower, int, also_not_a_filter]) # type:ignore
|
||||
Field(filters=[Filter1(), Filter2(), not_a_filter]) # type:ignore
|
||||
field.process(None, extra_filters=(str.upper, str.lower, int, not_a_filter)) # type:ignore
|
||||
field.process(None, extra_filters=(Filter1(), Filter2(), also_not_a_filter)) # type:ignore
|
||||
field.process(None, extra_filters=[str.upper, str.lower, int, also_not_a_filter]) # type:ignore
|
||||
field.process(None, extra_filters=[Filter1(), Filter2(), not_a_filter]) # type:ignore
|
||||
33
stubs/WTForms/@tests/test_cases/check_validators.py
Normal file
33
stubs/WTForms/@tests/test_cases/check_validators.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from wtforms import DateField, Field, Form, StringField
|
||||
from wtforms.validators import Email, Optional
|
||||
|
||||
form = Form()
|
||||
# on form we should accept any validator mapping
|
||||
form.validate({"field": (Optional(),), "string_field": (Optional(), Email())})
|
||||
form.validate({"field": [Optional()], "string_field": [Optional(), Email()]})
|
||||
|
||||
# both StringField validators and Field validators should be valid
|
||||
# as inputs on a StringField
|
||||
string_field = StringField(validators=(Optional(), Email()))
|
||||
string_field.validate(form, (Optional(), Email()))
|
||||
|
||||
# but not on Field
|
||||
field = Field(validators=(Optional(), Email())) # type:ignore
|
||||
field.validate(form, (Optional(), Email())) # type:ignore
|
||||
|
||||
# unless we only pass the Field validator
|
||||
Field(validators=(Optional(),))
|
||||
field.validate(form, (Optional(),))
|
||||
|
||||
# DateField should accept Field validators but not StringField validators
|
||||
date_field = DateField(validators=(Optional(), Email())) # type:ignore
|
||||
date_field.validate(form, (Optional(), Email())) # type:ignore
|
||||
DateField(validators=(Optional(),))
|
||||
|
||||
# for lists we can't be as strict so we won't get type errors here
|
||||
Field(validators=[Optional(), Email()])
|
||||
field.validate(form, [Optional(), Email()])
|
||||
DateField(validators=[Optional(), Email()])
|
||||
date_field.validate(form, [Optional(), Email()])
|
||||
26
stubs/WTForms/@tests/test_cases/check_widgets.py
Normal file
26
stubs/WTForms/@tests/test_cases/check_widgets.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from wtforms import Field, FieldList, Form, FormField, SelectField, StringField
|
||||
from wtforms.widgets import Input, ListWidget, Option, Select, TableWidget, TextArea
|
||||
|
||||
# more specific widgets should only work on more specific fields
|
||||
Field(widget=Input())
|
||||
Field(widget=TextArea()) # type:ignore
|
||||
Field(widget=Select()) # type:ignore
|
||||
|
||||
# less specific widgets are fine, even if they're often not what you want
|
||||
StringField(widget=Input())
|
||||
StringField(widget=TextArea())
|
||||
|
||||
SelectField(widget=Input(), option_widget=Input())
|
||||
SelectField(widget=Select(), option_widget=Option())
|
||||
# a more specific type other than Option widget is not allowed
|
||||
SelectField(widget=Select(), option_widget=TextArea()) # type:ignore
|
||||
|
||||
# we should be able to pass Field() even though it wants an unbound_field
|
||||
# this gets around __new__ not working in type checking
|
||||
FieldList(Field(), widget=Input())
|
||||
FieldList(Field(), widget=ListWidget())
|
||||
|
||||
FormField(Form, widget=Input())
|
||||
FormField(Form, widget=TableWidget())
|
||||
3
stubs/WTForms/METADATA.toml
Normal file
3
stubs/WTForms/METADATA.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
version = "3.0.*"
|
||||
upstream_repository = "https://github.com/wtforms/wtforms"
|
||||
requires = ["MarkupSafe"]
|
||||
4
stubs/WTForms/wtforms/__init__.pyi
Normal file
4
stubs/WTForms/wtforms/__init__.pyi
Normal file
@@ -0,0 +1,4 @@
|
||||
from wtforms import validators as validators, widgets as widgets
|
||||
from wtforms.fields import *
|
||||
from wtforms.form import Form as Form
|
||||
from wtforms.validators import ValidationError as ValidationError
|
||||
0
stubs/WTForms/wtforms/csrf/__init__.pyi
Normal file
0
stubs/WTForms/wtforms/csrf/__init__.pyi
Normal file
39
stubs/WTForms/wtforms/csrf/core.pyi
Normal file
39
stubs/WTForms/wtforms/csrf/core.pyi
Normal file
@@ -0,0 +1,39 @@
|
||||
from abc import abstractmethod
|
||||
from collections.abc import Callable, Sequence
|
||||
from typing import Any
|
||||
from typing_extensions import Self
|
||||
|
||||
from wtforms.fields import HiddenField
|
||||
from wtforms.fields.core import UnboundField, _Filter, _FormT, _Validator, _Widget
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext
|
||||
|
||||
class CSRFTokenField(HiddenField):
|
||||
current_token: str | None
|
||||
csrf_impl: CSRF
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: str | Callable[[], str] | 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,
|
||||
*,
|
||||
csrf_impl: CSRF,
|
||||
) -> None: ...
|
||||
|
||||
class CSRF:
|
||||
field_class: type[CSRFTokenField]
|
||||
def setup_form(self, form: BaseForm) -> list[tuple[str, UnboundField[Any]]]: ...
|
||||
@abstractmethod
|
||||
def generate_csrf_token(self, csrf_token_field: CSRFTokenField) -> str: ...
|
||||
@abstractmethod
|
||||
def validate_csrf_token(self, form: BaseForm, field: CSRFTokenField) -> None: ...
|
||||
18
stubs/WTForms/wtforms/csrf/session.pyi
Normal file
18
stubs/WTForms/wtforms/csrf/session.pyi
Normal file
@@ -0,0 +1,18 @@
|
||||
from _typeshed import SupportsItemAccess
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any
|
||||
|
||||
from wtforms.csrf.core import CSRF, CSRFTokenField
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta
|
||||
|
||||
class SessionCSRF(CSRF):
|
||||
TIME_FORMAT: str
|
||||
form_meta: DefaultMeta
|
||||
def generate_csrf_token(self, csrf_token_field: CSRFTokenField) -> str: ...
|
||||
def validate_csrf_token(self, form: BaseForm, field: CSRFTokenField) -> None: ...
|
||||
def now(self) -> datetime: ...
|
||||
@property
|
||||
def time_limit(self) -> timedelta: ...
|
||||
@property
|
||||
def session(self) -> SupportsItemAccess[str, Any]: ...
|
||||
8
stubs/WTForms/wtforms/fields/__init__.pyi
Normal file
8
stubs/WTForms/wtforms/fields/__init__.pyi
Normal file
@@ -0,0 +1,8 @@
|
||||
from wtforms.fields.choices import *
|
||||
from wtforms.fields.choices import SelectFieldBase as SelectFieldBase
|
||||
from wtforms.fields.core import Field as Field, Flags as Flags, Label as Label
|
||||
from wtforms.fields.datetime import *
|
||||
from wtforms.fields.form import *
|
||||
from wtforms.fields.list import *
|
||||
from wtforms.fields.numeric import *
|
||||
from wtforms.fields.simple import *
|
||||
76
stubs/WTForms/wtforms/fields/choices.pyi
Normal file
76
stubs/WTForms/wtforms/fields/choices.pyi
Normal file
@@ -0,0 +1,76 @@
|
||||
from collections.abc import Callable, Iterable, Iterator, Sequence
|
||||
from typing import Any
|
||||
from typing_extensions import Self, TypeAlias
|
||||
|
||||
from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget
|
||||
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
|
||||
_FullGroupedChoices: TypeAlias = tuple[str, Iterable[_FullChoice]]
|
||||
_Option: TypeAlias = SelectFieldBase._Option
|
||||
|
||||
class SelectFieldBase(Field):
|
||||
option_widget: _Widget[_Option]
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
option_widget: _Widget[_Option] | None = None,
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: object | 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: ...
|
||||
def iter_choices(self) -> Iterator[_FullChoice]: ...
|
||||
def has_groups(self) -> bool: ...
|
||||
def iter_groups(self) -> Iterator[_FullGroupedChoices]: ...
|
||||
def __iter__(self) -> Iterator[_Option]: ...
|
||||
|
||||
class _Option(Field):
|
||||
checked: bool
|
||||
|
||||
class SelectField(SelectFieldBase):
|
||||
coerce: Callable[[Any], Any]
|
||||
choices: list[_Choice] | _GroupedChoices
|
||||
validate_choice: bool
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
coerce: Callable[[Any], Any] = ...,
|
||||
choices: Iterable[_Choice] | _GroupedChoices | None = None,
|
||||
validate_choice: bool = True,
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: object | None = None,
|
||||
widget: _Widget[Self] | None = None,
|
||||
option_widget: _Widget[_Option] | 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: ...
|
||||
def iter_choices(self) -> Iterator[_FullChoice]: ...
|
||||
def has_groups(self) -> bool: ...
|
||||
def iter_groups(self) -> Iterator[_FullGroupedChoices]: ...
|
||||
|
||||
class SelectMultipleField(SelectField):
|
||||
data: list[Any] | None
|
||||
|
||||
class RadioField(SelectField): ...
|
||||
132
stubs/WTForms/wtforms/fields/core.pyi
Normal file
132
stubs/WTForms/wtforms/fields/core.pyi
Normal file
@@ -0,0 +1,132 @@
|
||||
from builtins import type as _type # type is being shadowed in Field
|
||||
from collections.abc import Callable, Iterable, Sequence
|
||||
from typing import Any, Generic, Protocol, TypeVar, overload
|
||||
from typing_extensions import Self, TypeAlias
|
||||
|
||||
from markupsafe import Markup
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta, _MultiDictLikeWithGetlist, _SupportsGettextAndNgettext
|
||||
|
||||
_FormT = TypeVar("_FormT", bound=BaseForm)
|
||||
_FieldT = TypeVar("_FieldT", bound=Field)
|
||||
_FormT_contra = TypeVar("_FormT_contra", bound=BaseForm, contravariant=True)
|
||||
_FieldT_contra = TypeVar("_FieldT_contra", bound=Field, contravariant=True)
|
||||
# It would be nice to annotate this as invariant, i.e. input type and output type
|
||||
# needs to be the same, but it will probably be too annoying to use, for now we
|
||||
# trust, that people won't use it to change the type of data in a field...
|
||||
_Filter: TypeAlias = Callable[[Any], Any]
|
||||
|
||||
class _Validator(Protocol[_FormT_contra, _FieldT_contra]):
|
||||
def __call__(self, __form: _FormT_contra, __field: _FieldT_contra) -> object: ...
|
||||
|
||||
class _Widget(Protocol[_FieldT_contra]):
|
||||
def __call__(self, field: _FieldT_contra, **kwargs: Any) -> Markup: ...
|
||||
|
||||
class Field:
|
||||
errors: Sequence[str]
|
||||
process_errors: Sequence[str]
|
||||
raw_data: list[Any] | None
|
||||
object_data: Any
|
||||
data: Any
|
||||
validators: Sequence[_Validator[Any, Self]]
|
||||
# even though this could be None on the base class, this should
|
||||
# never actually be None in a real field
|
||||
widget: _Widget[Self]
|
||||
do_not_call_in_templates: bool
|
||||
meta: DefaultMeta
|
||||
default: Any | None
|
||||
description: str
|
||||
render_kw: dict[str, Any]
|
||||
filters: Sequence[_Filter]
|
||||
flags: Flags
|
||||
name: str
|
||||
short_name: str
|
||||
id: str
|
||||
type: str
|
||||
label: Label
|
||||
# technically this can return UnboundField, but that is not allowed
|
||||
# by type checkers, so we use a descriptor hack to get around this
|
||||
# limitation instead
|
||||
def __new__(cls, *args: Any, **kwargs: Any) -> Self: ...
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
# for tuple we can be a bit more type safe and only accept validators
|
||||
# that would work on this or a less specific field, but in general it
|
||||
# would be too annoying to restrict to Sequence[_Validator], since mypy
|
||||
# will infer a list of mixed validators as list[object], since that is
|
||||
# the common base class between all validators
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: object | 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: ...
|
||||
def __html__(self) -> str: ...
|
||||
def __call__(self, **kwargs: object) -> Markup: ...
|
||||
@classmethod
|
||||
def check_validators(cls, validators: Iterable[_Validator[_FormT, Self]] | None) -> None: ...
|
||||
def gettext(self, string: str) -> str: ...
|
||||
def ngettext(self, singular: str, plural: str, n: int) -> str: ...
|
||||
def validate(self, form: BaseForm, extra_validators: tuple[_Validator[_FormT, Self], ...] | list[Any] = ()) -> bool: ...
|
||||
def pre_validate(self, form: BaseForm) -> None: ...
|
||||
def post_validate(self, form: BaseForm, validation_stopped: bool) -> None: ...
|
||||
def process(
|
||||
self, formdata: _MultiDictLikeWithGetlist | None, data: Any = ..., extra_filters: Sequence[_Filter] | None = None
|
||||
) -> None: ...
|
||||
def process_data(self, value: Any) -> None: ...
|
||||
def process_formdata(self, valuelist: list[Any]) -> None: ...
|
||||
def populate_obj(self, obj: object, name: str) -> None: ...
|
||||
|
||||
# this is a workaround for what is essentialy illegal in static type checking
|
||||
# Field.__new__ would return an UnboundField, unless the _form parameter is
|
||||
# specified. We can't really work around it by making UnboundField a subclass
|
||||
# of Field, since all subclasses of Field still need to return an UnboundField
|
||||
# and we can't expect third parties to add a __new__ method to every field
|
||||
# they define...
|
||||
# This workaround only works for Form, not BaseForm, but we take what we can get
|
||||
# BaseForm shouldn't really be used anyways
|
||||
@overload
|
||||
def __get__(self, obj: None, owner: _type[object] | None = None) -> UnboundField[Self]: ...
|
||||
@overload
|
||||
def __get__(self, obj: object, owner: _type[object] | None = None) -> Self: ...
|
||||
|
||||
class UnboundField(Generic[_FieldT]):
|
||||
creation_counter: int
|
||||
field_class: type[_FieldT]
|
||||
name: str | None
|
||||
args: tuple[Any, ...]
|
||||
kwargs: dict[str, Any]
|
||||
def __init__(self, field_class: type[_FieldT], *args: object, name: str | None = None, **kwargs: object) -> None: ...
|
||||
def bind(
|
||||
self,
|
||||
form: BaseForm,
|
||||
name: str,
|
||||
prefix: str = "",
|
||||
translations: _SupportsGettextAndNgettext | None = None,
|
||||
**kwargs: object,
|
||||
) -> _FieldT: ...
|
||||
|
||||
class Flags:
|
||||
# the API for this is a bit loosey goosey, the intention probably
|
||||
# was that the values should always be boolean, but __contains__
|
||||
# just returns the same thing as __getattr__ and in the widgets
|
||||
# there are fields that could accept numeric values from Flags
|
||||
def __getattr__(self, name: str) -> Any | None: ...
|
||||
def __setattr__(self, name: str, value: object) -> None: ...
|
||||
def __delattr__(self, name: str) -> None: ...
|
||||
def __contains__(self, name: str) -> Any | None: ...
|
||||
|
||||
class Label:
|
||||
field_id: str
|
||||
text: str
|
||||
def __init__(self, field_id: str, text: str) -> None: ...
|
||||
def __html__(self) -> str: ...
|
||||
def __call__(self, text: str | None = None, **kwargs: Any) -> Markup: ...
|
||||
116
stubs/WTForms/wtforms/fields/datetime.pyi
Normal file
116
stubs/WTForms/wtforms/fields/datetime.pyi
Normal file
@@ -0,0 +1,116 @@
|
||||
from collections.abc import Callable, Sequence
|
||||
from datetime import date, datetime, time
|
||||
from typing import Any
|
||||
from typing_extensions import Self
|
||||
|
||||
from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext
|
||||
|
||||
class DateTimeField(Field):
|
||||
format: list[str]
|
||||
strptime_format: list[str]
|
||||
data: datetime | None
|
||||
default: datetime | Callable[[], datetime] | None
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
format: str | list[str] = "%Y-%m-%d %H:%M:%S",
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: datetime | Callable[[], datetime] | 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 DateField(DateTimeField):
|
||||
data: date | None # type: ignore[assignment]
|
||||
default: date | Callable[[], date] | None # type: ignore[assignment]
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
format: str | list[str] = "%Y-%m-%d",
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: date | Callable[[], date] | 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 TimeField(DateTimeField):
|
||||
data: time | None # type: ignore[assignment]
|
||||
default: time | Callable[[], time] | None # type: ignore[assignment]
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
format: str | list[str] = "%H:%M",
|
||||
*,
|
||||
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 MonthField(DateField):
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
format: str | list[str] = "%Y-%m",
|
||||
*,
|
||||
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,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
format: str | list[str] = ...,
|
||||
*,
|
||||
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: ...
|
||||
38
stubs/WTForms/wtforms/fields/form.pyi
Normal file
38
stubs/WTForms/wtforms/fields/form.pyi
Normal file
@@ -0,0 +1,38 @@
|
||||
from collections.abc import Iterator, Sequence
|
||||
from typing import Any, Generic, TypeVar
|
||||
|
||||
from wtforms.fields.core import Field, _Widget
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext
|
||||
|
||||
_BoundFormT = TypeVar("_BoundFormT", bound=BaseForm)
|
||||
|
||||
class FormField(Field, Generic[_BoundFormT]):
|
||||
form_class: type[_BoundFormT]
|
||||
form: _BoundFormT
|
||||
separator: str
|
||||
def __init__(
|
||||
self: FormField[_BoundFormT],
|
||||
form_class: type[_BoundFormT],
|
||||
label: str | None = None,
|
||||
validators: None = None,
|
||||
separator: str = "-",
|
||||
*,
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: object | None = None,
|
||||
widget: _Widget[FormField[_BoundFormT]] | 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: ...
|
||||
def __iter__(self) -> Iterator[Field]: ...
|
||||
def __getitem__(self, name: str) -> Field: ...
|
||||
def __getattr__(self, name: str) -> Field: ...
|
||||
@property
|
||||
def data(self) -> dict[str, Any]: ...
|
||||
@property
|
||||
def errors(self) -> dict[str | None, Sequence[str]]: ... # type: ignore[override]
|
||||
44
stubs/WTForms/wtforms/fields/list.pyi
Normal file
44
stubs/WTForms/wtforms/fields/list.pyi
Normal file
@@ -0,0 +1,44 @@
|
||||
from collections.abc import Callable, Iterable, Iterator
|
||||
from typing import Any, Generic, TypeVar
|
||||
|
||||
from wtforms.fields.core import Field, UnboundField, _FormT, _Validator, _Widget
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext
|
||||
|
||||
_BoundFieldT = TypeVar("_BoundFieldT", bound=Field)
|
||||
|
||||
class FieldList(Field, Generic[_BoundFieldT]):
|
||||
unbound_field: UnboundField[_BoundFieldT]
|
||||
min_entries: int
|
||||
max_entries: int | None
|
||||
last_index: int
|
||||
entries: list[_BoundFieldT]
|
||||
object_data: Iterable[Any]
|
||||
def __init__(
|
||||
self: FieldList[_BoundFieldT],
|
||||
# because of our workaround we need to accept Field as well
|
||||
unbound_field: UnboundField[_BoundFieldT] | _BoundFieldT,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, _BoundFieldT], ...] | list[Any] | None = None,
|
||||
min_entries: int = 0,
|
||||
max_entries: int | None = None,
|
||||
separator: str = "-",
|
||||
default: Iterable[Any] | Callable[[], Iterable[Any]] = (),
|
||||
*,
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
widget: _Widget[FieldList[Any]] | 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: ...
|
||||
def append_entry(self, data: Any = ...) -> _BoundFieldT: ...
|
||||
def pop_entry(self) -> _BoundFieldT: ...
|
||||
def __iter__(self) -> Iterator[_BoundFieldT]: ...
|
||||
def __len__(self) -> int: ...
|
||||
def __getitem__(self, index: int) -> _BoundFieldT: ...
|
||||
@property
|
||||
def data(self) -> list[Any]: ...
|
||||
145
stubs/WTForms/wtforms/fields/numeric.pyi
Normal file
145
stubs/WTForms/wtforms/fields/numeric.pyi
Normal file
@@ -0,0 +1,145 @@
|
||||
from collections.abc import Callable, Sequence
|
||||
from decimal import Decimal
|
||||
from typing import Any, overload
|
||||
from typing_extensions import Literal, Self
|
||||
|
||||
from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext
|
||||
from wtforms.utils import UnsetValue
|
||||
|
||||
__all__ = ("IntegerField", "DecimalField", "FloatField", "IntegerRangeField", "DecimalRangeField")
|
||||
|
||||
class LocaleAwareNumberField(Field):
|
||||
use_locale: bool
|
||||
number_format: Any | None
|
||||
locale: str
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
use_locale: bool = False,
|
||||
# this accepts a babel.numbers.NumberPattern, but since it
|
||||
# is an optional dependency we don't want to depend on it
|
||||
# for annotating this one argument
|
||||
number_format: str | Any | None = None,
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: object | 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 IntegerField(Field):
|
||||
data: int | None
|
||||
# technically this is not as strict and will accept anything
|
||||
# that can be passed into int(), but we might as well be
|
||||
default: int | Callable[[], int] | None
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: int | Callable[[], int] | 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 DecimalField(LocaleAwareNumberField):
|
||||
data: Decimal | None
|
||||
# technically this is not as strict and will accept anything
|
||||
# that can be passed into Decimal(), but we might as well be
|
||||
default: Decimal | Callable[[], Decimal] | None
|
||||
places: int | None
|
||||
rounding: str | None
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
*,
|
||||
places: UnsetValue = ...,
|
||||
rounding: None = None,
|
||||
use_locale: Literal[True],
|
||||
# this accepts a babel.numbers.NumberPattern, but since it
|
||||
# is an optional dependency we don't want to depend on it
|
||||
# for annotation this one argument
|
||||
number_format: str | Any | None = None,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: Decimal | Callable[[], Decimal] | 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: ...
|
||||
@overload
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
places: int | UnsetValue | None = ...,
|
||||
rounding: str | None = None,
|
||||
*,
|
||||
use_locale: Literal[False] = False,
|
||||
# this accepts a babel.numbers.NumberPattern, but since it
|
||||
# is an optional dependency we don't want to depend on it
|
||||
# for annotation this one argument
|
||||
number_format: str | Any | None = None,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: Decimal | Callable[[], Decimal] | 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 FloatField(Field):
|
||||
data: float | None
|
||||
# technically this is not as strict and will accept anything
|
||||
# that can be passed into float(), but we might as well be
|
||||
default: float | Callable[[], float] | None
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: float | Callable[[], float] | 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 IntegerRangeField(IntegerField): ...
|
||||
class DecimalRangeField(DecimalField): ...
|
||||
64
stubs/WTForms/wtforms/fields/simple.pyi
Normal file
64
stubs/WTForms/wtforms/fields/simple.pyi
Normal file
@@ -0,0 +1,64 @@
|
||||
from collections.abc import Callable, Collection, Sequence
|
||||
from typing import Any
|
||||
from typing_extensions import Self
|
||||
|
||||
from wtforms.fields.core import Field, _Filter, _FormT, _Validator, _Widget
|
||||
from wtforms.form import BaseForm
|
||||
from wtforms.meta import DefaultMeta, _SupportsGettextAndNgettext
|
||||
|
||||
class BooleanField(Field):
|
||||
data: bool
|
||||
default: bool | Callable[[], bool] | None
|
||||
false_values: Collection[Any]
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
false_values: Collection[Any] | None = None,
|
||||
*,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: bool | Callable[[], bool] | 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 StringField(Field):
|
||||
data: str | None
|
||||
default: str | Callable[[], str] | None
|
||||
def __init__(
|
||||
self,
|
||||
label: str | None = None,
|
||||
validators: tuple[_Validator[_FormT, Self], ...] | list[Any] | None = None,
|
||||
filters: Sequence[_Filter] = (),
|
||||
description: str = "",
|
||||
id: str | None = None,
|
||||
default: str | Callable[[], str] | 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 TextAreaField(StringField): ...
|
||||
class PasswordField(StringField): ...
|
||||
class FileField(Field): ...
|
||||
|
||||
class MultipleFileField(FileField):
|
||||
data: list[Any]
|
||||
|
||||
class HiddenField(StringField): ...
|
||||
class SubmitField(BooleanField): ...
|
||||
class SearchField(StringField): ...
|
||||
class TelField(StringField): ...
|
||||
class URLField(StringField): ...
|
||||
class EmailField(StringField): ...
|
||||
84
stubs/WTForms/wtforms/form.pyi
Normal file
84
stubs/WTForms/wtforms/form.pyi
Normal file
@@ -0,0 +1,84 @@
|
||||
from _typeshed import SupportsItems
|
||||
from collections.abc import Iterable, Iterator, Mapping, Sequence
|
||||
from typing import Any, ClassVar, Protocol, overload
|
||||
from typing_extensions import TypeAlias
|
||||
|
||||
from wtforms.fields.core import Field, UnboundField
|
||||
from wtforms.meta import DefaultMeta, _MultiDictLike
|
||||
|
||||
_FormErrors: TypeAlias = dict[str | None, Sequence[str] | _FormErrors]
|
||||
|
||||
# _unbound_fields will always be a list on an instance, but on a
|
||||
# class it might be None, if it never has been instantiated, or
|
||||
# not instantianted after a new field had been added/removed
|
||||
class _UnboundFields(Protocol):
|
||||
@overload
|
||||
def __get__(self, obj: None, owner: type[object] | None = None) -> list[tuple[str, UnboundField[Any]]] | None: ...
|
||||
@overload
|
||||
def __get__(self, obj: object, owner: type[object] | None = None) -> list[tuple[str, UnboundField[Any]]]: ...
|
||||
|
||||
class BaseForm:
|
||||
meta: DefaultMeta
|
||||
form_errors: list[str]
|
||||
# we document this, because it's the only efficient way to introspect
|
||||
# the field names of the form, it also seems to be stable API-wise
|
||||
_fields: dict[str, Field]
|
||||
def __init__(
|
||||
self,
|
||||
fields: SupportsItems[str, UnboundField[Any]] | Iterable[tuple[str, UnboundField[Any]]],
|
||||
prefix: str = "",
|
||||
meta: DefaultMeta = ...,
|
||||
) -> None: ...
|
||||
def __iter__(self) -> Iterator[Field]: ...
|
||||
def __contains__(self, name: str) -> bool: ...
|
||||
def __getitem__(self, name: str) -> Field: ...
|
||||
def __setitem__(self, name: str, value: UnboundField[Any]) -> None: ...
|
||||
def __delitem__(self, name: str) -> None: ...
|
||||
def populate_obj(self, obj: object) -> None: ...
|
||||
# while we would like to be more strict on extra_filters, we can't easily do that
|
||||
# without it being annoying in most situations
|
||||
def process(
|
||||
self,
|
||||
formdata: _MultiDictLike | None = None,
|
||||
obj: object | None = None,
|
||||
data: Mapping[str, Any] | None = None,
|
||||
extra_filters: Mapping[str, Sequence[Any]] | None = None,
|
||||
**kwargs: object,
|
||||
) -> None: ...
|
||||
# same thing here with extra_validators
|
||||
def validate(self, extra_validators: Mapping[str, Sequence[Any]] | None = None) -> bool: ...
|
||||
@property
|
||||
def data(self) -> dict[str, Any]: ...
|
||||
# because of the Liskov violation in FormField.errors we need to make errors a recursive type
|
||||
@property
|
||||
def errors(self) -> _FormErrors: ...
|
||||
|
||||
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 __setattr__(cls, name: str, value: object) -> None: ...
|
||||
def __delattr__(cls, name: str) -> None: ...
|
||||
|
||||
class Form(BaseForm, metaclass=FormMeta):
|
||||
# due to the metaclass this should always be a subclass of DefaultMeta
|
||||
# but if we annotate this as such, then subclasses cannot use it in the
|
||||
# intended way
|
||||
Meta: ClassVar[type[Any]]
|
||||
# this attribute is documented, so we annotate it
|
||||
_unbound_fields: _UnboundFields
|
||||
def __init__(
|
||||
self,
|
||||
formdata: _MultiDictLike | None = None,
|
||||
obj: object | None = None,
|
||||
prefix: str = "",
|
||||
data: Mapping[str, Any] | None = None,
|
||||
meta: Mapping[str, Any] | None = None,
|
||||
*,
|
||||
# same issue as with process
|
||||
extra_filters: Mapping[str, Sequence[Any]] | None = None,
|
||||
**kwargs: object,
|
||||
) -> None: ...
|
||||
# this should emit a type_error, since it's not allowed to be called
|
||||
def __setitem__(self, name: str, value: None) -> None: ... # type: ignore[override]
|
||||
def __delitem__(self, name: str) -> None: ...
|
||||
def __delattr__(self, name: str) -> None: ...
|
||||
30
stubs/WTForms/wtforms/i18n.pyi
Normal file
30
stubs/WTForms/wtforms/i18n.pyi
Normal file
@@ -0,0 +1,30 @@
|
||||
from collections.abc import Callable, Iterable
|
||||
from gettext import GNUTranslations
|
||||
from typing import Protocol, TypeVar, overload
|
||||
|
||||
_T = TypeVar("_T")
|
||||
|
||||
class _SupportsUgettextAndUngettext(Protocol):
|
||||
def ugettext(self, __string: str) -> str: ...
|
||||
def ungettext(self, __singular: str, __plural: str, __n: int) -> str: ...
|
||||
|
||||
def messages_path() -> str: ...
|
||||
def get_builtin_gnu_translations(languages: Iterable[str] | None = None) -> GNUTranslations: ...
|
||||
@overload
|
||||
def get_translations(
|
||||
languages: Iterable[str] | None = None, getter: Callable[[Iterable[str]], GNUTranslations] = ...
|
||||
) -> GNUTranslations: ...
|
||||
@overload
|
||||
def get_translations(languages: Iterable[str] | None = None, *, getter: Callable[[Iterable[str]], _T]) -> _T: ...
|
||||
@overload
|
||||
def get_translations(languages: Iterable[str] | None, getter: Callable[[Iterable[str]], _T]) -> _T: ...
|
||||
|
||||
class DefaultTranslations:
|
||||
translations: _SupportsUgettextAndUngettext
|
||||
def __init__(self, translations: _SupportsUgettextAndUngettext) -> None: ...
|
||||
def gettext(self, string: str) -> str: ...
|
||||
def ngettext(self, singular: str, plural: str, n: int) -> str: ...
|
||||
|
||||
class DummyTranslations:
|
||||
def gettext(self, string: str) -> str: ...
|
||||
def ngettext(self, singular: str, plural: str, n: int) -> str: ...
|
||||
55
stubs/WTForms/wtforms/meta.pyi
Normal file
55
stubs/WTForms/wtforms/meta.pyi
Normal file
@@ -0,0 +1,55 @@
|
||||
from _typeshed import SupportsItems
|
||||
from collections.abc import Collection, Iterator, MutableMapping
|
||||
from typing import Any, Protocol, TypeVar, overload
|
||||
from typing_extensions import Literal, TypeAlias
|
||||
|
||||
from markupsafe import Markup
|
||||
from wtforms.fields.core import Field, UnboundField
|
||||
from wtforms.form import BaseForm
|
||||
|
||||
_FieldT = TypeVar("_FieldT", bound=Field)
|
||||
|
||||
class _SupportsGettextAndNgettext(Protocol):
|
||||
def gettext(self, __string: str) -> str: ...
|
||||
def ngettext(self, __singular: str, __plural: str, __n: int) -> str: ...
|
||||
|
||||
# these are the methods WTForms depends on, the dict can either provide
|
||||
# a getlist or getall, if it only provies getall, it will wrapped, to
|
||||
# provide getlist instead
|
||||
class _MultiDictLikeBase(Protocol):
|
||||
def __iter__(self) -> Iterator[str]: ...
|
||||
def __len__(self) -> int: ...
|
||||
def __contains__(self, __key: Any) -> bool: ...
|
||||
|
||||
# since how file uploads are represented in formdata is implementation-specific
|
||||
# we have to be generous in what we accept in the return of getlist/getall
|
||||
# we can make this generic if we ever want to be more specific
|
||||
class _MultiDictLikeWithGetlist(_MultiDictLikeBase, Protocol):
|
||||
def getlist(self, __key: str) -> list[Any]: ...
|
||||
|
||||
class _MultiDictLikeWithGetall(_MultiDictLikeBase, Protocol):
|
||||
def getall(self, __key: str) -> list[Any]: ...
|
||||
|
||||
_MultiDictLike: TypeAlias = _MultiDictLikeWithGetall | _MultiDictLikeWithGetlist
|
||||
|
||||
class DefaultMeta:
|
||||
def bind_field(self, form: BaseForm, unbound_field: UnboundField[_FieldT], options: MutableMapping[str, Any]) -> _FieldT: ...
|
||||
@overload
|
||||
def wrap_formdata(self, form: BaseForm, formdata: None) -> None: ...
|
||||
@overload
|
||||
def wrap_formdata(self, form: BaseForm, formdata: _MultiDictLike) -> _MultiDictLikeWithGetlist: ...
|
||||
def render_field(self, field: Field, render_kw: SupportsItems[str, Any]) -> Markup: ...
|
||||
csrf: bool
|
||||
csrf_field_name: str
|
||||
csrf_secret: Any | None
|
||||
csrf_context: Any | None
|
||||
csrf_class: type[Any] | None
|
||||
def build_csrf(self, form: BaseForm) -> Any: ...
|
||||
locales: Literal[False] | Collection[str]
|
||||
cache_translations: bool
|
||||
translations_cache: dict[str, _SupportsGettextAndNgettext]
|
||||
def get_translations(self, form: BaseForm) -> _SupportsGettextAndNgettext: ...
|
||||
def update_values(self, values: SupportsItems[str, Any]) -> None: ...
|
||||
# since meta can be extended with arbitary data we add a __getattr__
|
||||
# method that returns Any
|
||||
def __getattr__(self, name: str) -> Any: ...
|
||||
19
stubs/WTForms/wtforms/utils.pyi
Normal file
19
stubs/WTForms/wtforms/utils.pyi
Normal file
@@ -0,0 +1,19 @@
|
||||
from collections.abc import Iterable, Iterator
|
||||
from typing import Any
|
||||
from typing_extensions import Literal
|
||||
|
||||
from wtforms.meta import _MultiDictLikeWithGetall
|
||||
|
||||
def clean_datetime_format_for_strptime(formats: Iterable[str]) -> list[str]: ...
|
||||
|
||||
class UnsetValue:
|
||||
def __bool__(self) -> Literal[False]: ...
|
||||
|
||||
unset_value: UnsetValue
|
||||
|
||||
class WebobInputWrapper:
|
||||
def __init__(self, multidict: _MultiDictLikeWithGetall) -> None: ...
|
||||
def __iter__(self) -> Iterator[str]: ...
|
||||
def __len__(self) -> int: ...
|
||||
def __contains__(self, name: str) -> bool: ...
|
||||
def getlist(self, name: str) -> list[Any]: ...
|
||||
158
stubs/WTForms/wtforms/validators.pyi
Normal file
158
stubs/WTForms/wtforms/validators.pyi
Normal file
@@ -0,0 +1,158 @@
|
||||
from collections.abc import Callable, Collection, Iterable
|
||||
from decimal import Decimal
|
||||
from re import Match, Pattern
|
||||
from typing import Any, TypeVar, overload
|
||||
|
||||
from wtforms.fields import Field, StringField
|
||||
from wtforms.form import BaseForm
|
||||
|
||||
_ValuesT = TypeVar("_ValuesT", bound=Collection[Any], contravariant=True)
|
||||
|
||||
class ValidationError(ValueError):
|
||||
def __init__(self, message: str = "", *args: object) -> None: ...
|
||||
|
||||
class StopValidation(Exception):
|
||||
def __init__(self, message: str = "", *args: object) -> None: ...
|
||||
|
||||
class EqualTo:
|
||||
fieldname: str
|
||||
message: str | None
|
||||
def __init__(self, fieldname: str, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: Field) -> None: ...
|
||||
|
||||
class Length:
|
||||
min: int
|
||||
max: int
|
||||
message: str | None
|
||||
field_flags: dict[str, Any]
|
||||
def __init__(self, min: int = -1, max: int = -1, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: StringField) -> None: ...
|
||||
|
||||
class NumberRange:
|
||||
min: float | Decimal | None
|
||||
max: float | Decimal | None
|
||||
message: str | None
|
||||
field_flags: dict[str, Any]
|
||||
def __init__(
|
||||
self, min: float | Decimal | None = None, max: float | Decimal | None = None, message: str | None = None
|
||||
) -> None: ...
|
||||
# any numeric field will work, for now we don't try to use a union
|
||||
# to restrict to the defined numeric fields, since user-defined fields
|
||||
# will likely not use a common base class, just like the existing
|
||||
# numeric fields
|
||||
def __call__(self, form: BaseForm, field: Field) -> None: ...
|
||||
|
||||
class Optional:
|
||||
string_check: Callable[[str], bool]
|
||||
field_flags: dict[str, Any]
|
||||
def __init__(self, strip_whitespace: bool = True) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: Field) -> None: ...
|
||||
|
||||
class DataRequired:
|
||||
message: str | None
|
||||
field_flags: dict[str, Any]
|
||||
def __init__(self, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: Field) -> None: ...
|
||||
|
||||
class InputRequired:
|
||||
message: str | None
|
||||
field_flags: dict[str, Any]
|
||||
def __init__(self, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: Field) -> None: ...
|
||||
|
||||
class Regexp:
|
||||
regex: Pattern[str]
|
||||
message: str | None
|
||||
def __init__(self, regex: str | Pattern[str], flags: int = 0, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: StringField, message: str | None = None) -> Match[str]: ...
|
||||
|
||||
class Email:
|
||||
message: str | None
|
||||
granular_message: bool
|
||||
check_deliverability: bool
|
||||
allow_smtputf8: bool
|
||||
allow_empty_local: bool
|
||||
def __init__(
|
||||
self,
|
||||
message: str | None = None,
|
||||
granular_message: bool = False,
|
||||
check_deliverability: bool = False,
|
||||
allow_smtputf8: bool = True,
|
||||
allow_empty_local: bool = False,
|
||||
) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: StringField) -> None: ...
|
||||
|
||||
class IPAddress:
|
||||
ipv4: bool
|
||||
ipv6: bool
|
||||
message: str | None
|
||||
def __init__(self, ipv4: bool = True, ipv6: bool = False, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: StringField) -> None: ...
|
||||
@classmethod
|
||||
def check_ipv4(cls, value: str | None) -> bool: ...
|
||||
@classmethod
|
||||
def check_ipv6(cls, value: str | None) -> bool: ...
|
||||
|
||||
class MacAddress(Regexp):
|
||||
def __init__(self, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: StringField) -> None: ... # type: ignore[override]
|
||||
|
||||
class URL(Regexp):
|
||||
validate_hostname: HostnameValidation
|
||||
def __init__(self, require_tld: bool = True, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: StringField) -> None: ... # type: ignore[override]
|
||||
|
||||
class UUID:
|
||||
message: str | None
|
||||
def __init__(self, message: str | None = None) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: StringField) -> None: ...
|
||||
|
||||
class AnyOf:
|
||||
values: Collection[Any]
|
||||
message: str | None
|
||||
values_formatter: Callable[[Any], str]
|
||||
@overload
|
||||
def __init__(self, values: Collection[Any], message: str | None = None, values_formatter: None = None) -> None: ...
|
||||
@overload
|
||||
def __init__(self, values: _ValuesT, message: str | None, values_formatter: Callable[[_ValuesT], str]) -> None: ...
|
||||
@overload
|
||||
def __init__(self, values: _ValuesT, message: str | None = None, *, values_formatter: Callable[[_ValuesT], str]) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: Field) -> None: ...
|
||||
@staticmethod
|
||||
def default_values_formatter(values: Iterable[object]) -> str: ...
|
||||
|
||||
class NoneOf:
|
||||
values: Collection[Any]
|
||||
message: str | None
|
||||
values_formatter: Callable[[Any], str]
|
||||
@overload
|
||||
def __init__(self, values: Collection[Any], message: str | None = None, values_formatter: None = None) -> None: ...
|
||||
@overload
|
||||
def __init__(self, values: _ValuesT, message: str | None, values_formatter: Callable[[_ValuesT], str]) -> None: ...
|
||||
@overload
|
||||
def __init__(self, values: _ValuesT, message: str | None = None, *, values_formatter: Callable[[_ValuesT], str]) -> None: ...
|
||||
def __call__(self, form: BaseForm, field: Field) -> None: ...
|
||||
@staticmethod
|
||||
def default_values_formatter(v: Iterable[object]) -> str: ...
|
||||
|
||||
class HostnameValidation:
|
||||
hostname_part: Pattern[str]
|
||||
tld_part: Pattern[str]
|
||||
require_tld: bool
|
||||
allow_ip: bool
|
||||
def __init__(self, require_tld: bool = True, allow_ip: bool = False) -> None: ...
|
||||
def __call__(self, hostname: str) -> bool: ...
|
||||
|
||||
email = Email
|
||||
equal_to = EqualTo
|
||||
ip_address = IPAddress
|
||||
mac_address = MacAddress
|
||||
length = Length
|
||||
number_range = NumberRange
|
||||
optional = Optional
|
||||
input_required = InputRequired
|
||||
data_required = DataRequired
|
||||
regexp = Regexp
|
||||
url = URL
|
||||
any_of = AnyOf
|
||||
none_of = NoneOf
|
||||
2
stubs/WTForms/wtforms/widgets/__init__.pyi
Normal file
2
stubs/WTForms/wtforms/widgets/__init__.pyi
Normal file
@@ -0,0 +1,2 @@
|
||||
from wtforms.widgets.core import *
|
||||
from wtforms.widgets.core import Input as Input, html_params as html_params
|
||||
121
stubs/WTForms/wtforms/widgets/core.pyi
Normal file
121
stubs/WTForms/wtforms/widgets/core.pyi
Normal file
@@ -0,0 +1,121 @@
|
||||
from decimal import Decimal
|
||||
from typing import Any
|
||||
from typing_extensions import Literal
|
||||
|
||||
from markupsafe import Markup
|
||||
from wtforms.fields import Field, FormField, SelectFieldBase, StringField
|
||||
from wtforms.fields.choices import _Option
|
||||
|
||||
__all__ = (
|
||||
"CheckboxInput",
|
||||
"ColorInput",
|
||||
"DateInput",
|
||||
"DateTimeInput",
|
||||
"DateTimeLocalInput",
|
||||
"EmailInput",
|
||||
"FileInput",
|
||||
"HiddenInput",
|
||||
"ListWidget",
|
||||
"MonthInput",
|
||||
"NumberInput",
|
||||
"Option",
|
||||
"PasswordInput",
|
||||
"RadioInput",
|
||||
"RangeInput",
|
||||
"SearchInput",
|
||||
"Select",
|
||||
"SubmitInput",
|
||||
"TableWidget",
|
||||
"TextArea",
|
||||
"TextInput",
|
||||
"TelInput",
|
||||
"TimeInput",
|
||||
"URLInput",
|
||||
"WeekInput",
|
||||
)
|
||||
|
||||
def html_params(**kwargs: object) -> str: ...
|
||||
|
||||
class ListWidget:
|
||||
html_tag: Literal["ul", "ol"]
|
||||
prefix_label: bool
|
||||
def __init__(self, html_tag: Literal["ul", "ol"] = "ul", prefix_label: bool = True) -> None: ...
|
||||
# any iterable field is fine, since people might define iterable fields
|
||||
# that are not derived from FieldList, we just punt and accept any field
|
||||
# with Intersection we could be more specific
|
||||
def __call__(self, field: Field, **kwargs: object) -> Markup: ...
|
||||
|
||||
class TableWidget:
|
||||
with_table_tag: bool
|
||||
def __init__(self, with_table_tag: bool = True) -> None: ...
|
||||
def __call__(self, field: FormField[Any], **kwargs: object) -> Markup: ...
|
||||
|
||||
class Input:
|
||||
validation_attrs: list[str]
|
||||
input_type: str
|
||||
def __init__(self, input_type: str | None = None) -> None: ...
|
||||
def __call__(self, field: Field, **kwargs: object) -> Markup: ...
|
||||
@staticmethod
|
||||
def html_params(**kwargs: object) -> str: ...
|
||||
|
||||
class TextInput(Input): ...
|
||||
|
||||
class PasswordInput(Input):
|
||||
hide_value: bool
|
||||
def __init__(self, hide_value: bool = True) -> None: ...
|
||||
|
||||
class HiddenInput(Input):
|
||||
field_flags: dict[str, Any]
|
||||
|
||||
class CheckboxInput(Input): ...
|
||||
class RadioInput(Input): ...
|
||||
|
||||
class FileInput(Input):
|
||||
multiple: bool
|
||||
def __init__(self, multiple: bool = False) -> None: ...
|
||||
|
||||
class SubmitInput(Input): ...
|
||||
|
||||
class TextArea:
|
||||
validation_attrs: list[str]
|
||||
def __call__(self, field: StringField, **kwargs: object) -> Markup: ...
|
||||
|
||||
class Select:
|
||||
validation_attrs: list[str]
|
||||
multiple: bool
|
||||
def __init__(self, multiple: bool = False) -> None: ...
|
||||
def __call__(self, field: SelectFieldBase, **kwargs: object) -> Markup: ...
|
||||
@classmethod
|
||||
def render_option(cls, value: object, label: str, selected: bool, **kwargs: object) -> Markup: ...
|
||||
|
||||
class Option:
|
||||
def __call__(self, field: _Option, **kwargs: object) -> Markup: ...
|
||||
|
||||
class SearchInput(Input): ...
|
||||
class TelInput(Input): ...
|
||||
class URLInput(Input): ...
|
||||
class EmailInput(Input): ...
|
||||
class DateTimeInput(Input): ...
|
||||
class DateInput(Input): ...
|
||||
class MonthInput(Input): ...
|
||||
class WeekInput(Input): ...
|
||||
class TimeInput(Input): ...
|
||||
class DateTimeLocalInput(Input): ...
|
||||
|
||||
class NumberInput(Input):
|
||||
step: Decimal | float | str | None
|
||||
min: Decimal | float | str | None
|
||||
max: Decimal | float | str | None
|
||||
def __init__(
|
||||
self,
|
||||
step: Decimal | float | str | None = None,
|
||||
min: Decimal | float | str | None = None,
|
||||
max: Decimal | float | str | None = None,
|
||||
) -> None: ...
|
||||
|
||||
class RangeInput(Input):
|
||||
# maybe we should allow any str for this
|
||||
step: Decimal | float | str | None
|
||||
def __init__(self, step: Decimal | float | str | None = None) -> None: ...
|
||||
|
||||
class ColorInput(Input): ...
|
||||
Reference in New Issue
Block a user