Skip to content

Add stubs for WebTest #14541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions stubs/WebTest/@tests/stubtest_allowlist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# error: failed to find stub
# ==========================
# These modules have been migrated to external packages
# and emit an `ImportError` if people try to use the
# functions/classes defined within
webtest.ext
webtest.sel
# Compatibility/utility modules for internal use that didn't
# seem worth including in the stubs
webtest.compat
webtest.lint
webtest.utils

# error: variable differs from runtime type
# =========================================
# Even though this can be `None`, it never should be during
# normal use of WebTest, so it seems more pragmatic to treat
# it as always non-`None`
webtest.response.TestResponse.request
webtest.TestResponse.request
3 changes: 3 additions & 0 deletions stubs/WebTest/METADATA.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
version = "3.0.*"
upstream_repository = "https://github.com/Pylons/webtest"
requires = ["types-beautifulsoup4", "types-waitress", "types-WebOb"]
14 changes: 14 additions & 0 deletions stubs/WebTest/webtest/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from webtest.app import AppError as AppError, TestApp as TestApp, TestRequest as TestRequest
from webtest.forms import (
Checkbox as Checkbox,
Field as Field,
Form as Form,
Hidden as Hidden,
Radio as Radio,
Select as Select,
Submit as Submit,
Text as Text,
Textarea as Textarea,
Upload as Upload,
)
from webtest.response import TestResponse as TestResponse
187 changes: 187 additions & 0 deletions stubs/WebTest/webtest/app.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import json
from _typeshed.wsgi import WSGIApplication
from collections.abc import Mapping, Sequence
from http.cookiejar import CookieJar, DefaultCookiePolicy
from typing import Any, Generic, Literal, TypeVar
from typing_extensions import TypeAlias

from webob.request import BaseRequest
from webtest.response import TestResponse

_Files: TypeAlias = Sequence[tuple[str, str] | tuple[str, str, bytes]]
_AppT = TypeVar("_AppT", bound=WSGIApplication, default=WSGIApplication)

__all__ = ["TestApp", "TestRequest"]

class AppError(Exception):
def __init__(self, message: str, *args: object) -> None: ...

class CookiePolicy(DefaultCookiePolicy): ...

class TestRequest(BaseRequest):
ResponseClass: type[TestResponse]
__test__: Literal[False]

class TestApp(Generic[_AppT]):
RequestClass: type[TestRequest]
app: _AppT
lint: bool
relative_to: str | None
extra_environ: dict[str, Any]
use_unicode: bool
cookiejar: CookieJar
JSONEncoder: json.JSONEncoder
__test__: Literal[False]
def __init__(
self,
app: _AppT,
extra_environ: dict[str, Any] | None = None,
relative_to: str | None = None,
use_unicode: bool = True,
cookiejar: CookieJar | None = None,
parser_features: Sequence[str] | str | None = None,
json_encoder: json.JSONEncoder | None = None,
lint: bool = True,
) -> None: ...
def get_authorization(self) -> tuple[str, str | tuple[str, str]]: ...
def set_authorization(self, value: tuple[str, str | tuple[str, str]]) -> None: ...
@property
def authorization(self) -> tuple[str, str | tuple[str, str]]: ...
@authorization.setter
def authorization(self, value: tuple[str, str | tuple[str, str]]) -> None: ...
@property
def cookies(self) -> dict[str, str | None]: ...
def set_cookie(self, name: str, value: str | None) -> None: ...
def reset(self) -> None: ...
def set_parser_features(self, parser_features: Sequence[str] | str) -> None: ...
def get(
self,
url: str,
params: Mapping[str, str] | str | None = None,
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
xhr: bool = False,
) -> TestResponse: ...
def post(
self,
url: str,
params: Mapping[str, str] | str = "",
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
upload_files: _Files | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def put(
self,
url: str,
params: Mapping[str, str] | str = "",
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
upload_files: _Files | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def patch(
self,
url: str,
params: Mapping[str, str] | str = "",
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
upload_files: _Files | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def delete(
self,
url: str,
params: Mapping[str, str] | str = "",
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def options(
self,
url: str,
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
xhr: bool = False,
) -> TestResponse: ...
def head(
self,
url: str,
params: Mapping[str, str] | str | None = None,
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
xhr: bool = False,
) -> TestResponse: ...
def post_json(
self,
url: str,
params: Any = ...,
*,
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def put_json(
self,
url: str,
params: Any = ...,
*,
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def patch_json(
self,
url: str,
params: Any = ...,
*,
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def delete_json(
self,
url: str,
params: Any = ...,
*,
headers: Mapping[str, str] | None = None,
extra_environ: Mapping[str, Any] | None = None,
status: int | str | None = None,
expect_errors: bool = False,
content_type: str | None = None,
xhr: bool = False,
) -> TestResponse: ...
def encode_multipart(self, params: Sequence[tuple[str, str]], files: _Files) -> tuple[str, bytes]: ...
def request(
self, url_or_req: str | TestRequest, status: int | str | None = None, expect_errors: bool = False, **req_params: Any
) -> TestResponse: ...
def do_request(
self, req: TestRequest, status: int | str | None = None, expect_errors: bool | None = None
) -> TestResponse: ...
21 changes: 21 additions & 0 deletions stubs/WebTest/webtest/debugapp.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from _typeshed import StrOrBytesPath
from _typeshed.wsgi import StartResponse, WSGIEnvironment
from collections.abc import Iterable
from typing import TypedDict
from typing_extensions import Unpack

class _DebugAppParams(TypedDict, total=False):
form: StrOrBytesPath | bytes | None
show_form: bool

__all__ = ["DebugApp", "make_debug_app"]

class DebugApp:
form: bytes | None
show_form: bool
def __init__(self, form: StrOrBytesPath | bytes | None = None, show_form: bool = False) -> None: ...
def __call__(self, environ: WSGIEnvironment, start_response: StartResponse) -> Iterable[bytes]: ...

debug_app: DebugApp

def make_debug_app(global_conf: object, **local_conf: Unpack[_DebugAppParams]) -> DebugApp: ...
Loading