Skip to content
Merged
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
2 changes: 1 addition & 1 deletion py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ disallow_incomplete_defs = false
# type-checks the interior of functions without type annotations.
check_untyped_defs = false
# reports an error whenever a function with type annotations is decorated with a decorator without annotations.
disallow_untyped_decorators = false
disallow_untyped_decorators = true
# changes the treatment of arguments with a default value of None by not implicitly making their type `typing.Optional`.
no_implicit_optional = true
# warns about casting an expression to it's inferred type.
Expand Down
17 changes: 11 additions & 6 deletions py/selenium/webdriver/remote/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
import zipfile
from abc import ABCMeta
from base64 import b64decode, urlsafe_b64encode
from collections.abc import Generator
from collections.abc import Callable, Generator
from contextlib import asynccontextmanager, contextmanager
from importlib import import_module
from typing import TYPE_CHECKING, Any, cast
from typing import TYPE_CHECKING, Any, Concatenate, ParamSpec, TypeVar, cast

from typing_extensions import Self

Expand Down Expand Up @@ -173,6 +173,11 @@ def create_matches(options: list[BaseOptions]) -> dict:
return capabilities


_P = ParamSpec("_P")
_R = TypeVar("_R")
_D = TypeVar("_D", bound="WebDriver")


if TYPE_CHECKING:
from selenium.webdriver.common.api_request_context import APIRequestContext
from selenium.webdriver.common.fedcm.dialog import Dialog
Expand All @@ -181,9 +186,9 @@ def create_matches(options: list[BaseOptions]) -> dict:
from selenium.webdriver.common.virtual_authenticator import Credential, VirtualAuthenticatorOptions


def _required_chromium_based_browser(func):
def _required_chromium_based_browser(func: Callable[Concatenate[_D, _P], _R]) -> Callable[Concatenate[_D, _P], _R]:
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
def wrapper(self: _D, *args: _P.args, **kwargs: _P.kwargs) -> _R:
assert self.caps["browserName"].lower() not in ["firefox", "safari"], (
"This only currently works in Chromium based browsers"
)
Expand All @@ -192,10 +197,10 @@ def wrapper(self, *args, **kwargs):
return wrapper


def _required_virtual_authenticator(func):
def _required_virtual_authenticator(func: Callable[Concatenate[_D, _P], _R]) -> Callable[Concatenate[_D, _P], _R]:
@functools.wraps(func)
@_required_chromium_based_browser
def wrapper(self, *args, **kwargs):
def wrapper(self: _D, *args: _P.args, **kwargs: _P.kwargs) -> _R:
if not self.virtual_authenticator_id:
raise ValueError("This function requires a virtual authenticator to be set.")
return func(self, *args, **kwargs)
Expand Down