diff --git a/py/selenium/common/exceptions.py b/py/selenium/common/exceptions.py index 645e81bdc24d3..6f10146b779d4 100644 --- a/py/selenium/common/exceptions.py +++ b/py/selenium/common/exceptions.py @@ -16,7 +16,8 @@ # under the License. """Exceptions that may happen in all the webdriver code.""" -from typing import Optional, Sequence +from collections.abc import Sequence +from typing import Optional SUPPORT_MSG = "For documentation on this error, please visit:" ERROR_URL = "https://www.selenium.dev/documentation/webdriver/troubleshooting/errors" diff --git a/py/selenium/types.py b/py/selenium/types.py index b6af1d57e60e8..fdec985bd16ab 100644 --- a/py/selenium/types.py +++ b/py/selenium/types.py @@ -16,10 +16,11 @@ # under the License. """Selenium type definitions.""" -from typing import IO, Any, Iterable, Type, Union +from collections.abc import Iterable +from typing import IO, Any, Union AnyKey = Union[str, int, float] -WaitExcTypes = Iterable[Type[Exception]] +WaitExcTypes = Iterable[type[Exception]] # Service Types SubprocessStdAlias = Union[int, str, IO[Any]] diff --git a/py/selenium/webdriver/chrome/service.py b/py/selenium/webdriver/chrome/service.py index ff90b95eac651..036b35ef99623 100644 --- a/py/selenium/webdriver/chrome/service.py +++ b/py/selenium/webdriver/chrome/service.py @@ -16,7 +16,8 @@ # under the License. -from typing import List, Mapping, Optional +from collections.abc import Mapping +from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.chromium import service @@ -37,7 +38,7 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, log_output: Optional[SubprocessStdAlias] = None, env: Optional[Mapping[str, str]] = None, **kwargs, diff --git a/py/selenium/webdriver/chromium/options.py b/py/selenium/webdriver/chromium/options.py index a2f55ec1a5534..1a83cd42b4c77 100644 --- a/py/selenium/webdriver/chromium/options.py +++ b/py/selenium/webdriver/chromium/options.py @@ -17,7 +17,7 @@ import base64 import os -from typing import BinaryIO, Dict, List, Optional, Union +from typing import BinaryIO, Optional, Union from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.options import ArgOptions @@ -29,9 +29,9 @@ class ChromiumOptions(ArgOptions): def __init__(self) -> None: super().__init__() self._binary_location: str = "" - self._extension_files: List[str] = [] - self._extensions: List[str] = [] - self._experimental_options: Dict[str, Union[str, int, dict, List[str]]] = {} + self._extension_files: list[str] = [] + self._extensions: list[str] = [] + self._experimental_options: dict[str, Union[str, int, dict, list[str]]] = {} self._debugger_address: Optional[str] = None @property @@ -68,7 +68,7 @@ def debugger_address(self, value: str) -> None: self._debugger_address = value @property - def extensions(self) -> List[str]: + def extensions(self) -> list[str]: """:Returns: A list of encoded extensions that will be loaded.""" def _decode(file_data: BinaryIO) -> str: @@ -117,7 +117,7 @@ def experimental_options(self) -> dict: """:Returns: A dictionary of experimental options for chromium.""" return self._experimental_options - def add_experimental_option(self, name: str, value: Union[str, int, dict, List[str]]) -> None: + def add_experimental_option(self, name: str, value: Union[str, int, dict, list[str]]) -> None: """Adds an experimental option which is passed to chromium. :Args: diff --git a/py/selenium/webdriver/chromium/service.py b/py/selenium/webdriver/chromium/service.py index 897b6d1e7395d..9f50e21e8e36f 100644 --- a/py/selenium/webdriver/chromium/service.py +++ b/py/selenium/webdriver/chromium/service.py @@ -14,8 +14,9 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +from collections.abc import Mapping from io import IOBase -from typing import List, Mapping, Optional +from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service @@ -37,7 +38,7 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, log_output: Optional[SubprocessStdAlias] = None, env: Optional[Mapping[str, str]] = None, driver_path_env_key: Optional[str] = None, @@ -63,5 +64,5 @@ def __init__( **kwargs, ) - def command_line_args(self) -> List[str]: + def command_line_args(self) -> list[str]: return [f"--port={self.port}"] + self.service_args diff --git a/py/selenium/webdriver/common/actions/action_builder.py b/py/selenium/webdriver/common/actions/action_builder.py index 5cbb1c7f1aad0..211217edd7140 100644 --- a/py/selenium/webdriver/common/actions/action_builder.py +++ b/py/selenium/webdriver/common/actions/action_builder.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import List, Optional, Union +from typing import Optional, Union from selenium.webdriver.remote.command import Command @@ -61,11 +61,11 @@ def get_device_with(self, name: str) -> Optional[Union["WheelInput", "PointerInp return next(filter(lambda x: x == name, self.devices), None) @property - def pointer_inputs(self) -> List[PointerInput]: + def pointer_inputs(self) -> list[PointerInput]: return [device for device in self.devices if device.type == interaction.POINTER] @property - def key_inputs(self) -> List[KeyInput]: + def key_inputs(self) -> list[KeyInput]: return [device for device in self.devices if device.type == interaction.KEY] @property diff --git a/py/selenium/webdriver/common/actions/input_device.py b/py/selenium/webdriver/common/actions/input_device.py index 70b4caacb55f2..37b6ff5c7061a 100644 --- a/py/selenium/webdriver/common/actions/input_device.py +++ b/py/selenium/webdriver/common/actions/input_device.py @@ -16,7 +16,7 @@ # under the License. import uuid -from typing import Any, List, Optional +from typing import Any, Optional class InputDevice: @@ -24,7 +24,7 @@ class InputDevice: def __init__(self, name: Optional[str] = None): self.name = name or uuid.uuid4() - self.actions: List[Any] = [] + self.actions: list[Any] = [] def add_action(self, action: Any) -> None: """""" diff --git a/py/selenium/webdriver/common/actions/interaction.py b/py/selenium/webdriver/common/actions/interaction.py index 2af9318173b8e..6225efcf143e7 100644 --- a/py/selenium/webdriver/common/actions/interaction.py +++ b/py/selenium/webdriver/common/actions/interaction.py @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -from typing import Dict, Union +from typing import Union KEY = "key" POINTER = "pointer" @@ -41,5 +41,5 @@ def __init__(self, source, duration: float = 0) -> None: super().__init__(source) self.duration = duration - def encode(self) -> Dict[str, Union[str, int]]: + def encode(self) -> dict[str, Union[str, int]]: return {"type": self.PAUSE, "duration": int(self.duration * 1000)} diff --git a/py/selenium/webdriver/common/actions/pointer_input.py b/py/selenium/webdriver/common/actions/pointer_input.py index d7296bd35f5de..615ce6edb1932 100644 --- a/py/selenium/webdriver/common/actions/pointer_input.py +++ b/py/selenium/webdriver/common/actions/pointer_input.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import Any, Dict, Optional, Union +from typing import Any, Optional, Union from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.remote.webelement import WebElement @@ -66,7 +66,7 @@ def create_pause(self, pause_duration: Union[int, float] = 0) -> None: def encode(self): return {"type": self.type, "parameters": {"pointerType": self.kind}, "id": self.name, "actions": self.actions} - def _convert_keys(self, actions: Dict[str, Any]): + def _convert_keys(self, actions: dict[str, Any]): out = {} for k, v in actions.items(): if v is None: diff --git a/py/selenium/webdriver/common/bidi/browser.py b/py/selenium/webdriver/common/bidi/browser.py index 261987619e08d..ce697051bef44 100644 --- a/py/selenium/webdriver/common/bidi/browser.py +++ b/py/selenium/webdriver/common/bidi/browser.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Dict, List from selenium.webdriver.common.bidi.common import command_builder @@ -114,7 +113,7 @@ def is_active(self) -> bool: return self.active @classmethod - def from_dict(cls, data: Dict) -> "ClientWindowInfo": + def from_dict(cls, data: dict) -> "ClientWindowInfo": """Creates a ClientWindowInfo instance from a dictionary. Parameters: @@ -154,7 +153,7 @@ def create_user_context(self) -> str: result = self.conn.execute(command_builder("browser.createUserContext", {})) return result["userContext"] - def get_user_contexts(self) -> List[str]: + def get_user_contexts(self) -> list[str]: """Gets all user contexts. Returns: @@ -181,7 +180,7 @@ def remove_user_context(self, user_context_id: str) -> None: params = {"userContext": user_context_id} self.conn.execute(command_builder("browser.removeUserContext", params)) - def get_client_windows(self) -> List[ClientWindowInfo]: + def get_client_windows(self) -> list[ClientWindowInfo]: """Gets all client windows. Returns: diff --git a/py/selenium/webdriver/common/bidi/browsing_context.py b/py/selenium/webdriver/common/bidi/browsing_context.py index b2ea4e152abe4..e843752b7a27f 100644 --- a/py/selenium/webdriver/common/bidi/browsing_context.py +++ b/py/selenium/webdriver/common/bidi/browsing_context.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import Dict, List, Optional, Union +from typing import Optional, Union from selenium.webdriver.common.bidi.common import command_builder @@ -55,7 +55,7 @@ def __init__( self.url = url @classmethod - def from_json(cls, json: Dict) -> "NavigationInfo": + def from_json(cls, json: dict) -> "NavigationInfo": """Creates a NavigationInfo instance from a dictionary. Parameters: @@ -81,7 +81,7 @@ def __init__( self, context: str, url: str, - children: Optional[List["BrowsingContextInfo"]], + children: Optional[list["BrowsingContextInfo"]], parent: Optional[str] = None, user_context: Optional[str] = None, original_opener: Optional[str] = None, @@ -96,7 +96,7 @@ def __init__( self.client_window = client_window @classmethod - def from_json(cls, json: Dict) -> "BrowsingContextInfo": + def from_json(cls, json: dict) -> "BrowsingContextInfo": """Creates a BrowsingContextInfo instance from a dictionary. Parameters: @@ -137,7 +137,7 @@ def __init__( self.suggested_filename = suggested_filename @classmethod - def from_json(cls, json: Dict) -> "DownloadWillBeginParams": + def from_json(cls, json: dict) -> "DownloadWillBeginParams": """Creates a DownloadWillBeginParams instance from a dictionary. Parameters: @@ -175,7 +175,7 @@ def __init__( self.default_value = default_value @classmethod - def from_json(cls, json: Dict) -> "UserPromptOpenedParams": + def from_json(cls, json: dict) -> "UserPromptOpenedParams": """Creates a UserPromptOpenedParams instance from a dictionary. Parameters: @@ -211,7 +211,7 @@ def __init__( self.user_text = user_text @classmethod - def from_json(cls, json: Dict) -> "UserPromptClosedParams": + def from_json(cls, json: dict) -> "UserPromptClosedParams": """Creates a UserPromptClosedParams instance from a dictionary. Parameters: @@ -242,7 +242,7 @@ def __init__( self.url = url @classmethod - def from_json(cls, json: Dict) -> "HistoryUpdatedParams": + def from_json(cls, json: dict) -> "HistoryUpdatedParams": """Creates a HistoryUpdatedParams instance from a dictionary. Parameters: @@ -267,7 +267,7 @@ def __init__(self, event_class: str, **kwargs): self.params = kwargs @classmethod - def from_json(cls, json: Dict) -> "BrowsingContextEvent": + def from_json(cls, json: dict) -> "BrowsingContextEvent": """Creates a BrowsingContextEvent instance from a dictionary. Parameters: @@ -323,8 +323,8 @@ def capture_screenshot( self, context: str, origin: str = "viewport", - format: Optional[Dict] = None, - clip: Optional[Dict] = None, + format: Optional[dict] = None, + clip: Optional[dict] = None, ) -> str: """Captures an image of the given navigable, and returns it as a Base64-encoded string. @@ -398,7 +398,7 @@ def get_tree( self, max_depth: Optional[int] = None, root: Optional[str] = None, - ) -> List[BrowsingContextInfo]: + ) -> list[BrowsingContextInfo]: """Returns a tree of all descendent navigables including the given parent itself, or all top-level contexts when no parent is provided. @@ -445,11 +445,11 @@ def handle_user_prompt( def locate_nodes( self, context: str, - locator: Dict, + locator: dict, max_node_count: Optional[int] = None, - serialization_options: Optional[Dict] = None, - start_nodes: Optional[List[Dict]] = None, - ) -> List[Dict]: + serialization_options: Optional[dict] = None, + start_nodes: Optional[list[dict]] = None, + ) -> list[dict]: """Returns a list of all nodes matching the specified locator. Parameters: @@ -480,7 +480,7 @@ def navigate( context: str, url: str, wait: Optional[str] = None, - ) -> Dict: + ) -> dict: """Navigates a navigable to the given URL. Parameters: @@ -504,10 +504,10 @@ def print( self, context: str, background: bool = False, - margin: Optional[Dict] = None, + margin: Optional[dict] = None, orientation: str = "portrait", - page: Optional[Dict] = None, - page_ranges: Optional[List[Union[int, str]]] = None, + page: Optional[dict] = None, + page_ranges: Optional[list[Union[int, str]]] = None, scale: float = 1.0, shrink_to_fit: bool = True, ) -> str: @@ -551,7 +551,7 @@ def reload( context: str, ignore_cache: Optional[bool] = None, wait: Optional[str] = None, - ) -> Dict: + ) -> dict: """Reloads a navigable. Parameters: @@ -576,9 +576,9 @@ def reload( def set_viewport( self, context: Optional[str] = None, - viewport: Optional[Dict] = None, + viewport: Optional[dict] = None, device_pixel_ratio: Optional[float] = None, - user_contexts: Optional[List[str]] = None, + user_contexts: Optional[list[str]] = None, ) -> None: """Modifies specific viewport characteristics on the given top-level traversable. @@ -605,7 +605,7 @@ def set_viewport( self.conn.execute(command_builder("browsingContext.setViewport", params)) - def traverse_history(self, context: str, delta: int) -> Dict: + def traverse_history(self, context: str, delta: int) -> dict: """Traverses the history of a given navigable by a delta. Parameters: @@ -665,7 +665,7 @@ def _callback(event_data): return callback_id - def add_event_handler(self, event: str, callback: callable, contexts: Optional[List[str]] = None) -> int: + def add_event_handler(self, event: str, callback: callable, contexts: Optional[list[str]] = None) -> int: """Add an event handler to the browsing context. Parameters: diff --git a/py/selenium/webdriver/common/bidi/cdp.py b/py/selenium/webdriver/common/bidi/cdp.py index 2d40ed9ddc66e..6ab3d3b012299 100644 --- a/py/selenium/webdriver/common/bidi/cdp.py +++ b/py/selenium/webdriver/common/bidi/cdp.py @@ -35,9 +35,9 @@ from contextlib import contextmanager from dataclasses import dataclass from typing import Any -from typing import AsyncGenerator -from typing import AsyncIterator -from typing import Generator +from collections.abc import AsyncGenerator +from collections.abc import AsyncIterator +from collections.abc import Generator from typing import Type from typing import TypeVar @@ -241,7 +241,7 @@ def listen(self, *event_types, buffer_size=10): return receiver @asynccontextmanager - async def wait_for(self, event_type: Type[T], buffer_size=10) -> AsyncGenerator[CmEventProxy, None]: + async def wait_for(self, event_type: type[T], buffer_size=10) -> AsyncGenerator[CmEventProxy, None]: """Wait for an event of the given type and return it. This is an async context manager, so you should open it inside diff --git a/py/selenium/webdriver/common/bidi/common.py b/py/selenium/webdriver/common/bidi/common.py index 38a4d7e31d3d5..a56ba2e5a9894 100644 --- a/py/selenium/webdriver/common/bidi/common.py +++ b/py/selenium/webdriver/common/bidi/common.py @@ -15,10 +15,8 @@ # specific language governing permissions and limitations # under the License. -from typing import Dict - -def command_builder(method: str, params: Dict = None) -> Dict: +def command_builder(method: str, params: dict = None) -> dict: """Build a command iterator to send to the BiDi protocol. Parameters: diff --git a/py/selenium/webdriver/common/bidi/log.py b/py/selenium/webdriver/common/bidi/log.py index 036ebd24a031f..290e209f1d235 100644 --- a/py/selenium/webdriver/common/bidi/log.py +++ b/py/selenium/webdriver/common/bidi/log.py @@ -16,7 +16,6 @@ # under the License. from dataclasses import dataclass -from typing import List class LogEntryAdded: @@ -36,7 +35,7 @@ class ConsoleLogEntry: text: str timestamp: str method: str - args: List[dict] + args: list[dict] type_: str @classmethod diff --git a/py/selenium/webdriver/common/bidi/storage.py b/py/selenium/webdriver/common/bidi/storage.py index 02211f05e68a3..620477aeae6da 100644 --- a/py/selenium/webdriver/common/bidi/storage.py +++ b/py/selenium/webdriver/common/bidi/storage.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import Dict, List, Optional, Union +from typing import Optional, Union from selenium.webdriver.common.bidi.common import command_builder @@ -38,7 +38,7 @@ def __init__(self, type: str, value: str): self.type = type self.value = value - def to_dict(self) -> Dict: + def to_dict(self) -> dict: """Converts the BytesValue to a dictionary. Returns: @@ -74,7 +74,7 @@ def __init__( self.expiry = expiry @classmethod - def from_dict(cls, data: Dict) -> "Cookie": + def from_dict(cls, data: dict) -> "Cookie": """Creates a Cookie instance from a dictionary. Parameters: @@ -125,7 +125,7 @@ def __init__( self.same_site = same_site self.expiry = expiry - def to_dict(self) -> Dict: + def to_dict(self) -> dict: """Converts the CookieFilter to a dictionary. Returns: @@ -162,7 +162,7 @@ def __init__(self, user_context: Optional[str] = None, source_origin: Optional[s self.source_origin = source_origin @classmethod - def from_dict(cls, data: Dict) -> "PartitionKey": + def from_dict(cls, data: dict) -> "PartitionKey": """Creates a PartitionKey instance from a dictionary. Parameters: @@ -186,7 +186,7 @@ def __init__(self, context: str): self.type = "context" self.context = context - def to_dict(self) -> Dict: + def to_dict(self) -> dict: """Converts the BrowsingContextPartitionDescriptor to a dictionary. Returns: @@ -204,7 +204,7 @@ def __init__(self, user_context: Optional[str] = None, source_origin: Optional[s self.user_context = user_context self.source_origin = source_origin - def to_dict(self) -> Dict: + def to_dict(self) -> dict: """Converts the StorageKeyPartitionDescriptor to a dictionary. Returns: @@ -242,7 +242,7 @@ def __init__( self.same_site = same_site self.expiry = expiry - def to_dict(self) -> Dict: + def to_dict(self) -> dict: """Converts the PartialCookie to a dictionary. Returns: @@ -270,12 +270,12 @@ def to_dict(self) -> Dict: class GetCookiesResult: """Represents the result of a getCookies command.""" - def __init__(self, cookies: List[Cookie], partition_key: PartitionKey): + def __init__(self, cookies: list[Cookie], partition_key: PartitionKey): self.cookies = cookies self.partition_key = partition_key @classmethod - def from_dict(cls, data: Dict) -> "GetCookiesResult": + def from_dict(cls, data: dict) -> "GetCookiesResult": """Creates a GetCookiesResult instance from a dictionary. Parameters: @@ -298,7 +298,7 @@ def __init__(self, partition_key: PartitionKey): self.partition_key = partition_key @classmethod - def from_dict(cls, data: Dict) -> "SetCookieResult": + def from_dict(cls, data: dict) -> "SetCookieResult": """Creates a SetCookieResult instance from a dictionary. Parameters: @@ -320,7 +320,7 @@ def __init__(self, partition_key: PartitionKey): self.partition_key = partition_key @classmethod - def from_dict(cls, data: Dict) -> "DeleteCookiesResult": + def from_dict(cls, data: dict) -> "DeleteCookiesResult": """Creates a DeleteCookiesResult instance from a dictionary. Parameters: diff --git a/py/selenium/webdriver/common/bidi/webextension.py b/py/selenium/webdriver/common/bidi/webextension.py index 2e42de34c3ce5..2b43a273f21c1 100644 --- a/py/selenium/webdriver/common/bidi/webextension.py +++ b/py/selenium/webdriver/common/bidi/webextension.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import Dict, Union +from typing import Union from selenium.webdriver.common.bidi.common import command_builder @@ -28,7 +28,7 @@ class WebExtension: def __init__(self, conn): self.conn = conn - def install(self, path=None, archive_path=None, base64_value=None) -> Dict: + def install(self, path=None, archive_path=None, base64_value=None) -> dict: """Installs a web extension in the remote end. You must provide exactly one of the parameters. @@ -57,7 +57,7 @@ def install(self, path=None, archive_path=None, base64_value=None) -> Dict: result = self.conn.execute(command_builder("webExtension.install", params)) return result - def uninstall(self, extension_id_or_result: Union[str, Dict]) -> None: + def uninstall(self, extension_id_or_result: Union[str, dict]) -> None: """Uninstalls a web extension from the remote end. Parameters: diff --git a/py/selenium/webdriver/common/by.py b/py/selenium/webdriver/common/by.py index 45d2c3eff6237..c26b6ea62db05 100644 --- a/py/selenium/webdriver/common/by.py +++ b/py/selenium/webdriver/common/by.py @@ -16,7 +16,7 @@ # under the License. """The By implementation.""" -from typing import Dict, Literal, Optional +from typing import Literal, Optional class By: @@ -82,7 +82,7 @@ class By: CLASS_NAME = "class name" CSS_SELECTOR = "css selector" - _custom_finders: Dict[str, str] = {} + _custom_finders: dict[str, str] = {} @classmethod def register_custom_finder(cls, name: str, strategy: str) -> None: diff --git a/py/selenium/webdriver/common/fedcm/dialog.py b/py/selenium/webdriver/common/fedcm/dialog.py index 86bca67c79fcf..cf5fe2d351f55 100644 --- a/py/selenium/webdriver/common/fedcm/dialog.py +++ b/py/selenium/webdriver/common/fedcm/dialog.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import List, Optional +from typing import Optional from .account import Account @@ -45,7 +45,7 @@ def subtitle(self) -> Optional[str]: result = self._driver.fedcm.subtitle return result.get("subtitle") if result else None - def get_accounts(self) -> List[Account]: + def get_accounts(self) -> list[Account]: """Gets the list of accounts shown in the dialog.""" accounts = self._driver.fedcm.account_list return [Account(account) for account in accounts] diff --git a/py/selenium/webdriver/common/log.py b/py/selenium/webdriver/common/log.py index c65f770dfff3f..8e041006dd912 100644 --- a/py/selenium/webdriver/common/log.py +++ b/py/selenium/webdriver/common/log.py @@ -17,9 +17,10 @@ import json import pkgutil +from collections.abc import AsyncGenerator from contextlib import asynccontextmanager from importlib import import_module -from typing import Any, AsyncGenerator, Dict, Optional +from typing import Any, Optional from selenium.webdriver.common.by import By @@ -53,7 +54,7 @@ def __init__(self, driver, bidi_session) -> None: self._mutation_listener_js = _mutation_listener_js_bytes.decode("utf8").strip() @asynccontextmanager - async def mutation_events(self) -> AsyncGenerator[Dict[str, Any], None]: + async def mutation_events(self) -> AsyncGenerator[dict[str, Any], None]: """Listen for mutation events and emit them as they are found. :Usage: @@ -82,7 +83,7 @@ async def mutation_events(self) -> AsyncGenerator[Dict[str, Any], None]: self.driver.pin_script(self._mutation_listener_js, script_key) self.driver.execute_script(f"return {self._mutation_listener_js}") - event: Dict[str, Any] = {} + event: dict[str, Any] = {} async with runtime.wait_for(self.devtools.runtime.BindingCalled) as evnt: yield event @@ -96,7 +97,7 @@ async def mutation_events(self) -> AsyncGenerator[Dict[str, Any], None]: event["old_value"] = payload["oldValue"] @asynccontextmanager - async def add_js_error_listener(self) -> AsyncGenerator[Dict[str, Any], None]: + async def add_js_error_listener(self) -> AsyncGenerator[dict[str, Any], None]: """Listen for JS errors and when the contextmanager exits check if there were JS Errors. @@ -120,7 +121,7 @@ async def add_js_error_listener(self) -> AsyncGenerator[Dict[str, Any], None]: js_exception.exception_details = exception.value.exception_details @asynccontextmanager - async def add_listener(self, event_type) -> AsyncGenerator[Dict[str, Any], None]: + async def add_listener(self, event_type) -> AsyncGenerator[dict[str, Any], None]: """Listen for certain events that are passed in. :Args: @@ -140,7 +141,7 @@ async def add_listener(self, event_type) -> AsyncGenerator[Dict[str, Any], None] await session.execute(self.devtools.page.enable()) session = self.cdp.get_session_context("runtime.enable") await session.execute(self.devtools.runtime.enable()) - console: Dict[str, Any] = {"message": None, "level": None} + console: dict[str, Any] = {"message": None, "level": None} async with session.wait_for(self.devtools.runtime.ConsoleAPICalled) as messages: yield console diff --git a/py/selenium/webdriver/common/options.py b/py/selenium/webdriver/common/options.py index 673cc4a140c69..67e5765645133 100644 --- a/py/selenium/webdriver/common/options.py +++ b/py/selenium/webdriver/common/options.py @@ -18,7 +18,7 @@ import warnings from abc import ABCMeta, abstractmethod from enum import Enum -from typing import List, Optional +from typing import Optional from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.common.proxy import Proxy @@ -474,7 +474,7 @@ class ArgOptions(BaseOptions): def __init__(self) -> None: super().__init__() - self._arguments: List[str] = [] + self._arguments: list[str] = [] @property def arguments(self): diff --git a/py/selenium/webdriver/common/print_page_options.py b/py/selenium/webdriver/common/print_page_options.py index 500b6cfc5ce75..8207583714d7b 100644 --- a/py/selenium/webdriver/common/print_page_options.py +++ b/py/selenium/webdriver/common/print_page_options.py @@ -16,7 +16,7 @@ # under the License. -from typing import TYPE_CHECKING, List, Optional, Type +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from typing import Literal, TypedDict @@ -40,13 +40,13 @@ class _PrintOpts(TypedDict, total=False): orientation: Orientation scale: float shrinkToFit: bool - pageRanges: List[str] + pageRanges: list[str] else: - from typing import Any, Dict + from typing import Any Orientation = str - _MarginOpts = _PageOpts = _PrintOpts = Dict[str, Any] + _MarginOpts = _PageOpts = _PrintOpts = dict[str, Any] class _PageSettingsDescriptor: @@ -121,7 +121,7 @@ def __set__(self, obj, value) -> None: class _ValidateTypeDescriptor: """Base Class Descriptor which validates type of any subclass attribute.""" - def __init__(self, name, expected_type: Type): + def __init__(self, name, expected_type: type): self.name = name self.expected_type = expected_type diff --git a/py/selenium/webdriver/common/selenium_manager.py b/py/selenium/webdriver/common/selenium_manager.py index 0e20de5373441..9caec37e10c7f 100644 --- a/py/selenium/webdriver/common/selenium_manager.py +++ b/py/selenium/webdriver/common/selenium_manager.py @@ -22,7 +22,7 @@ import sys import sysconfig from pathlib import Path -from typing import List, Optional +from typing import Optional from selenium.common import WebDriverException @@ -35,7 +35,7 @@ class SeleniumManager: This implementation is still in beta, and may change. """ - def binary_paths(self, args: List) -> dict: + def binary_paths(self, args: list) -> dict: """Determines the locations of the requested assets. :Args: @@ -102,7 +102,7 @@ def _get_binary() -> Path: return path @staticmethod - def _run(args: List[str]) -> dict: + def _run(args: list[str]) -> dict: """Executes the Selenium Manager Binary. :Args: @@ -131,7 +131,7 @@ def _run(args: List[str]) -> dict: return result @staticmethod - def _process_logs(log_items: List[dict]): + def _process_logs(log_items: list[dict]): for item in log_items: if item["level"] == "WARN": logger.warning(item["message"]) diff --git a/py/selenium/webdriver/common/service.py b/py/selenium/webdriver/common/service.py index b26d20c95cafa..e03adb6202f84 100644 --- a/py/selenium/webdriver/common/service.py +++ b/py/selenium/webdriver/common/service.py @@ -19,11 +19,12 @@ import os import subprocess from abc import ABC, abstractmethod +from collections.abc import Mapping from io import IOBase from platform import system from subprocess import PIPE from time import sleep -from typing import IO, Any, List, Mapping, Optional, Union, cast +from typing import IO, Any, Optional, Union, cast from urllib import request from urllib.error import URLError @@ -78,7 +79,7 @@ def service_url(self) -> str: return f"http://{utils.join_host_port('localhost', self.port)}" @abstractmethod - def command_line_args(self) -> List[str]: + def command_line_args(self) -> list[str]: """A List of program arguments (excluding the executable).""" raise NotImplementedError("This method needs to be implemented in a sub class") diff --git a/py/selenium/webdriver/common/timeouts.py b/py/selenium/webdriver/common/timeouts.py index baf6f4b5bc3b4..d10704557f8b2 100644 --- a/py/selenium/webdriver/common/timeouts.py +++ b/py/selenium/webdriver/common/timeouts.py @@ -26,9 +26,7 @@ class JSONTimeouts(TypedDict, total=False): script: int else: - from typing import Dict - - JSONTimeouts = Dict[str, int] + JSONTimeouts = dict[str, int] class _TimeoutsDescriptor: diff --git a/py/selenium/webdriver/common/utils.py b/py/selenium/webdriver/common/utils.py index 483fe415eca0f..b04e2b0e40c30 100644 --- a/py/selenium/webdriver/common/utils.py +++ b/py/selenium/webdriver/common/utils.py @@ -17,7 +17,8 @@ """The Utils methods.""" import socket -from typing import Iterable, List, Optional, Union +from collections.abc import Iterable +from typing import Optional, Union from selenium.types import AnyKey from selenium.webdriver.common.keys import Keys @@ -125,9 +126,9 @@ def is_url_connectable(port: Union[int, str]) -> bool: return False -def keys_to_typing(value: Iterable[AnyKey]) -> List[str]: +def keys_to_typing(value: Iterable[AnyKey]) -> list[str]: """Processes the values that will be typed in the element.""" - characters: List[str] = [] + characters: list[str] = [] for val in value: if isinstance(val, Keys): # Todo: Does this even work? diff --git a/py/selenium/webdriver/common/virtual_authenticator.py b/py/selenium/webdriver/common/virtual_authenticator.py index 631b619dc76d6..a434de83741df 100644 --- a/py/selenium/webdriver/common/virtual_authenticator.py +++ b/py/selenium/webdriver/common/virtual_authenticator.py @@ -18,7 +18,7 @@ import functools from base64 import urlsafe_b64decode, urlsafe_b64encode from enum import Enum -from typing import Any, Dict, Optional, Union +from typing import Any, Optional, Union class Protocol(str, Enum): @@ -64,7 +64,7 @@ def __init__( self.is_user_consenting: bool = is_user_consenting self.is_user_verified: bool = is_user_verified - def to_dict(self) -> Dict[str, Union[str, bool]]: + def to_dict(self) -> dict[str, Union[str, bool]]: return { "protocol": self.protocol, "transport": self.transport, @@ -162,7 +162,7 @@ def create_resident_credential( """ return cls(id, True, rp_id, user_handle, private_key, sign_count) - def to_dict(self) -> Dict[str, Any]: + def to_dict(self) -> dict[str, Any]: credential_data = { "credentialId": self.id, "isResidentCredential": self._is_resident_credential, @@ -177,7 +177,7 @@ def to_dict(self) -> Dict[str, Any]: return credential_data @classmethod - def from_dict(cls, data: Dict[str, Any]) -> "Credential": + def from_dict(cls, data: dict[str, Any]) -> "Credential": _id = urlsafe_b64decode(f"{data['credentialId']}==") is_resident_credential = bool(data["isResidentCredential"]) rp_id = data.get("rpId", None) diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index fcdb4f37d1dbf..7a152e58c6ca8 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -15,7 +15,8 @@ # specific language governing permissions and limitations # under the License. -from typing import List, Mapping, Optional +from collections.abc import Mapping +from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.chromium import service @@ -38,7 +39,7 @@ def __init__( executable_path: Optional[str] = None, port: int = 0, log_output: Optional[SubprocessStdAlias] = None, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, env: Optional[Mapping[str, str]] = None, driver_path_env_key: Optional[str] = None, **kwargs, diff --git a/py/selenium/webdriver/firefox/options.py b/py/selenium/webdriver/firefox/options.py index 0a2fb13031e62..931b6020d16fc 100644 --- a/py/selenium/webdriver/firefox/options.py +++ b/py/selenium/webdriver/firefox/options.py @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -from typing import Any, Dict, Optional, Union +from typing import Any, Optional, Union from typing_extensions import deprecated @@ -108,7 +108,7 @@ def to_capabilities(self) -> dict: # it will defer to geckodriver to find the system Firefox # and generate a fresh profile. caps = self._caps - opts: Dict[str, Any] = {} + opts: dict[str, Any] = {} if self._binary_location: opts["binary"] = self._binary_location diff --git a/py/selenium/webdriver/firefox/service.py b/py/selenium/webdriver/firefox/service.py index b957df8ed8b3b..55ff4c6ec89e9 100644 --- a/py/selenium/webdriver/firefox/service.py +++ b/py/selenium/webdriver/firefox/service.py @@ -14,7 +14,8 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -from typing import List, Mapping, Optional +from collections.abc import Mapping +from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service, utils @@ -36,7 +37,7 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, log_output: Optional[SubprocessStdAlias] = None, env: Optional[Mapping[str, str]] = None, driver_path_env_key: Optional[str] = None, @@ -59,5 +60,5 @@ def __init__( self.service_args.append("--websocket-port") self.service_args.append(f"{utils.free_port()}") - def command_line_args(self) -> List[str]: + def command_line_args(self) -> list[str]: return ["--port", f"{self.port}"] + self.service_args diff --git a/py/selenium/webdriver/ie/options.py b/py/selenium/webdriver/ie/options.py index 404bc1ad5aa48..0775acc7a9693 100644 --- a/py/selenium/webdriver/ie/options.py +++ b/py/selenium/webdriver/ie/options.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. from enum import Enum -from typing import Any, Dict +from typing import Any from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.options import ArgOptions @@ -363,8 +363,8 @@ class Options(ArgOptions): def __init__(self) -> None: super().__init__() - self._options: Dict[str, Any] = {} - self._additional: Dict[str, Any] = {} + self._options: dict[str, Any] = {} + self._additional: dict[str, Any] = {} @property def options(self) -> dict: diff --git a/py/selenium/webdriver/ie/service.py b/py/selenium/webdriver/ie/service.py index 083590c5751aa..3b1be6be13307 100644 --- a/py/selenium/webdriver/ie/service.py +++ b/py/selenium/webdriver/ie/service.py @@ -14,7 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -from typing import List, Optional +from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service @@ -28,7 +28,7 @@ def __init__( executable_path: Optional[str] = None, port: int = 0, host: Optional[str] = None, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, log_level: Optional[str] = None, log_output: Optional[SubprocessStdAlias] = None, driver_path_env_key: Optional[str] = None, @@ -61,5 +61,5 @@ def __init__( **kwargs, ) - def command_line_args(self) -> List[str]: + def command_line_args(self) -> list[str]: return [f"--port={self.port}"] + self.service_args diff --git a/py/selenium/webdriver/remote/errorhandler.py b/py/selenium/webdriver/remote/errorhandler.py index f734283292977..fbfc7696d3986 100644 --- a/py/selenium/webdriver/remote/errorhandler.py +++ b/py/selenium/webdriver/remote/errorhandler.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import Any, Dict, Type +from typing import Any from selenium.common.exceptions import ( DetachedShadowRootException, @@ -141,7 +141,7 @@ class ErrorCode: class ErrorHandler: """Handles errors returned by the WebDriver server.""" - def check_response(self, response: Dict[str, Any]) -> None: + def check_response(self, response: dict[str, Any]) -> None: """Checks that a JSON response from the WebDriver does not have an error. @@ -179,7 +179,7 @@ def check_response(self, response: Dict[str, Any]) -> None: except ValueError: pass - exception_class: Type[WebDriverException] + exception_class: type[WebDriverException] e = ErrorCode() error_codes = [item for item in dir(e) if not item.startswith("__")] for error_code in error_codes: diff --git a/py/selenium/webdriver/remote/fedcm.py b/py/selenium/webdriver/remote/fedcm.py index cf877789d3964..5c44009ea6878 100644 --- a/py/selenium/webdriver/remote/fedcm.py +++ b/py/selenium/webdriver/remote/fedcm.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import List, Optional +from typing import Optional from .command import Command @@ -40,7 +40,7 @@ def dialog_type(self) -> str: return self._driver.execute(Command.GET_FEDCM_DIALOG_TYPE).get("value") @property - def account_list(self) -> List[dict]: + def account_list(self) -> list[dict]: """Gets the list of accounts shown in the dialog.""" return self._driver.execute(Command.GET_FEDCM_ACCOUNT_LIST).get("value") diff --git a/py/selenium/webdriver/remote/webdriver.py b/py/selenium/webdriver/remote/webdriver.py index 14c8e6555f918..149f12d8fe1a0 100644 --- a/py/selenium/webdriver/remote/webdriver.py +++ b/py/selenium/webdriver/remote/webdriver.py @@ -30,7 +30,7 @@ from base64 import b64decode, urlsafe_b64encode from contextlib import asynccontextmanager, contextmanager from importlib import import_module -from typing import Any, Dict, List, Optional, Type, Union +from typing import Any, Optional, Union from selenium.common.exceptions import ( InvalidArgumentException, @@ -131,7 +131,7 @@ def get_remote_connection( ) -def create_matches(options: List[BaseOptions]) -> Dict: +def create_matches(options: list[BaseOptions]) -> dict: capabilities = {"capabilities": {}} opts = [] for opt in options: @@ -195,7 +195,7 @@ def __init__( command_executor: Union[str, RemoteConnection] = "http://127.0.0.1:4444", keep_alive: bool = True, file_detector: Optional[FileDetector] = None, - options: Optional[Union[BaseOptions, List[BaseOptions]]] = None, + options: Optional[Union[BaseOptions, list[BaseOptions]]] = None, locator_converter: Optional[LocatorConverter] = None, web_element_cls: Optional[type] = None, client_config: Optional[ClientConfig] = None, @@ -274,7 +274,7 @@ def __enter__(self): def __exit__( self, - exc_type: Optional[Type[BaseException]], + exc_type: Optional[type[BaseException]], exc: Optional[BaseException], traceback: Optional[types.TracebackType], ): @@ -506,7 +506,7 @@ def unpin(self, script_key: ScriptKey) -> None: except KeyError: raise KeyError(f"No script with key: {script_key} existed in {self.pinned_scripts}") from None - def get_pinned_scripts(self) -> List[str]: + def get_pinned_scripts(self) -> list[str]: """Return a list of all pinned scripts. Example: @@ -618,7 +618,7 @@ def current_window_handle(self) -> str: return self.execute(Command.W3C_GET_CURRENT_WINDOW_HANDLE)["value"] @property - def window_handles(self) -> List[str]: + def window_handles(self) -> list[str]: """Returns the handles of all windows within the current session. Example: @@ -716,7 +716,7 @@ def refresh(self) -> None: self.execute(Command.REFRESH) # Options - def get_cookies(self) -> List[dict]: + def get_cookies(self) -> list[dict]: """Returns a set of dictionaries, corresponding to cookies visible in the current session. @@ -730,7 +730,7 @@ def get_cookies(self) -> List[dict]: """ return self.execute(Command.GET_ALL_COOKIES)["value"] - def get_cookie(self, name) -> Optional[Dict]: + def get_cookie(self, name) -> Optional[dict]: """Get a single cookie by name. Raises ValueError if the name is empty or whitespace. Returns the cookie if found, None if not. @@ -913,7 +913,7 @@ def find_element(self, by=By.ID, value: Optional[str] = None) -> WebElement: return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"] - def find_elements(self, by=By.ID, value: Optional[str] = None) -> List[WebElement]: + def find_elements(self, by=By.ID, value: Optional[str] = None) -> list[WebElement]: """Find elements given a By strategy and locator. Parameters: @@ -1433,7 +1433,7 @@ def add_credential(self, credential: Credential) -> None: self.execute(Command.ADD_CREDENTIAL, {**credential.to_dict(), "authenticatorId": self._authenticator_id}) @required_virtual_authenticator - def get_credentials(self) -> List[Credential]: + def get_credentials(self) -> list[Credential]: """Returns the list of credentials owned by the authenticator. Example: diff --git a/py/selenium/webdriver/remote/webelement.py b/py/selenium/webdriver/remote/webelement.py index b6d085cb6932c..0e5754d82b314 100644 --- a/py/selenium/webdriver/remote/webelement.py +++ b/py/selenium/webdriver/remote/webelement.py @@ -24,7 +24,6 @@ from base64 import b64decode, encodebytes from hashlib import md5 as md5_hash from io import BytesIO -from typing import List from selenium.common.exceptions import JavascriptException, WebDriverException from selenium.webdriver.common.by import By @@ -602,7 +601,7 @@ def find_element(self, by=By.ID, value=None) -> WebElement: by, value = self._parent.locator_converter.convert(by, value) return self._execute(Command.FIND_CHILD_ELEMENT, {"using": by, "value": value})["value"] - def find_elements(self, by=By.ID, value=None) -> List[WebElement]: + def find_elements(self, by=By.ID, value=None) -> list[WebElement]: """Find elements given a By strategy and locator. Parameters: diff --git a/py/selenium/webdriver/safari/options.py b/py/selenium/webdriver/safari/options.py index f25535cead3fe..5a9ea25cfa4a0 100644 --- a/py/selenium/webdriver/safari/options.py +++ b/py/selenium/webdriver/safari/options.py @@ -14,7 +14,6 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -from typing import Dict from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.options import ArgOptions @@ -111,5 +110,5 @@ class Options(ArgOptions): """ @property - def default_capabilities(self) -> Dict[str, str]: + def default_capabilities(self) -> dict[str, str]: return DesiredCapabilities.SAFARI.copy() diff --git a/py/selenium/webdriver/safari/service.py b/py/selenium/webdriver/safari/service.py index d1ff0f86b4211..4d9f5a35e9774 100644 --- a/py/selenium/webdriver/safari/service.py +++ b/py/selenium/webdriver/safari/service.py @@ -16,7 +16,8 @@ # under the License. -from typing import List, Mapping, Optional +from collections.abc import Mapping +from typing import Optional from selenium.webdriver.common import service @@ -38,7 +39,7 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, env: Optional[Mapping[str, str]] = None, reuse_service=False, enable_logging: bool = False, @@ -60,7 +61,7 @@ def __init__( **kwargs, ) - def command_line_args(self) -> List[str]: + def command_line_args(self) -> list[str]: return ["-p", f"{self.port}"] + self.service_args @property diff --git a/py/selenium/webdriver/support/color.py b/py/selenium/webdriver/support/color.py index ae28371667e6a..f62f79d971d94 100644 --- a/py/selenium/webdriver/support/color.py +++ b/py/selenium/webdriver/support/color.py @@ -16,13 +16,9 @@ # under the License. from __future__ import annotations -import sys -from typing import TYPE_CHECKING, Any, Sequence - -if sys.version_info >= (3, 9): - from re import Match -else: - from typing import Match +from collections.abc import Sequence +from re import Match +from typing import TYPE_CHECKING, Any if TYPE_CHECKING: from typing import SupportsFloat, SupportsIndex, SupportsInt, Union diff --git a/py/selenium/webdriver/support/event_firing_webdriver.py b/py/selenium/webdriver/support/event_firing_webdriver.py index e79be65576640..888407e06c782 100644 --- a/py/selenium/webdriver/support/event_firing_webdriver.py +++ b/py/selenium/webdriver/support/event_firing_webdriver.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -from typing import Any, List, Tuple +from typing import Any from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.by import By @@ -108,10 +108,10 @@ def quit(self) -> None: def find_element(self, by=By.ID, value=None) -> WebElement: return self._dispatch("find", (by, value, self._driver), "find_element", (by, value)) - def find_elements(self, by=By.ID, value=None) -> List[WebElement]: + def find_elements(self, by=By.ID, value=None) -> list[WebElement]: return self._dispatch("find", (by, value, self._driver), "find_elements", (by, value)) - def _dispatch(self, l_call: str, l_args: Tuple[Any, ...], d_call: str, d_args: Tuple[Any, ...]): + def _dispatch(self, l_call: str, l_args: tuple[Any, ...], d_call: str, d_args: tuple[Any, ...]): getattr(self._listener, f"before_{l_call}")(*l_args) try: result = getattr(self._driver, d_call)(*d_args) @@ -190,7 +190,7 @@ def send_keys(self, *value) -> None: def find_element(self, by=By.ID, value=None) -> WebElement: return self._dispatch("find", (by, value, self._driver), "find_element", (by, value)) - def find_elements(self, by=By.ID, value=None) -> List[WebElement]: + def find_elements(self, by=By.ID, value=None) -> list[WebElement]: return self._dispatch("find", (by, value, self._driver), "find_elements", (by, value)) def _dispatch(self, l_call, l_args, d_call, d_args): diff --git a/py/selenium/webdriver/support/expected_conditions.py b/py/selenium/webdriver/support/expected_conditions.py index fb39aa9d72d31..06a5f36d9e7c6 100644 --- a/py/selenium/webdriver/support/expected_conditions.py +++ b/py/selenium/webdriver/support/expected_conditions.py @@ -17,7 +17,7 @@ import re from collections.abc import Iterable -from typing import Any, Callable, List, Literal, Tuple, TypeVar, Union +from typing import Any, Callable, Literal, TypeVar, Union from selenium.common.exceptions import ( NoAlertPresentException, @@ -79,7 +79,7 @@ def _predicate(driver: WebDriver): return _predicate -def presence_of_element_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], WebElement]: +def presence_of_element_located(locator: tuple[str, str]) -> Callable[[WebDriverOrWebElement], WebElement]: """An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible. @@ -189,7 +189,7 @@ def _predicate(driver: WebDriver): def visibility_of_element_located( - locator: Tuple[str, str], + locator: tuple[str, str], ) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]: """An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed @@ -272,7 +272,7 @@ def _element_if_visible(element: WebElement, visibility: bool = True) -> Union[L return element if element.is_displayed() == visibility else False -def presence_of_all_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]: +def presence_of_all_elements_located(locator: tuple[str, str]) -> Callable[[WebDriverOrWebElement], list[WebElement]]: """An expectation for checking that there is at least one element present on a web page. @@ -299,7 +299,7 @@ def _predicate(driver: WebDriverOrWebElement): return _predicate -def visibility_of_any_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]: +def visibility_of_any_elements_located(locator: tuple[str, str]) -> Callable[[WebDriverOrWebElement], list[WebElement]]: """An expectation for checking that there is at least one element visible on a web page. @@ -327,8 +327,8 @@ def _predicate(driver: WebDriverOrWebElement): def visibility_of_all_elements_located( - locator: Tuple[str, str], -) -> Callable[[WebDriverOrWebElement], Union[List[WebElement], Literal[False]]]: + locator: tuple[str, str], +) -> Callable[[WebDriverOrWebElement], Union[list[WebElement], Literal[False]]]: """An expectation for checking that all elements are present on the DOM of a page and visible. Visibility means that the elements are not only displayed but also has a height and width that is greater than 0. @@ -363,7 +363,7 @@ def _predicate(driver: WebDriverOrWebElement): return _predicate -def text_to_be_present_in_element(locator: Tuple[str, str], text_: str) -> Callable[[WebDriverOrWebElement], bool]: +def text_to_be_present_in_element(locator: tuple[str, str], text_: str) -> Callable[[WebDriverOrWebElement], bool]: """An expectation for checking if the given text is present in the specified element. @@ -399,7 +399,7 @@ def _predicate(driver: WebDriverOrWebElement): def text_to_be_present_in_element_value( - locator: Tuple[str, str], text_: str + locator: tuple[str, str], text_: str ) -> Callable[[WebDriverOrWebElement], bool]: """An expectation for checking if the given text is present in the element's value. @@ -436,7 +436,7 @@ def _predicate(driver: WebDriverOrWebElement): def text_to_be_present_in_element_attribute( - locator: Tuple[str, str], attribute_: str, text_: str + locator: tuple[str, str], attribute_: str, text_: str ) -> Callable[[WebDriverOrWebElement], bool]: """An expectation for checking if the given text is present in the element's attribute. @@ -477,7 +477,7 @@ def _predicate(driver: WebDriverOrWebElement): def frame_to_be_available_and_switch_to_it( - locator: Union[Tuple[str, str], str, WebElement], + locator: Union[tuple[str, str], str, WebElement], ) -> Callable[[WebDriver], bool]: """An expectation for checking whether the given frame is available to switch to. @@ -517,7 +517,7 @@ def _predicate(driver: WebDriver): def invisibility_of_element_located( - locator: Union[WebElement, Tuple[str, str]], + locator: Union[WebElement, tuple[str, str]], ) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]: """An Expectation for checking that an element is either invisible or not present on the DOM. @@ -565,7 +565,7 @@ def _predicate(driver: WebDriverOrWebElement): def invisibility_of_element( - element: Union[WebElement, Tuple[str, str]], + element: Union[WebElement, tuple[str, str]], ) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]: """An Expectation for checking that an element is either invisible or not present on the DOM. @@ -592,7 +592,7 @@ def invisibility_of_element( def element_to_be_clickable( - mark: Union[WebElement, Tuple[str, str]], + mark: Union[WebElement, tuple[str, str]], ) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]: """An Expectation for checking an element is visible and enabled such that you can click it. @@ -687,7 +687,7 @@ def _predicate(_): return _predicate -def element_located_to_be_selected(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], bool]: +def element_located_to_be_selected(locator: tuple[str, str]) -> Callable[[WebDriverOrWebElement], bool]: """An expectation for the element to be located is selected. Parameters: @@ -743,7 +743,7 @@ def _predicate(_): def element_located_selection_state_to_be( - locator: Tuple[str, str], is_selected: bool + locator: tuple[str, str], is_selected: bool ) -> Callable[[WebDriverOrWebElement], bool]: """An expectation to locate an element and check if the selection state specified is in that state. @@ -803,7 +803,7 @@ def _predicate(driver: WebDriver): return _predicate -def new_window_is_opened(current_handles: List[str]) -> Callable[[WebDriver], bool]: +def new_window_is_opened(current_handles: list[str]) -> Callable[[WebDriver], bool]: """An expectation that a new window will be opened and have the number of windows handles increase. @@ -858,7 +858,7 @@ def _predicate(driver: WebDriver): return _predicate -def element_attribute_to_include(locator: Tuple[str, str], attribute_: str) -> Callable[[WebDriverOrWebElement], bool]: +def element_attribute_to_include(locator: tuple[str, str], attribute_: str) -> Callable[[WebDriverOrWebElement], bool]: """An expectation for checking if the given attribute is included in the specified element. @@ -935,7 +935,7 @@ def any_of_condition(driver: D): def all_of( *expected_conditions: Callable[[D], Union[T, Literal[False]]], -) -> Callable[[D], Union[List[T], Literal[False]]]: +) -> Callable[[D], Union[list[T], Literal[False]]]: """An expectation that all of multiple expected conditions is true. Parameters: @@ -964,7 +964,7 @@ def all_of( """ def all_of_condition(driver: D): - results: List[T] = [] + results: list[T] = [] for expected_condition in expected_conditions: try: result = expected_condition(driver) diff --git a/py/selenium/webdriver/support/relative_locator.py b/py/selenium/webdriver/support/relative_locator.py index 53cd066c20b3f..5962ae128c874 100644 --- a/py/selenium/webdriver/support/relative_locator.py +++ b/py/selenium/webdriver/support/relative_locator.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. import warnings -from typing import Dict, List, NoReturn, Optional, Union, overload +from typing import NoReturn, Optional, Union, overload from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.by import By, ByType @@ -91,9 +91,9 @@ class RelativeBy: >>> assert "mid" in ids """ - LocatorType = Dict[ByType, str] + LocatorType = dict[ByType, str] - def __init__(self, root: Optional[Dict[ByType, str]] = None, filters: Optional[List] = None): + def __init__(self, root: Optional[dict[ByType, str]] = None, filters: Optional[list] = None): """Creates a new RelativeBy object. It is preferred if you use the `locate_with` method as this signature could change. @@ -149,7 +149,7 @@ def below(self, element_or_locator: Union[WebElement, LocatorType]) -> "Relative @overload def below(self, element_or_locator: None = None) -> "NoReturn": ... - def below(self, element_or_locator: Union[WebElement, Dict, None] = None) -> "RelativeBy": + def below(self, element_or_locator: Union[WebElement, dict, None] = None) -> "RelativeBy": """Add a filter to look for elements below. Parameters: @@ -183,7 +183,7 @@ def to_left_of(self, element_or_locator: Union[WebElement, LocatorType]) -> "Rel @overload def to_left_of(self, element_or_locator: None = None) -> "NoReturn": ... - def to_left_of(self, element_or_locator: Union[WebElement, Dict, None] = None) -> "RelativeBy": + def to_left_of(self, element_or_locator: Union[WebElement, dict, None] = None) -> "RelativeBy": """Add a filter to look for elements to the left of. Parameters: @@ -217,7 +217,7 @@ def to_right_of(self, element_or_locator: Union[WebElement, LocatorType]) -> "Re @overload def to_right_of(self, element_or_locator: None = None) -> "NoReturn": ... - def to_right_of(self, element_or_locator: Union[WebElement, Dict, None] = None) -> "RelativeBy": + def to_right_of(self, element_or_locator: Union[WebElement, dict, None] = None) -> "RelativeBy": """Add a filter to look for elements right of. Parameters: @@ -269,7 +269,7 @@ def straight_below(self, element_or_locator: Union[WebElement, LocatorType]) -> @overload def straight_below(self, element_or_locator: None = None) -> "NoReturn": ... - def straight_below(self, element_or_locator: Union[WebElement, Dict, None] = None) -> "RelativeBy": + def straight_below(self, element_or_locator: Union[WebElement, dict, None] = None) -> "RelativeBy": """Add a filter to look for elements below. :Args: @@ -287,7 +287,7 @@ def straight_left_of(self, element_or_locator: Union[WebElement, LocatorType]) - @overload def straight_left_of(self, element_or_locator: None = None) -> "NoReturn": ... - def straight_left_of(self, element_or_locator: Union[WebElement, Dict, None] = None) -> "RelativeBy": + def straight_left_of(self, element_or_locator: Union[WebElement, dict, None] = None) -> "RelativeBy": """Add a filter to look for elements to the left of. :Args: @@ -305,7 +305,7 @@ def straight_right_of(self, element_or_locator: Union[WebElement, LocatorType]) @overload def straight_right_of(self, element_or_locator: None = None) -> "NoReturn": ... - def straight_right_of(self, element_or_locator: Union[WebElement, Dict, None] = None) -> "RelativeBy": + def straight_right_of(self, element_or_locator: Union[WebElement, dict, None] = None) -> "RelativeBy": """Add a filter to look for elements right of. :Args: @@ -357,7 +357,7 @@ def near(self, element_or_locator: Union[WebElement, LocatorType, None] = None, self.filters.append({"kind": "near", "args": [element_or_locator, distance]}) return self - def to_dict(self) -> Dict: + def to_dict(self) -> dict: """Create a dict that will be passed to the driver to start searching for the element.""" return { diff --git a/py/selenium/webdriver/support/select.py b/py/selenium/webdriver/support/select.py index 4874fcac151e7..23140b2e60f08 100644 --- a/py/selenium/webdriver/support/select.py +++ b/py/selenium/webdriver/support/select.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import List from selenium.common.exceptions import NoSuchElementException, UnexpectedTagNameException from selenium.webdriver.common.by import By @@ -41,12 +40,12 @@ def __init__(self, webelement: WebElement) -> None: self.is_multiple = multi and multi != "false" @property - def options(self) -> List[WebElement]: + def options(self) -> list[WebElement]: """Returns a list of all options belonging to this select tag.""" return self._el.find_elements(By.TAG_NAME, "option") @property - def all_selected_options(self) -> List[WebElement]: + def all_selected_options(self) -> list[WebElement]: """Returns a list of all selected options belonging to this select tag.""" return [opt for opt in self.options if opt.is_selected()] diff --git a/py/selenium/webdriver/support/wait.py b/py/selenium/webdriver/support/wait.py index 19fcf60f05922..30c20fc862aa4 100644 --- a/py/selenium/webdriver/support/wait.py +++ b/py/selenium/webdriver/support/wait.py @@ -16,7 +16,7 @@ # under the License. import time -from typing import Callable, Generic, Literal, Optional, Tuple, Type, TypeVar, Union +from typing import Callable, Generic, Literal, Optional, TypeVar, Union from selenium.common.exceptions import NoSuchElementException, TimeoutException from selenium.types import WaitExcTypes @@ -24,7 +24,7 @@ from selenium.webdriver.remote.webelement import WebElement POLL_FREQUENCY: float = 0.5 # How long to sleep in between calls to the method -IGNORED_EXCEPTIONS: Tuple[Type[Exception]] = (NoSuchElementException,) # default to be ignored. +IGNORED_EXCEPTIONS: tuple[type[Exception]] = (NoSuchElementException,) # default to be ignored. D = TypeVar("D", bound=Union[WebDriver, WebElement]) T = TypeVar("T") diff --git a/py/selenium/webdriver/webkitgtk/service.py b/py/selenium/webdriver/webkitgtk/service.py index ed15cdf83ddda..e7f300019c838 100644 --- a/py/selenium/webdriver/webkitgtk/service.py +++ b/py/selenium/webdriver/webkitgtk/service.py @@ -16,7 +16,8 @@ # under the License. import shutil import warnings -from typing import List, Mapping, Optional +from collections.abc import Mapping +from typing import Optional from selenium.webdriver.common import service @@ -42,7 +43,7 @@ def __init__( port: int = 0, log_path: Optional[str] = None, log_output: Optional[str] = None, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, env: Optional[Mapping[str, str]] = None, **kwargs, ) -> None: @@ -59,5 +60,5 @@ def __init__( **kwargs, ) - def command_line_args(self) -> List[str]: + def command_line_args(self) -> list[str]: return ["-p", f"{self.port}"] + self.service_args diff --git a/py/selenium/webdriver/wpewebkit/options.py b/py/selenium/webdriver/wpewebkit/options.py index 5a9736c72d29e..23fc3349c4bc1 100644 --- a/py/selenium/webdriver/wpewebkit/options.py +++ b/py/selenium/webdriver/wpewebkit/options.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Dict from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.options import ArgOptions @@ -61,5 +60,5 @@ def to_capabilities(self): return caps @property - def default_capabilities(self) -> Dict[str, str]: + def default_capabilities(self) -> dict[str, str]: return DesiredCapabilities.WPEWEBKIT.copy() diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index 552438818b4a9..1f2b244807583 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -15,7 +15,8 @@ # specific language governing permissions and limitations # under the License. import shutil -from typing import List, Mapping, Optional +from collections.abc import Mapping +from typing import Optional from selenium.webdriver.common import service @@ -40,7 +41,7 @@ def __init__( executable_path: str = DEFAULT_EXECUTABLE_PATH, port: int = 0, log_output: Optional[str] = None, - service_args: Optional[List[str]] = None, + service_args: Optional[list[str]] = None, env: Optional[Mapping[str, str]] = None, **kwargs, ): @@ -53,5 +54,5 @@ def __init__( **kwargs, ) - def command_line_args(self) -> List[str]: + def command_line_args(self) -> list[str]: return ["-p", f"{self.port}"] + self.service_args diff --git a/py/test/selenium/webdriver/common/bidi_webextension_tests.py b/py/test/selenium/webdriver/common/bidi_webextension_tests.py index b487eb370336f..ac186cf89e980 100644 --- a/py/test/selenium/webdriver/common/bidi_webextension_tests.py +++ b/py/test/selenium/webdriver/common/bidi_webextension_tests.py @@ -17,13 +17,13 @@ import base64 import os -import pytest +import pytest from python.runfiles import Runfiles + from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait - EXTENSION_ID = "webextensions-selenium-example-v3@example.com" EXTENSION_PATH = "webextensions-selenium-example-signed" EXTENSION_ARCHIVE_PATH = "webextensions-selenium-example.xpi" diff --git a/py/test/selenium/webdriver/common/virtual_authenticator_tests.py b/py/test/selenium/webdriver/common/virtual_authenticator_tests.py index 79a7d21322a4d..9bdf5779a2294 100644 --- a/py/test/selenium/webdriver/common/virtual_authenticator_tests.py +++ b/py/test/selenium/webdriver/common/virtual_authenticator_tests.py @@ -16,7 +16,6 @@ # under the License. from base64 import b64decode, urlsafe_b64decode -from typing import List import pytest @@ -90,7 +89,7 @@ def create_rk_disabled_ctap2_authenticator(driver) -> WebDriver: return driver -def get_assertion_for(webdriver: WebDriver, credential_id: List[int]): +def get_assertion_for(webdriver: WebDriver, credential_id: list[int]): return webdriver.execute_async_script(GET_CREDENTIAL, credential_id) diff --git a/py/test/selenium/webdriver/remote/remote_downloads_tests.py b/py/test/selenium/webdriver/remote/remote_downloads_tests.py index 152e0f4383a2f..5238eb813ae97 100644 --- a/py/test/selenium/webdriver/remote/remote_downloads_tests.py +++ b/py/test/selenium/webdriver/remote/remote_downloads_tests.py @@ -44,7 +44,7 @@ def test_download_file(driver, pages): driver.download_file(text_file_name, target_directory) target_file = os.path.join(target_directory, text_file_name) - with open(target_file, "r") as file: + with open(target_file) as file: assert "Hello, World!" in file.read() diff --git a/py/test/unit/selenium/webdriver/virtual_authenticator/credentials_tests.py b/py/test/unit/selenium/webdriver/virtual_authenticator/credentials_tests.py index f46ea0dbd9c9e..e0a1d2ef37d77 100644 --- a/py/test/unit/selenium/webdriver/virtual_authenticator/credentials_tests.py +++ b/py/test/unit/selenium/webdriver/virtual_authenticator/credentials_tests.py @@ -16,7 +16,6 @@ # under the License. from base64 import urlsafe_b64decode, urlsafe_b64encode -from typing import Tuple import pytest @@ -45,7 +44,7 @@ @pytest.fixture() -def data() -> Tuple: +def data() -> tuple: _id = bytearray({1, 2, 3, 4}) rp_id = "localhost" user_handle = bytearray({1})