diff --git a/py/generate.py b/py/generate.py index ec8edc82bd0b2..c746364a256ae 100644 --- a/py/generate.py +++ b/py/generate.py @@ -23,7 +23,6 @@ # This is a copy of https://github.com/HyperionGray/python-chrome-devtools-protocol/blob/master/generator/generate.py # The license above is theirs and MUST be preserved. -# flake8: noqa import builtins from dataclasses import dataclass @@ -36,7 +35,9 @@ from pathlib import Path import re from textwrap import dedent, indent as tw_indent -from typing import Optional , cast, List, Union, Iterator +from typing import Optional, cast, List, Union + +from collections.abc import Iterator import inflection # type: ignore @@ -206,11 +207,11 @@ def from_json(cls, type): class CdpProperty: ''' A property belonging to a non-primitive CDP type. ''' name: str - description: Optional[str] - type: Optional[str] - ref: Optional[str] - enum: List[str] - items: Optional[CdpItems] + description: str | None + type: str | None + ref: str | None + enum: list[str] + items: CdpItems | None optional: bool experimental: bool deprecated: bool @@ -316,11 +317,11 @@ def generate_from_json(self, dict_): class CdpType: ''' A top-level CDP type. ''' id: str - description: Optional[str] + description: str | None type: str - items: Optional[CdpItems] - enum: List[str] - properties: List[CdpProperty] + items: CdpItems | None + enum: list[str] + properties: list[CdpProperty] @classmethod def from_json(cls, type_): @@ -585,8 +586,8 @@ class CdpCommand: description: str experimental: bool deprecated: bool - parameters: List[CdpParameter] - returns: List[CdpReturn] + parameters: list[CdpParameter] + returns: list[CdpReturn] domain: str @property @@ -712,10 +713,10 @@ def get_refs(self): class CdpEvent: ''' A CDP event object. ''' name: str - description: Optional[str] + description: str | None deprecated: bool experimental: bool - parameters: List[CdpParameter] + parameters: list[CdpParameter] domain: str @property @@ -786,12 +787,12 @@ def get_refs(self): class CdpDomain: ''' A CDP domain contains metadata, types, commands, and events. ''' domain: str - description: Optional[str] + description: str | None experimental: bool - dependencies: List[str] - types: List[CdpType] - commands: List[CdpCommand] - events: List[CdpEvent] + dependencies: list[str] + types: list[CdpType] + commands: list[CdpCommand] + events: list[CdpEvent] @property def module(self) -> str: diff --git a/py/selenium/common/exceptions.py b/py/selenium/common/exceptions.py index 3ff4e0b4fd549..c45f530002a8f 100644 --- a/py/selenium/common/exceptions.py +++ b/py/selenium/common/exceptions.py @@ -17,7 +17,7 @@ """Exceptions that may happen in all the webdriver code.""" from collections.abc import Sequence -from typing import Any, Optional +from typing import Any SUPPORT_MSG = "For documentation on this error, please visit:" ERROR_URL = "https://www.selenium.dev/documentation/webdriver/troubleshooting/errors" @@ -27,7 +27,7 @@ class WebDriverException(Exception): """Base webdriver exception.""" def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: super().__init__() self.msg = msg @@ -73,7 +73,7 @@ class NoSuchElementException(WebDriverException): """ def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#nosuchelementexception" @@ -111,7 +111,7 @@ class StaleElementReferenceException(WebDriverException): """ def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#staleelementreferenceexception" @@ -134,10 +134,10 @@ class UnexpectedAlertPresentException(WebDriverException): def __init__( self, - msg: Optional[Any] = None, - screen: Optional[str] = None, - stacktrace: Optional[Sequence[str]] = None, - alert_text: Optional[str] = None, + msg: Any | None = None, + screen: str | None = None, + stacktrace: Sequence[str] | None = None, + alert_text: str | None = None, ) -> None: super().__init__(msg, screen, stacktrace) self.alert_text = alert_text @@ -161,7 +161,7 @@ class ElementNotVisibleException(InvalidElementStateException): """ def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#elementnotvisibleexception" @@ -172,7 +172,7 @@ class ElementNotInteractableException(InvalidElementStateException): """Thrown when element interactions will hit another element due to paint order.""" def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#elementnotinteractableexception" @@ -213,7 +213,7 @@ class InvalidSelectorException(WebDriverException): """ def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#invalidselectorexception" @@ -252,7 +252,7 @@ class ElementClickInterceptedException(WebDriverException): """Thrown when element click fails because another element obscures it.""" def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#elementclickinterceptedexception" @@ -271,7 +271,7 @@ class InvalidSessionIdException(WebDriverException): """Thrown when the given session id is not in the list of active sessions.""" def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#invalidsessionidexception" @@ -282,7 +282,7 @@ class SessionNotCreatedException(WebDriverException): """A new session could not be created.""" def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}#sessionnotcreatedexception" @@ -297,7 +297,7 @@ class NoSuchDriverException(WebDriverException): """Raised when driver is not specified and cannot be located.""" def __init__( - self, msg: Optional[Any] = None, screen: Optional[str] = None, stacktrace: Optional[Sequence[str]] = None + self, msg: Any | None = None, screen: str | None = None, stacktrace: Sequence[str] | None = None ) -> None: with_support = f"{msg}; {SUPPORT_MSG} {ERROR_URL}/driver_location" diff --git a/py/selenium/webdriver/chrome/options.py b/py/selenium/webdriver/chrome/options.py index c03651075d170..6ef6e5e839c21 100644 --- a/py/selenium/webdriver/chrome/options.py +++ b/py/selenium/webdriver/chrome/options.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.chromium.options import ChromiumOptions from selenium.webdriver.common.desired_capabilities import DesiredCapabilities @@ -28,8 +27,8 @@ def default_capabilities(self) -> dict: def enable_mobile( self, - android_package: Optional[str] = "com.android.chrome", - android_activity: Optional[str] = None, - device_serial: Optional[str] = None, + android_package: str | None = "com.android.chrome", + android_activity: str | None = None, + device_serial: str | None = None, ) -> None: super().enable_mobile(android_package, android_activity, device_serial) diff --git a/py/selenium/webdriver/chrome/remote_connection.py b/py/selenium/webdriver/chrome/remote_connection.py index 1aa34dbfa4b31..b8794b2208495 100644 --- a/py/selenium/webdriver/chrome/remote_connection.py +++ b/py/selenium/webdriver/chrome/remote_connection.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver import DesiredCapabilities from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection @@ -29,8 +28,8 @@ def __init__( self, remote_server_addr: str, keep_alive: bool = True, - ignore_proxy: Optional[bool] = False, - client_config: Optional[ClientConfig] = None, + ignore_proxy: bool | None = False, + client_config: ClientConfig | None = None, ) -> None: super().__init__( remote_server_addr=remote_server_addr, diff --git a/py/selenium/webdriver/chrome/service.py b/py/selenium/webdriver/chrome/service.py index 38f483d8acea8..a15b161bf7cc4 100644 --- a/py/selenium/webdriver/chrome/service.py +++ b/py/selenium/webdriver/chrome/service.py @@ -17,7 +17,6 @@ from collections.abc import Mapping, Sequence -from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.chromium import service @@ -41,11 +40,11 @@ class Service(service.ChromiumService): def __init__( self, - executable_path: Optional[str] = None, + executable_path: str | None = None, port: int = 0, - service_args: Optional[Sequence[str]] = None, - log_output: Optional[SubprocessStdAlias] = None, - env: Optional[Mapping[str, str]] = None, + service_args: Sequence[str] | None = None, + log_output: SubprocessStdAlias | None = None, + env: Mapping[str, str] | None = None, **kwargs, ) -> None: self._service_args = service_args or [] diff --git a/py/selenium/webdriver/chrome/webdriver.py b/py/selenium/webdriver/chrome/webdriver.py index 44882bcf4cae0..747656fdb69fc 100644 --- a/py/selenium/webdriver/chrome/webdriver.py +++ b/py/selenium/webdriver/chrome/webdriver.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service @@ -28,8 +27,8 @@ class WebDriver(ChromiumDriver): def __init__( self, - options: Optional[Options] = None, - service: Optional[Service] = None, + options: Options | None = None, + service: Service | None = None, keep_alive: bool = True, ) -> None: """Creates a new instance of the chrome driver. diff --git a/py/selenium/webdriver/chromium/options.py b/py/selenium/webdriver/chromium/options.py index 92363410a46b3..52f6a4b58600e 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, Optional, Union +from typing import BinaryIO from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.options import ArgOptions @@ -32,8 +32,8 @@ def __init__(self) -> None: 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._debugger_address: Optional[str] = None + self._experimental_options: dict[str, str | int | dict | list[str]] = {} + self._debugger_address: str | None = None self._enable_webextensions: bool = False @property @@ -53,7 +53,7 @@ def binary_location(self, value: str) -> None: self._binary_location = value @property - def debugger_address(self) -> Optional[str]: + def debugger_address(self) -> str | None: """Returns the address of the remote devtools instance.""" return self._debugger_address @@ -116,7 +116,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: str | int | dict | list[str]) -> None: """Adds an experimental option which is passed to chromium. Args: diff --git a/py/selenium/webdriver/chromium/remote_connection.py b/py/selenium/webdriver/chromium/remote_connection.py index ea532cba8ddcd..8690f9581d3ed 100644 --- a/py/selenium/webdriver/chromium/remote_connection.py +++ b/py/selenium/webdriver/chromium/remote_connection.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 Optional from selenium.webdriver.remote.client_config import ClientConfig from selenium.webdriver.remote.remote_connection import RemoteConnection @@ -27,8 +26,8 @@ def __init__( vendor_prefix: str, browser_name: str, keep_alive: bool = True, - ignore_proxy: Optional[bool] = False, - client_config: Optional[ClientConfig] = None, + ignore_proxy: bool | None = False, + client_config: ClientConfig | None = None, ) -> None: client_config = client_config or ClientConfig( remote_server_addr=remote_server_addr, keep_alive=keep_alive, timeout=120 diff --git a/py/selenium/webdriver/chromium/service.py b/py/selenium/webdriver/chromium/service.py index cd4394c0667d8..5aed283b683aa 100644 --- a/py/selenium/webdriver/chromium/service.py +++ b/py/selenium/webdriver/chromium/service.py @@ -17,7 +17,6 @@ from collections.abc import Mapping, Sequence from io import IOBase -from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service @@ -42,12 +41,12 @@ class ChromiumService(service.Service): def __init__( self, - executable_path: Optional[str] = None, + executable_path: str | None = None, port: int = 0, - service_args: Optional[Sequence[str]] = None, - log_output: Optional[SubprocessStdAlias] = None, - env: Optional[Mapping[str, str]] = None, - driver_path_env_key: Optional[str] = None, + service_args: Sequence[str] | None = None, + log_output: SubprocessStdAlias | None = None, + env: Mapping[str, str] | None = None, + driver_path_env_key: str | None = None, **kwargs, ) -> None: self._service_args = list(service_args or []) @@ -55,7 +54,7 @@ def __init__( if isinstance(log_output, str): self._service_args.append(f"--log-path={log_output}") - self.log_output: Optional[IOBase] = None + self.log_output: IOBase | None = None elif isinstance(log_output, IOBase): self.log_output = log_output else: diff --git a/py/selenium/webdriver/chromium/webdriver.py b/py/selenium/webdriver/chromium/webdriver.py index 894e26df3e97b..484fa132ad74d 100644 --- a/py/selenium/webdriver/chromium/webdriver.py +++ b/py/selenium/webdriver/chromium/webdriver.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.chromium.options import ChromiumOptions from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection @@ -30,10 +29,10 @@ class ChromiumDriver(RemoteWebDriver): def __init__( self, - browser_name: Optional[str] = None, - vendor_prefix: Optional[str] = None, - options: Optional[ChromiumOptions] = None, - service: Optional[ChromiumService] = None, + browser_name: str | None = None, + vendor_prefix: str | None = None, + options: ChromiumOptions | None = None, + service: ChromiumService | None = None, keep_alive: bool = True, ) -> None: """Create a new WebDriver instance, start the service, and create new ChromiumDriver instance. diff --git a/py/selenium/webdriver/common/actions/action_builder.py b/py/selenium/webdriver/common/actions/action_builder.py index e4f923976c7dd..e2787b5006383 100644 --- a/py/selenium/webdriver/common/actions/action_builder.py +++ b/py/selenium/webdriver/common/actions/action_builder.py @@ -16,7 +16,7 @@ # under the License. -from typing import Any, Optional, Union +from typing import Any, Union from selenium.webdriver.common.actions import interaction from selenium.webdriver.common.actions.key_actions import KeyActions @@ -32,21 +32,21 @@ class ActionBuilder: def __init__( self, driver, - mouse: Optional[PointerInput] = None, - wheel: Optional[WheelInput] = None, - keyboard: Optional[KeyInput] = None, + mouse: PointerInput | None = None, + wheel: WheelInput | None = None, + keyboard: KeyInput | None = None, duration: int = 250, ) -> None: mouse = mouse or PointerInput(interaction.POINTER_MOUSE, "mouse") keyboard = keyboard or KeyInput(interaction.KEY) wheel = wheel or WheelInput(interaction.WHEEL) - self.devices: list[Union[PointerInput, KeyInput, WheelInput]] = [mouse, keyboard, wheel] + self.devices: list[PointerInput | KeyInput | WheelInput] = [mouse, keyboard, wheel] self._key_action = KeyActions(keyboard) self._pointer_action = PointerActions(mouse, duration=duration) self._wheel_action = WheelActions(wheel) self.driver = driver - def get_device_with(self, name: str) -> Optional[Union["WheelInput", "PointerInput", "KeyInput"]]: + def get_device_with(self, name: str) -> Union["WheelInput", "PointerInput", "KeyInput"] | None: """Get the device with the given name. Args: @@ -159,7 +159,7 @@ def clear_actions(self) -> None: """ self.driver.execute(Command.W3C_CLEAR_ACTIONS) - def _add_input(self, new_input: Union[KeyInput, PointerInput, WheelInput]) -> None: + def _add_input(self, new_input: KeyInput | PointerInput | WheelInput) -> None: """Add a new input device to the action builder. Args: diff --git a/py/selenium/webdriver/common/actions/input_device.py b/py/selenium/webdriver/common/actions/input_device.py index 2cb97f8036e34..06ad2991c8b90 100644 --- a/py/selenium/webdriver/common/actions/input_device.py +++ b/py/selenium/webdriver/common/actions/input_device.py @@ -16,13 +16,13 @@ # under the License. import uuid -from typing import Any, Optional +from typing import Any class InputDevice: """Describes the input device being used for the action.""" - def __init__(self, name: Optional[str] = None): + def __init__(self, name: str | None = None): self.name = name or uuid.uuid4() self.actions: list[Any] = [] diff --git a/py/selenium/webdriver/common/actions/interaction.py b/py/selenium/webdriver/common/actions/interaction.py index 3118c5fe0a586..70d9d4adc897c 100644 --- a/py/selenium/webdriver/common/actions/interaction.py +++ b/py/selenium/webdriver/common/actions/interaction.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 Union from selenium.webdriver.common.actions.input_device import InputDevice @@ -43,5 +42,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, str | int]: return {"type": self.PAUSE, "duration": int(self.duration * 1000)} diff --git a/py/selenium/webdriver/common/actions/pointer_actions.py b/py/selenium/webdriver/common/actions/pointer_actions.py index 28186f767d9d8..73503bf91da49 100644 --- a/py/selenium/webdriver/common/actions/pointer_actions.py +++ b/py/selenium/webdriver/common/actions/pointer_actions.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 Optional from selenium.webdriver.common.actions import interaction from selenium.webdriver.common.actions.interaction import Interaction @@ -24,7 +23,7 @@ class PointerActions(Interaction): - def __init__(self, source: Optional[PointerInput] = None, duration: int = 250): + def __init__(self, source: PointerInput | None = None, duration: int = 250): """Initialize a new PointerActions instance. Args: @@ -168,17 +167,17 @@ def move_to_location( ) return self - def click(self, element: Optional[WebElement] = None, button=MouseButton.LEFT): + def click(self, element: WebElement | None = None, button=MouseButton.LEFT): if element: self.move_to(element) self.pointer_down(button) self.pointer_up(button) return self - def context_click(self, element: Optional[WebElement] = None): + def context_click(self, element: WebElement | None = None): return self.click(element=element, button=MouseButton.RIGHT) - def click_and_hold(self, element: Optional[WebElement] = None, button=MouseButton.LEFT): + def click_and_hold(self, element: WebElement | None = None, button=MouseButton.LEFT): if element: self.move_to(element) self.pointer_down(button=button) @@ -188,7 +187,7 @@ def release(self, button=MouseButton.LEFT): self.pointer_up(button=button) return self - def double_click(self, element: Optional[WebElement] = None): + def double_click(self, element: WebElement | None = None): if element: self.move_to(element) self.pointer_down(MouseButton.LEFT) diff --git a/py/selenium/webdriver/common/actions/pointer_input.py b/py/selenium/webdriver/common/actions/pointer_input.py index 661b126ffd7f4..448b2c6b18390 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, Optional, Union +from typing import Any from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.common.actions.input_device import InputDevice @@ -39,7 +39,7 @@ def create_pointer_move( duration=DEFAULT_MOVE_DURATION, x: float = 0, y: float = 0, - origin: Optional[WebElement] = None, + origin: WebElement | None = None, **kwargs, ): action = {"type": "pointerMove", "duration": duration, "x": x, "y": y, **kwargs} @@ -59,7 +59,7 @@ def create_pointer_up(self, button): def create_pointer_cancel(self): self.add_action({"type": "pointerCancel"}) - def create_pause(self, pause_duration: Union[int, float] = 0) -> None: + def create_pause(self, pause_duration: int | float = 0) -> None: self.add_action({"type": "pause", "duration": int(pause_duration * 1000)}) def encode(self): diff --git a/py/selenium/webdriver/common/actions/wheel_actions.py b/py/selenium/webdriver/common/actions/wheel_actions.py index cfb47141087c5..8fbdbd610f00b 100644 --- a/py/selenium/webdriver/common/actions/wheel_actions.py +++ b/py/selenium/webdriver/common/actions/wheel_actions.py @@ -15,14 +15,13 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.common.actions.interaction import WHEEL, Interaction from selenium.webdriver.common.actions.wheel_input import WheelInput class WheelActions(Interaction): - def __init__(self, source: Optional[WheelInput] = None): + def __init__(self, source: WheelInput | None = None): if source is None: source = WheelInput(WHEEL) super().__init__(source) diff --git a/py/selenium/webdriver/common/actions/wheel_input.py b/py/selenium/webdriver/common/actions/wheel_input.py index e9ce59a203a73..7ae17d3fabb6a 100644 --- a/py/selenium/webdriver/common/actions/wheel_input.py +++ b/py/selenium/webdriver/common/actions/wheel_input.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 Union from selenium.webdriver.common.actions import interaction from selenium.webdriver.common.actions.input_device import InputDevice @@ -22,7 +21,7 @@ class ScrollOrigin: - def __init__(self, origin: Union[str, WebElement], x_offset: int, y_offset: int) -> None: + def __init__(self, origin: str | WebElement, x_offset: int, y_offset: int) -> None: self._origin = origin self._x_offset = x_offset self._y_offset = y_offset @@ -36,7 +35,7 @@ def from_viewport(cls, x_offset: int = 0, y_offset: int = 0): return cls("viewport", x_offset, y_offset) @property - def origin(self) -> Union[str, WebElement]: + def origin(self) -> str | WebElement: return self._origin @property @@ -72,5 +71,5 @@ def create_scroll(self, x: int, y: int, delta_x: int, delta_y: int, duration: in } ) - def create_pause(self, pause_duration: Union[int, float] = 0) -> None: + def create_pause(self, pause_duration: int | float = 0) -> None: self.add_action({"type": "pause", "duration": int(pause_duration * 1000)}) diff --git a/py/selenium/webdriver/common/bidi/browser.py b/py/selenium/webdriver/common/bidi/browser.py index f597332563a14..5b449ae69276a 100644 --- a/py/selenium/webdriver/common/bidi/browser.py +++ b/py/selenium/webdriver/common/bidi/browser.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. import os -from typing import Any, Optional +from typing import Any from selenium.webdriver.common.bidi.common import command_builder from selenium.webdriver.common.bidi.session import UserPromptHandler @@ -175,9 +175,9 @@ def __init__(self, conn): def create_user_context( self, - accept_insecure_certs: Optional[bool] = None, - proxy: Optional[Proxy] = None, - unhandled_prompt_behavior: Optional[UserPromptHandler] = None, + accept_insecure_certs: bool | None = None, + proxy: Proxy | None = None, + unhandled_prompt_behavior: UserPromptHandler | None = None, ) -> str: """Creates a new user context. @@ -239,9 +239,9 @@ def get_client_windows(self) -> list[ClientWindowInfo]: def set_download_behavior( self, *, - allowed: Optional[bool] = None, - destination_folder: Optional[str | os.PathLike] = None, - user_contexts: Optional[list[str]] = None, + allowed: bool | None = None, + destination_folder: str | os.PathLike | None = None, + user_contexts: list[str] | None = None, ) -> None: """Set the download behavior for the browser or specific user contexts. diff --git a/py/selenium/webdriver/common/bidi/browsing_context.py b/py/selenium/webdriver/common/bidi/browsing_context.py index 132c9d65e9243..403e10b87d539 100644 --- a/py/selenium/webdriver/common/bidi/browsing_context.py +++ b/py/selenium/webdriver/common/bidi/browsing_context.py @@ -16,8 +16,9 @@ # under the License. import threading +from collections.abc import Callable from dataclasses import dataclass -from typing import Any, Callable, Optional, Union +from typing import Any from selenium.webdriver.common.bidi.common import command_builder from selenium.webdriver.common.bidi.session import Session @@ -46,7 +47,7 @@ class NavigationInfo: def __init__( self, context: str, - navigation: Optional[str], + navigation: str | None, timestamp: int, url: str, ): @@ -91,11 +92,11 @@ def __init__( self, context: str, url: str, - children: Optional[list["BrowsingContextInfo"]], + children: list["BrowsingContextInfo"] | None, client_window: str, user_context: str, - parent: Optional[str] = None, - original_opener: Optional[str] = None, + parent: str | None = None, + original_opener: str | None = None, ): self.context = context self.url = url @@ -168,7 +169,7 @@ class DownloadWillBeginParams(NavigationInfo): def __init__( self, context: str, - navigation: Optional[str], + navigation: str | None, timestamp: int, url: str, suggested_filename: str, @@ -202,7 +203,7 @@ def __init__( handler: str, message: str, type: str, - default_value: Optional[str] = None, + default_value: str | None = None, ): self.context = context self.handler = handler @@ -257,7 +258,7 @@ def __init__( context: str, accepted: bool, type: str, - user_text: Optional[str] = None, + user_text: str | None = None, ): self.context = context self.accepted = accepted @@ -344,7 +345,7 @@ class DownloadCanceledParams(NavigationInfo): def __init__( self, context: str, - navigation: Optional[str], + navigation: str | None, timestamp: int, url: str, status: str = "canceled", @@ -373,11 +374,11 @@ class DownloadCompleteParams(NavigationInfo): def __init__( self, context: str, - navigation: Optional[str], + navigation: str | None, timestamp: int, url: str, status: str = "complete", - filepath: Optional[str] = None, + filepath: str | None = None, ): super().__init__(context, navigation, timestamp, url) self.status = status @@ -410,7 +411,7 @@ class DownloadEndParams: def __init__( self, - download_params: Union[DownloadCanceledParams, DownloadCompleteParams], + download_params: DownloadCanceledParams | DownloadCompleteParams, ): self.download_params = download_params @@ -608,7 +609,7 @@ def validate_event(self, event: str) -> EventConfig: raise ValueError(f"Event '{event}' not found. Available events: {self._available_events}") return event_config - def subscribe_to_event(self, bidi_event: str, contexts: Optional[list[str]] = None) -> None: + def subscribe_to_event(self, bidi_event: str, contexts: list[str] | None = None) -> None: """Subscribe to a BiDi event if not already subscribed. Args: @@ -644,7 +645,7 @@ def remove_callback_from_tracking(self, bidi_event: str, callback_id: int) -> No if callback_list and callback_id in callback_list: callback_list.remove(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: list[str] | None = None) -> int: event_config = self.validate_event(event) callback_id = self.conn.add_callback(event_config.event_class, callback) @@ -742,8 +743,8 @@ def capture_screenshot( self, context: str, origin: str = "viewport", - format: Optional[dict] = None, - clip: Optional[dict] = None, + format: dict | None = None, + clip: dict | None = None, ) -> str: """Captures an image of the given navigable, and returns it as a Base64-encoded string. @@ -781,9 +782,9 @@ def close(self, context: str, prompt_unload: bool = False) -> None: def create( self, type: str, - reference_context: Optional[str] = None, + reference_context: str | None = None, background: bool = False, - user_context: Optional[str] = None, + user_context: str | None = None, ) -> str: """Creates a new navigable, either in a new tab or in a new window, and returns its navigable id. @@ -809,8 +810,8 @@ def create( def get_tree( self, - max_depth: Optional[int] = None, - root: Optional[str] = None, + max_depth: int | None = None, + root: str | None = None, ) -> list[BrowsingContextInfo]: """Get a tree of all descendent navigables including the given parent itself. @@ -836,8 +837,8 @@ def get_tree( def handle_user_prompt( self, context: str, - accept: Optional[bool] = None, - user_text: Optional[str] = None, + accept: bool | None = None, + user_text: str | None = None, ) -> None: """Allows closing an open prompt. @@ -858,9 +859,9 @@ def locate_nodes( self, context: str, locator: dict, - max_node_count: Optional[int] = None, - serialization_options: Optional[dict] = None, - start_nodes: Optional[list[dict]] = None, + max_node_count: int | None = None, + serialization_options: dict | None = None, + start_nodes: list[dict] | None = None, ) -> list[dict]: """Returns a list of all nodes matching the specified locator. @@ -889,7 +890,7 @@ def navigate( self, context: str, url: str, - wait: Optional[str] = None, + wait: str | None = None, ) -> dict: """Navigates a navigable to the given URL. @@ -912,10 +913,10 @@ def print( self, context: str, background: bool = False, - margin: Optional[dict] = None, + margin: dict | None = None, orientation: str = "portrait", - page: Optional[dict] = None, - page_ranges: Optional[list[Union[int, str]]] = None, + page: dict | None = None, + page_ranges: list[int | str] | None = None, scale: float = 1.0, shrink_to_fit: bool = True, ) -> str: @@ -954,8 +955,8 @@ def print( def reload( self, context: str, - ignore_cache: Optional[bool] = None, - wait: Optional[str] = None, + ignore_cache: bool | None = None, + wait: str | None = None, ) -> dict: """Reloads a navigable. @@ -978,10 +979,10 @@ def reload( def set_viewport( self, - context: Optional[str] = None, - viewport: Optional[dict] = None, - device_pixel_ratio: Optional[float] = None, - user_contexts: Optional[list[str]] = None, + context: str | None = None, + viewport: dict | None = None, + device_pixel_ratio: float | None = None, + user_contexts: list[str] | None = None, ) -> None: """Modifies specific viewport characteristics on the given top-level traversable. @@ -1020,7 +1021,7 @@ def traverse_history(self, context: str, delta: int) -> dict: result = self.conn.execute(command_builder("browsingContext.traverseHistory", params)) return result - 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: list[str] | None = None) -> int: """Add an event handler to the browsing context. Args: diff --git a/py/selenium/webdriver/common/bidi/common.py b/py/selenium/webdriver/common/bidi/common.py index be982cceafa99..0f57d07e5f0d4 100644 --- a/py/selenium/webdriver/common/bidi/common.py +++ b/py/selenium/webdriver/common/bidi/common.py @@ -16,10 +16,9 @@ # under the License. from collections.abc import Generator -from typing import Optional -def command_builder(method: str, params: Optional[dict] = None) -> Generator[dict, dict, dict]: +def command_builder(method: str, params: dict | None = None) -> Generator[dict, dict, dict]: """Build a command iterator to send to the BiDi protocol. Args: diff --git a/py/selenium/webdriver/common/bidi/emulation.py b/py/selenium/webdriver/common/bidi/emulation.py index 85558d4b0f4f3..c158ad5b936ae 100644 --- a/py/selenium/webdriver/common/bidi/emulation.py +++ b/py/selenium/webdriver/common/bidi/emulation.py @@ -16,7 +16,7 @@ # under the License. from enum import Enum -from typing import Any, Optional, Union +from typing import Any from selenium.webdriver.common.bidi.common import command_builder @@ -51,8 +51,8 @@ class ScreenOrientation: def __init__( self, - natural: Union[ScreenOrientationNatural, str], - type: Union[ScreenOrientationType, str], + natural: ScreenOrientationNatural | str, + type: ScreenOrientationType | str, ): """Initialize ScreenOrientation. @@ -83,10 +83,10 @@ def __init__( latitude: float, longitude: float, accuracy: float = 1.0, - altitude: Optional[float] = None, - altitude_accuracy: Optional[float] = None, - heading: Optional[float] = None, - speed: Optional[float] = None, + altitude: float | None = None, + altitude_accuracy: float | None = None, + heading: float | None = None, + speed: float | None = None, ): """Initialize GeolocationCoordinates. @@ -180,8 +180,8 @@ def speed(self, value): raise ValueError("speed must be >= 0.0") self._speed = value - def to_dict(self) -> dict[str, Union[float, None]]: - result: dict[str, Union[float, None]] = { + def to_dict(self) -> dict[str, float | None]: + result: dict[str, float | None] = { "latitude": self.latitude, "longitude": self.longitude, "accuracy": self.accuracy, @@ -224,10 +224,10 @@ def __init__(self, conn): def set_geolocation_override( self, - coordinates: Optional[GeolocationCoordinates] = None, - error: Optional[GeolocationPositionError] = None, - contexts: Optional[list[str]] = None, - user_contexts: Optional[list[str]] = None, + coordinates: GeolocationCoordinates | None = None, + error: GeolocationPositionError | None = None, + contexts: list[str] | None = None, + user_contexts: list[str] | None = None, ) -> None: """Set geolocation override for the given contexts or user contexts. @@ -267,9 +267,9 @@ def set_geolocation_override( def set_timezone_override( self, - timezone: Optional[str] = None, - contexts: Optional[list[str]] = None, - user_contexts: Optional[list[str]] = None, + timezone: str | None = None, + contexts: list[str] | None = None, + user_contexts: list[str] | None = None, ) -> None: """Set timezone override for the given contexts or user contexts. @@ -300,9 +300,9 @@ def set_timezone_override( def set_locale_override( self, - locale: Optional[str] = None, - contexts: Optional[list[str]] = None, - user_contexts: Optional[list[str]] = None, + locale: str | None = None, + contexts: list[str] | None = None, + user_contexts: list[str] | None = None, ) -> None: """Set locale override for the given contexts or user contexts. @@ -332,9 +332,9 @@ def set_locale_override( def set_scripting_enabled( self, - enabled: Union[bool, None] = False, - contexts: Optional[list[str]] = None, - user_contexts: Optional[list[str]] = None, + enabled: bool | None = False, + contexts: list[str] | None = None, + user_contexts: list[str] | None = None, ) -> None: """Set scripting enabled override for the given contexts or user contexts. @@ -368,9 +368,9 @@ def set_scripting_enabled( def set_screen_orientation_override( self, - screen_orientation: Optional[ScreenOrientation] = None, - contexts: Optional[list[str]] = None, - user_contexts: Optional[list[str]] = None, + screen_orientation: ScreenOrientation | None = None, + contexts: list[str] | None = None, + user_contexts: list[str] | None = None, ) -> None: """Set screen orientation override for the given contexts or user contexts. diff --git a/py/selenium/webdriver/common/bidi/input.py b/py/selenium/webdriver/common/bidi/input.py index e3cf175015096..270ececaf41a1 100644 --- a/py/selenium/webdriver/common/bidi/input.py +++ b/py/selenium/webdriver/common/bidi/input.py @@ -17,7 +17,7 @@ import math from dataclasses import dataclass, field -from typing import Any, Optional, Union +from typing import Any from selenium.webdriver.common.bidi.common import command_builder from selenium.webdriver.common.bidi.session import Session @@ -124,7 +124,7 @@ def to_dict(self) -> dict: class PauseAction: """Represents a pause action.""" - duration: Optional[int] = None + duration: int | None = None @property def type(self) -> str: @@ -173,7 +173,7 @@ class PointerDownAction: """Represents a pointer down action.""" button: int = 0 - properties: Optional[PointerCommonProperties] = None + properties: PointerCommonProperties | None = None @property def type(self) -> str: @@ -208,9 +208,9 @@ class PointerMoveAction: x: float = 0 y: float = 0 - duration: Optional[int] = None - origin: Optional[Union[str, ElementOrigin]] = None - properties: Optional[PointerCommonProperties] = None + duration: int | None = None + origin: str | ElementOrigin | None = None + properties: PointerCommonProperties | None = None @property def type(self) -> str: @@ -239,8 +239,8 @@ class WheelScrollAction: y: int = 0 delta_x: int = 0 delta_y: int = 0 - duration: Optional[int] = None - origin: Optional[Union[str, ElementOrigin]] = Origin.VIEWPORT + duration: int | None = None + origin: str | ElementOrigin | None = Origin.VIEWPORT @property def type(self) -> str: @@ -287,7 +287,7 @@ class KeySourceActions: """Represents a sequence of key actions.""" id: str = "" - actions: list[Union[PauseAction, KeyDownAction, KeyUpAction]] = field(default_factory=list) + actions: list[PauseAction | KeyDownAction | KeyUpAction] = field(default_factory=list) @property def type(self) -> str: @@ -303,10 +303,8 @@ class PointerSourceActions: """Represents a sequence of pointer actions.""" id: str = "" - parameters: Optional[PointerParameters] = None - actions: list[Union[PauseAction, PointerDownAction, PointerUpAction, PointerMoveAction]] = field( - default_factory=list - ) + parameters: PointerParameters | None = None + actions: list[PauseAction | PointerDownAction | PointerUpAction | PointerMoveAction] = field(default_factory=list) def __post_init__(self): if self.parameters is None: @@ -333,7 +331,7 @@ class WheelSourceActions: """Represents a sequence of wheel actions.""" id: str = "" - actions: list[Union[PauseAction, WheelScrollAction]] = field(default_factory=list) + actions: list[PauseAction | WheelScrollAction] = field(default_factory=list) @property def type(self) -> str: @@ -350,7 +348,7 @@ class FileDialogInfo: context: str multiple: bool - element: Optional[dict] = None + element: dict | None = None @classmethod def from_dict(cls, data: dict) -> "FileDialogInfo": @@ -388,7 +386,7 @@ def __init__(self, conn): def perform_actions( self, context: str, - actions: list[Union[NoneSourceActions, KeySourceActions, PointerSourceActions, WheelSourceActions]], + actions: list[NoneSourceActions | KeySourceActions | PointerSourceActions | WheelSourceActions], ) -> None: """Performs a sequence of user input actions. diff --git a/py/selenium/webdriver/common/bidi/permissions.py b/py/selenium/webdriver/common/bidi/permissions.py index b167b47d09032..17faa1ff5454f 100644 --- a/py/selenium/webdriver/common/bidi/permissions.py +++ b/py/selenium/webdriver/common/bidi/permissions.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional, Union from selenium.webdriver.common.bidi.common import command_builder @@ -46,10 +45,10 @@ def __init__(self, conn): def set_permission( self, - descriptor: Union[str, PermissionDescriptor], + descriptor: str | PermissionDescriptor, state: str, origin: str, - user_context: Optional[str] = None, + user_context: str | None = None, ) -> None: """Sets a permission state for a given permission descriptor. diff --git a/py/selenium/webdriver/common/bidi/script.py b/py/selenium/webdriver/common/bidi/script.py index 6583e211b6b38..e37b3269a4ade 100644 --- a/py/selenium/webdriver/common/bidi/script.py +++ b/py/selenium/webdriver/common/bidi/script.py @@ -18,7 +18,7 @@ import datetime import math from dataclasses import dataclass -from typing import Any, Optional +from typing import Any from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.bidi.common import command_builder @@ -53,8 +53,8 @@ class RealmInfo: realm: str origin: str type: str - context: Optional[str] = None - sandbox: Optional[str] = None + context: str | None = None + sandbox: str | None = None @classmethod def from_json(cls, json: dict[str, Any]) -> "RealmInfo": @@ -87,7 +87,7 @@ class Source: """Represents the source of a script message.""" realm: str - context: Optional[str] = None + context: str | None = None @classmethod def from_json(cls, json: dict[str, Any]) -> "Source": @@ -114,8 +114,8 @@ class EvaluateResult: type: str realm: str - result: Optional[dict] = None - exception_details: Optional[dict] = None + result: dict | None = None + exception_details: dict | None = None @classmethod def from_json(cls, json: dict[str, Any]) -> "EvaluateResult": @@ -362,10 +362,10 @@ def __convert_to_local_value(self, value) -> dict: def _add_preload_script( self, function_declaration: str, - arguments: Optional[list[dict[str, Any]]] = None, - contexts: Optional[list[str]] = None, - user_contexts: Optional[list[str]] = None, - sandbox: Optional[str] = None, + arguments: list[dict[str, Any]] | None = None, + contexts: list[str] | None = None, + user_contexts: list[str] | None = None, + sandbox: str | None = None, ) -> str: """Adds a preload script. @@ -426,10 +426,10 @@ def _call_function( function_declaration: str, await_promise: bool, target: dict, - arguments: Optional[list[dict]] = None, - result_ownership: Optional[str] = None, - serialization_options: Optional[dict] = None, - this: Optional[dict] = None, + arguments: list[dict] | None = None, + result_ownership: str | None = None, + serialization_options: dict | None = None, + this: dict | None = None, user_activation: bool = False, ) -> EvaluateResult: """Calls a provided function with given arguments in a given realm. @@ -471,8 +471,8 @@ def _evaluate( expression: str, target: dict, await_promise: bool, - result_ownership: Optional[str] = None, - serialization_options: Optional[dict] = None, + result_ownership: str | None = None, + serialization_options: dict | None = None, user_activation: bool = False, ) -> EvaluateResult: """Evaluates a provided script in a given realm. @@ -505,8 +505,8 @@ def _evaluate( def _get_realms( self, - context: Optional[str] = None, - type: Optional[str] = None, + context: str | None = None, + type: str | None = None, ) -> list[RealmInfo]: """Returns a list of all realms, optionally filtered. diff --git a/py/selenium/webdriver/common/bidi/session.py b/py/selenium/webdriver/common/bidi/session.py index 534cf861c2423..3481c2d77842d 100644 --- a/py/selenium/webdriver/common/bidi/session.py +++ b/py/selenium/webdriver/common/bidi/session.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.common.bidi.common import command_builder @@ -35,12 +34,12 @@ class UserPromptHandler: def __init__( self, - alert: Optional[str] = None, - before_unload: Optional[str] = None, - confirm: Optional[str] = None, - default: Optional[str] = None, - file: Optional[str] = None, - prompt: Optional[str] = None, + alert: str | None = None, + before_unload: str | None = None, + confirm: str | None = None, + default: str | None = None, + file: str | None = None, + prompt: str | None = None, ): """Initialize UserPromptHandler. diff --git a/py/selenium/webdriver/common/bidi/storage.py b/py/selenium/webdriver/common/bidi/storage.py index 6e0ca289a313a..a1700c962a4fd 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 Any, Optional, Union +from typing import Any from selenium.webdriver.common.bidi.common import command_builder @@ -56,12 +56,12 @@ def __init__( name: str, value: BytesValue, domain: str, - path: Optional[str] = None, - size: Optional[int] = None, - http_only: Optional[bool] = None, - secure: Optional[bool] = None, - same_site: Optional[str] = None, - expiry: Optional[int] = None, + path: str | None = None, + size: int | None = None, + http_only: bool | None = None, + secure: bool | None = None, + same_site: str | None = None, + expiry: int | None = None, ): self.name = name self.value = value @@ -110,15 +110,15 @@ class CookieFilter: def __init__( self, - name: Optional[str] = None, - value: Optional[BytesValue] = None, - domain: Optional[str] = None, - path: Optional[str] = None, - size: Optional[int] = None, - http_only: Optional[bool] = None, - secure: Optional[bool] = None, - same_site: Optional[str] = None, - expiry: Optional[int] = None, + name: str | None = None, + value: BytesValue | None = None, + domain: str | None = None, + path: str | None = None, + size: int | None = None, + http_only: bool | None = None, + secure: bool | None = None, + same_site: str | None = None, + expiry: int | None = None, ): self.name = name self.value = value @@ -161,7 +161,7 @@ def to_dict(self) -> dict[str, Any]: class PartitionKey: """Represents a storage partition key.""" - def __init__(self, user_context: Optional[str] = None, source_origin: Optional[str] = None): + def __init__(self, user_context: str | None = None, source_origin: str | None = None): self.user_context = user_context self.source_origin = source_origin @@ -200,7 +200,7 @@ def to_dict(self) -> dict: class StorageKeyPartitionDescriptor: """Represents a storage key partition descriptor.""" - def __init__(self, user_context: Optional[str] = None, source_origin: Optional[str] = None): + def __init__(self, user_context: str | None = None, source_origin: str | None = None): self.type = "storageKey" self.user_context = user_context self.source_origin = source_origin @@ -227,11 +227,11 @@ def __init__( name: str, value: BytesValue, domain: str, - path: Optional[str] = None, - http_only: Optional[bool] = None, - secure: Optional[bool] = None, - same_site: Optional[str] = None, - expiry: Optional[int] = None, + path: str | None = None, + http_only: bool | None = None, + secure: bool | None = None, + same_site: str | None = None, + expiry: int | None = None, ): self.name = name self.value = value @@ -337,8 +337,8 @@ def __init__(self, conn): def get_cookies( self, - filter: Optional[CookieFilter] = None, - partition: Optional[Union[BrowsingContextPartitionDescriptor, StorageKeyPartitionDescriptor]] = None, + filter: CookieFilter | None = None, + partition: BrowsingContextPartitionDescriptor | StorageKeyPartitionDescriptor | None = None, ) -> GetCookiesResult: """Gets cookies matching the specified filter. @@ -367,7 +367,7 @@ def get_cookies( def set_cookie( self, cookie: PartialCookie, - partition: Optional[Union[BrowsingContextPartitionDescriptor, StorageKeyPartitionDescriptor]] = None, + partition: BrowsingContextPartitionDescriptor | StorageKeyPartitionDescriptor | None = None, ) -> SetCookieResult: """Sets a cookie in the browser. @@ -387,8 +387,8 @@ def set_cookie( def delete_cookies( self, - filter: Optional[CookieFilter] = None, - partition: Optional[Union[BrowsingContextPartitionDescriptor, StorageKeyPartitionDescriptor]] = None, + filter: CookieFilter | None = None, + partition: BrowsingContextPartitionDescriptor | StorageKeyPartitionDescriptor | None = None, ) -> DeleteCookiesResult: """Deletes cookies that match the given parameters. diff --git a/py/selenium/webdriver/common/bidi/webextension.py b/py/selenium/webdriver/common/bidi/webextension.py index 5fb3983bdefb8..eca1a53f1a7e1 100644 --- a/py/selenium/webdriver/common/bidi/webextension.py +++ b/py/selenium/webdriver/common/bidi/webextension.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Union from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.bidi.common import command_builder @@ -63,7 +62,7 @@ def install(self, path=None, archive_path=None, base64_value=None) -> dict: ) from e raise - def uninstall(self, extension_id_or_result: Union[str, dict]) -> None: + def uninstall(self, extension_id_or_result: str | dict) -> None: """Uninstalls a web extension from the remote end. Args: diff --git a/py/selenium/webdriver/common/by.py b/py/selenium/webdriver/common/by.py index 986099c7bb414..d2a10ac70a7c6 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 Literal, Optional +from typing import Literal ByType = Literal["id", "xpath", "link text", "partial link text", "name", "tag name", "class name", "css selector"] @@ -91,7 +91,7 @@ def register_custom_finder(cls, name: str, strategy: str) -> None: cls._custom_finders[name] = strategy @classmethod - def get_finder(cls, name: str) -> Optional[str]: + def get_finder(cls, name: str) -> str | None: return cls._custom_finders.get(name) or getattr(cls, name.upper(), None) @classmethod diff --git a/py/selenium/webdriver/common/fedcm/account.py b/py/selenium/webdriver/common/fedcm/account.py index 7258ea677426b..f8cf8a00b775c 100644 --- a/py/selenium/webdriver/common/fedcm/account.py +++ b/py/selenium/webdriver/common/fedcm/account.py @@ -16,7 +16,6 @@ # under the License. from enum import Enum -from typing import Optional class LoginState(Enum): @@ -28,7 +27,7 @@ class _AccountDescriptor: def __init__(self, name): self.name = name - def __get__(self, obj, cls) -> Optional[str]: + def __get__(self, obj, cls) -> str | None: return obj._account_data.get(self.name) def __set__(self, obj, value) -> None: diff --git a/py/selenium/webdriver/common/fedcm/dialog.py b/py/selenium/webdriver/common/fedcm/dialog.py index 9a7a2a89a2d61..b99f8f74d31e5 100644 --- a/py/selenium/webdriver/common/fedcm/dialog.py +++ b/py/selenium/webdriver/common/fedcm/dialog.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.common.fedcm.account import Account @@ -30,7 +29,7 @@ def __init__(self, driver) -> None: self._driver = driver @property - def type(self) -> Optional[str]: + def type(self) -> str | None: """Gets the type of the dialog currently being shown.""" return self._driver.fedcm.dialog_type @@ -40,7 +39,7 @@ def title(self) -> str: return self._driver.fedcm.title @property - def subtitle(self) -> Optional[str]: + def subtitle(self) -> str | None: """Gets the subtitle of the dialog.""" result = self._driver.fedcm.subtitle return result.get("subtitle") if result else None diff --git a/py/selenium/webdriver/common/log.py b/py/selenium/webdriver/common/log.py index 65da4347dca87..6bf048049ec85 100644 --- a/py/selenium/webdriver/common/log.py +++ b/py/selenium/webdriver/common/log.py @@ -20,7 +20,7 @@ from collections.abc import AsyncGenerator from contextlib import asynccontextmanager from importlib import import_module -from typing import Any, Optional +from typing import Any from selenium.webdriver.common.by import By @@ -47,7 +47,7 @@ def __init__(self, driver, bidi_session) -> None: self.devtools = bidi_session.devtools _pkg = ".".join(__name__.split(".")[:-1]) # Ensure _mutation_listener_js is not None before decoding - _mutation_listener_js_bytes: Optional[bytes] = pkgutil.get_data(_pkg, "mutation-listener.js") + _mutation_listener_js_bytes: bytes | None = pkgutil.get_data(_pkg, "mutation-listener.js") if _mutation_listener_js_bytes is None: raise ValueError("Failed to load mutation-listener.js") self._mutation_listener_js = _mutation_listener_js_bytes.decode("utf8").strip() diff --git a/py/selenium/webdriver/common/options.py b/py/selenium/webdriver/common/options.py index 5599cc635b874..af0dd55e285ac 100644 --- a/py/selenium/webdriver/common/options.py +++ b/py/selenium/webdriver/common/options.py @@ -18,7 +18,6 @@ import warnings from abc import ABCMeta, abstractmethod from enum import Enum -from typing import Optional from selenium.common.exceptions import InvalidArgumentException from selenium.webdriver.common.proxy import Proxy @@ -338,7 +337,7 @@ def __init__(self) -> None: self._caps = self.default_capabilities self._proxy = None self.set_capability("pageLoadStrategy", PageLoadStrategy.normal) - self.mobile_options: Optional[dict[str, str]] = None + self.mobile_options: dict[str, str] | None = None self._ignore_local_proxy = False @property @@ -351,9 +350,9 @@ def set_capability(self, name, value) -> None: def enable_mobile( self, - android_package: Optional[str] = None, - android_activity: Optional[str] = None, - device_serial: Optional[str] = None, + android_package: str | None = None, + android_activity: str | None = None, + device_serial: str | None = None, ) -> None: """Enables mobile browser use for browsers that support it. diff --git a/py/selenium/webdriver/common/print_page_options.py b/py/selenium/webdriver/common/print_page_options.py index cb13c32a32afa..07b5f598e38d2 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, Optional +from typing import TYPE_CHECKING if TYPE_CHECKING: from typing import Literal, TypedDict @@ -55,7 +55,7 @@ class _PageSettingsDescriptor: def __init__(self, name): self.name = name - def __get__(self, obj, cls) -> Optional[float]: + def __get__(self, obj, cls) -> float | None: return obj._page.get(self.name, None) def __set__(self, obj, value) -> None: @@ -76,7 +76,7 @@ class _MarginSettingsDescriptor: def __init__(self, name): self.name = name - def __get__(self, obj, cls) -> Optional[float]: + def __get__(self, obj, cls) -> float | None: return obj._margin.get(self.name, None) def __set__(self, obj, value) -> None: @@ -91,7 +91,7 @@ class _ScaleDescriptor: def __init__(self, name): self.name = name - def __get__(self, obj, cls) -> Optional[float]: + def __get__(self, obj, cls) -> float | None: return obj._print_options.get(self.name) def __set__(self, obj, value) -> None: @@ -109,7 +109,7 @@ class _PageOrientationDescriptor: def __init__(self, name): self.name = name - def __get__(self, obj, cls) -> Optional[Orientation]: + def __get__(self, obj, cls) -> Orientation | None: return obj._print_options.get(self.name, None) def __set__(self, obj, value) -> None: diff --git a/py/selenium/webdriver/common/selenium_manager.py b/py/selenium/webdriver/common/selenium_manager.py index 6317220fb61c9..51c2723c4ac35 100644 --- a/py/selenium/webdriver/common/selenium_manager.py +++ b/py/selenium/webdriver/common/selenium_manager.py @@ -22,7 +22,6 @@ import sys import sysconfig from pathlib import Path -from typing import Optional from selenium.common import WebDriverException @@ -69,7 +68,7 @@ def _get_binary() -> Path: if exe is not None: compiled_path = compiled_path.with_suffix(exe) - path: Optional[Path] = None + path: Path | None = None if (env_path := os.getenv("SE_MANAGER_PATH")) is not None: logger.debug("Selenium Manager set by env SE_MANAGER_PATH to: %s", env_path) diff --git a/py/selenium/webdriver/common/service.py b/py/selenium/webdriver/common/service.py index ed39ad9d70118..df7997ed688b7 100644 --- a/py/selenium/webdriver/common/service.py +++ b/py/selenium/webdriver/common/service.py @@ -52,14 +52,14 @@ class Service(ABC): def __init__( self, - executable_path: Optional[str] = None, + executable_path: str | None = None, port: int = 0, - log_output: Optional[SubprocessStdAlias] = None, - env: Optional[Mapping[Any, Any]] = None, - driver_path_env_key: Optional[str] = None, + log_output: SubprocessStdAlias | None = None, + env: Mapping[Any, Any] | None = None, + driver_path_env_key: str | None = None, **kwargs, ) -> None: - self.log_output: Optional[Union[int, IOBase]] + self.log_output: int | IOBase | None if isinstance(log_output, str): self.log_output = cast(IOBase, open(log_output, "a+", encoding="utf-8")) elif log_output == subprocess.STDOUT: @@ -246,7 +246,7 @@ def _start_process(self, path: str) -> None: ) from err raise - def env_path(self) -> Optional[str]: + def env_path(self) -> str | None: if self.DRIVER_PATH_ENV_KEY: return os.getenv(self.DRIVER_PATH_ENV_KEY, None) return None diff --git a/py/selenium/webdriver/common/utils.py b/py/selenium/webdriver/common/utils.py index ac3087fc17ddf..52e54e63da875 100644 --- a/py/selenium/webdriver/common/utils.py +++ b/py/selenium/webdriver/common/utils.py @@ -20,7 +20,6 @@ import socket import urllib.request from collections.abc import Iterable -from typing import Optional, Union from selenium.types import AnyKey from selenium.webdriver.common.keys import Keys @@ -58,7 +57,7 @@ def free_port() -> int: return port -def find_connectable_ip(host: Union[str, bytes, bytearray, None], port: Optional[int] = None) -> Optional[str]: +def find_connectable_ip(host: str | bytes | bytearray | None, port: int | None = None) -> str | None: """Resolve a hostname to an IP, preferring IPv4 addresses. We prefer IPv4 so that we don't change behavior from previous IPv4-only @@ -110,7 +109,7 @@ def join_host_port(host: str, port: int) -> str: return f"{host}:{port}" -def is_connectable(port: int, host: Optional[str] = "localhost") -> bool: +def is_connectable(port: int, host: str | None = "localhost") -> bool: """Tries to connect to the server at port to see if it is running. Args: @@ -134,9 +133,9 @@ def is_connectable(port: int, host: Optional[str] = "localhost") -> bool: def is_url_connectable( - port: Union[int, str], - host: Optional[str] = "127.0.0.1", - scheme: Optional[str] = "http", + port: int | str, + host: str | None = "127.0.0.1", + scheme: str | None = "http", ) -> bool: """Send a request to the HTTP server at the /status endpoint to verify connectivity. diff --git a/py/selenium/webdriver/common/virtual_authenticator.py b/py/selenium/webdriver/common/virtual_authenticator.py index 7eee90ddb7152..0210edda0a8bd 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, Optional, Union +from typing import Any class Protocol(str, Enum): @@ -63,7 +63,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, str | bool]: return { "protocol": self.protocol, "transport": self.transport, @@ -79,8 +79,8 @@ def __init__( self, credential_id: bytes, is_resident_credential: bool, - rp_id: Optional[str], - user_handle: Optional[bytes], + rp_id: str | None, + user_handle: bytes | None, private_key: bytes, sign_count: int, ): @@ -112,11 +112,11 @@ def is_resident_credential(self) -> bool: return self._is_resident_credential @property - def rp_id(self) -> Optional[str]: + def rp_id(self) -> str | None: return self._rp_id @property - def user_handle(self) -> Optional[str]: + def user_handle(self) -> str | None: if self._user_handle: return urlsafe_b64encode(self._user_handle).decode() return None @@ -146,7 +146,7 @@ def create_non_resident_credential(cls, id: bytes, rp_id: str, private_key: byte @classmethod def create_resident_credential( - cls, id: bytes, rp_id: str, user_handle: Optional[bytes], private_key: bytes, sign_count: int + cls, id: bytes, rp_id: str, user_handle: bytes | None, private_key: bytes, sign_count: int ) -> "Credential": """Creates a resident (i.e. stateful) credential. diff --git a/py/selenium/webdriver/edge/remote_connection.py b/py/selenium/webdriver/edge/remote_connection.py index 39634c580c9d4..54f396340d0b9 100644 --- a/py/selenium/webdriver/edge/remote_connection.py +++ b/py/selenium/webdriver/edge/remote_connection.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver import DesiredCapabilities from selenium.webdriver.chromium.remote_connection import ChromiumRemoteConnection @@ -29,8 +28,8 @@ def __init__( self, remote_server_addr: str, keep_alive: bool = True, - ignore_proxy: Optional[bool] = False, - client_config: Optional[ClientConfig] = None, + ignore_proxy: bool | None = False, + client_config: ClientConfig | None = None, ) -> None: super().__init__( remote_server_addr=remote_server_addr, diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index 8eee39b24c0c6..2e1131200ca2e 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -16,7 +16,6 @@ # under the License. from collections.abc import Mapping, Sequence -from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.chromium import service @@ -36,12 +35,12 @@ class Service(service.ChromiumService): def __init__( self, - executable_path: Optional[str] = None, + executable_path: str | None = None, port: int = 0, - log_output: Optional[SubprocessStdAlias] = None, - service_args: Optional[Sequence[str]] = None, - env: Optional[Mapping[str, str]] = None, - driver_path_env_key: Optional[str] = None, + log_output: SubprocessStdAlias | None = None, + service_args: Sequence[str] | None = None, + env: Mapping[str, str] | None = None, + driver_path_env_key: str | None = None, **kwargs, ) -> None: """Initialize Edge service with the specified parameters.""" diff --git a/py/selenium/webdriver/edge/webdriver.py b/py/selenium/webdriver/edge/webdriver.py index 4d8d895ad48fa..fee90b418bf53 100644 --- a/py/selenium/webdriver/edge/webdriver.py +++ b/py/selenium/webdriver/edge/webdriver.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.chromium.webdriver import ChromiumDriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities @@ -28,8 +27,8 @@ class WebDriver(ChromiumDriver): def __init__( self, - options: Optional[Options] = None, - service: Optional[Service] = None, + options: Options | None = None, + service: Service | None = None, keep_alive: bool = True, ) -> None: """Creates a new instance of the edge driver. diff --git a/py/selenium/webdriver/firefox/options.py b/py/selenium/webdriver/firefox/options.py index 9f5a7bbe0bded..57d636d77e6c7 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, Optional, Union +from typing import Any from typing_extensions import deprecated @@ -44,7 +44,7 @@ def __init__(self) -> None: # https://fxdx.dev/deprecating-cdp-support-in-firefox-embracing-the-future-with-webdriver-bidi/. # Enable BiDi only self._preferences["remote.active-protocols"] = 1 - self._profile: Optional[FirefoxProfile] = None + self._profile: FirefoxProfile | None = None self.log = Log() @property @@ -55,7 +55,7 @@ def binary(self) -> FirefoxBinary: @binary.setter @deprecated("use binary_location instead") - def binary(self, new_binary: Union[str, FirefoxBinary]) -> None: + def binary(self, new_binary: str | FirefoxBinary) -> None: """Set location of browser binary (string or FirefoxBinary instance).""" if isinstance(new_binary, FirefoxBinary): new_binary = new_binary._start_cmd @@ -78,24 +78,24 @@ def preferences(self) -> dict: """Returns a dict of preferences.""" return self._preferences - def set_preference(self, name: str, value: Union[str, int, bool]): + def set_preference(self, name: str, value: str | int | bool): """Sets a preference.""" self._preferences[name] = value @property - def profile(self) -> Optional[FirefoxProfile]: + def profile(self) -> FirefoxProfile | None: """Returns the Firefox profile to use.""" return self._profile @profile.setter - def profile(self, new_profile: Union[str, FirefoxProfile]) -> None: + def profile(self, new_profile: str | FirefoxProfile) -> None: """Set the location of the browser profile to use (string or FirefoxProfile object).""" if not isinstance(new_profile, FirefoxProfile): new_profile = FirefoxProfile(new_profile) self._profile = new_profile def enable_mobile( - self, android_package: Optional[str] = "org.mozilla.firefox", android_activity=None, device_serial=None + self, android_package: str | None = "org.mozilla.firefox", android_activity=None, device_serial=None ): super().enable_mobile(android_package, android_activity, device_serial) diff --git a/py/selenium/webdriver/firefox/remote_connection.py b/py/selenium/webdriver/firefox/remote_connection.py index a749cce37dc62..f2dff3d3e32f5 100644 --- a/py/selenium/webdriver/firefox/remote_connection.py +++ b/py/selenium/webdriver/firefox/remote_connection.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.remote.client_config import ClientConfig @@ -29,8 +28,8 @@ def __init__( self, remote_server_addr: str, keep_alive: bool = True, - ignore_proxy: Optional[bool] = False, - client_config: Optional[ClientConfig] = None, + ignore_proxy: bool | None = False, + client_config: ClientConfig | None = None, ) -> None: client_config = client_config or ClientConfig( remote_server_addr=remote_server_addr, keep_alive=keep_alive, timeout=120 diff --git a/py/selenium/webdriver/firefox/service.py b/py/selenium/webdriver/firefox/service.py index e0096b1e1d77c..b275a25ee8166 100644 --- a/py/selenium/webdriver/firefox/service.py +++ b/py/selenium/webdriver/firefox/service.py @@ -16,7 +16,6 @@ # under the License. from collections.abc import Mapping, Sequence -from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service, utils @@ -36,12 +35,12 @@ class Service(service.Service): def __init__( self, - executable_path: Optional[str] = None, + executable_path: str | None = None, port: int = 0, - service_args: Optional[Sequence[str]] = None, - log_output: Optional[SubprocessStdAlias] = None, - env: Optional[Mapping[str, str]] = None, - driver_path_env_key: Optional[str] = None, + service_args: Sequence[str] | None = None, + log_output: SubprocessStdAlias | None = None, + env: Mapping[str, str] | None = None, + driver_path_env_key: str | None = None, **kwargs, ) -> None: self._service_args = list(service_args or []) diff --git a/py/selenium/webdriver/firefox/webdriver.py b/py/selenium/webdriver/firefox/webdriver.py index 65b9eb5760d47..fd953edd23e5b 100644 --- a/py/selenium/webdriver/firefox/webdriver.py +++ b/py/selenium/webdriver/firefox/webdriver.py @@ -20,7 +20,6 @@ import zipfile from contextlib import contextmanager from io import BytesIO -from typing import Optional from selenium.webdriver.common.driver_finder import DriverFinder from selenium.webdriver.firefox.options import Options @@ -37,8 +36,8 @@ class WebDriver(RemoteWebDriver): def __init__( self, - options: Optional[Options] = None, - service: Optional[Service] = None, + options: Options | None = None, + service: Service | None = None, keep_alive: bool = True, ) -> None: """Create a new instance of the Firefox driver, start the service, and create new instance. diff --git a/py/selenium/webdriver/ie/service.py b/py/selenium/webdriver/ie/service.py index 35a14fcfb51f0..96393ed55cd69 100644 --- a/py/selenium/webdriver/ie/service.py +++ b/py/selenium/webdriver/ie/service.py @@ -16,7 +16,6 @@ # under the License. from collections.abc import Sequence -from typing import Optional from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service @@ -27,13 +26,13 @@ class Service(service.Service): def __init__( self, - executable_path: Optional[str] = None, + executable_path: str | None = None, port: int = 0, - host: Optional[str] = None, - service_args: Optional[Sequence[str]] = None, - log_level: Optional[str] = None, - log_output: Optional[SubprocessStdAlias] = None, - driver_path_env_key: Optional[str] = None, + host: str | None = None, + service_args: Sequence[str] | None = None, + log_level: str | None = None, + log_output: SubprocessStdAlias | None = None, + driver_path_env_key: str | None = None, **kwargs, ) -> None: """Creates a new instance of the Service. diff --git a/py/selenium/webdriver/ie/webdriver.py b/py/selenium/webdriver/ie/webdriver.py index b2380e22550fd..47f3224e2123a 100644 --- a/py/selenium/webdriver/ie/webdriver.py +++ b/py/selenium/webdriver/ie/webdriver.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.common.driver_finder import DriverFinder from selenium.webdriver.ie.options import Options @@ -30,8 +29,8 @@ class WebDriver(RemoteWebDriver): def __init__( self, - options: Optional[Options] = None, - service: Optional[Service] = None, + options: Options | None = None, + service: Service | None = None, keep_alive: bool = True, ) -> None: """Creates a new instance of the Ie driver. diff --git a/py/selenium/webdriver/remote/client_config.py b/py/selenium/webdriver/remote/client_config.py index 480c0c7e2fe41..98019b8f15834 100644 --- a/py/selenium/webdriver/remote/client_config.py +++ b/py/selenium/webdriver/remote/client_config.py @@ -19,7 +19,6 @@ import os import socket from enum import Enum -from typing import Optional from urllib import parse import certifi @@ -79,20 +78,20 @@ class ClientConfig: def __init__( self, remote_server_addr: str, - keep_alive: Optional[bool] = True, - proxy: Optional[Proxy] = Proxy(raw={"proxyType": ProxyType.SYSTEM}), - ignore_certificates: Optional[bool] = False, - init_args_for_pool_manager: Optional[dict] = None, - timeout: Optional[int] = None, - ca_certs: Optional[str] = None, - username: Optional[str] = None, - password: Optional[str] = None, - auth_type: Optional[AuthType] = AuthType.BASIC, - token: Optional[str] = None, - user_agent: Optional[str] = None, - extra_headers: Optional[dict] = None, - websocket_timeout: Optional[float] = 30.0, - websocket_interval: Optional[float] = 0.1, + keep_alive: bool | None = True, + proxy: Proxy | None = Proxy(raw={"proxyType": ProxyType.SYSTEM}), + ignore_certificates: bool | None = False, + init_args_for_pool_manager: dict | None = None, + timeout: int | None = None, + ca_certs: str | None = None, + username: str | None = None, + password: str | None = None, + auth_type: AuthType | None = AuthType.BASIC, + token: str | None = None, + user_agent: str | None = None, + extra_headers: dict | None = None, + websocket_timeout: float | None = 30.0, + websocket_interval: float | None = 0.1, ) -> None: self.remote_server_addr = remote_server_addr self.keep_alive = keep_alive @@ -119,7 +118,7 @@ def reset_timeout(self) -> None: """Resets the timeout to the default value of socket.""" self._timeout = socket.getdefaulttimeout() - def get_proxy_url(self) -> Optional[str]: + def get_proxy_url(self) -> str | None: """Returns the proxy URL to use for the connection.""" proxy_type = self.proxy.proxy_type remote_add = parse.urlparse(self.remote_server_addr) @@ -144,7 +143,7 @@ def get_proxy_url(self) -> Optional[str]: return self.proxy.sslProxy if self.remote_server_addr.startswith("https://") else self.proxy.http_proxy return None - def get_auth_header(self) -> Optional[dict]: + def get_auth_header(self) -> dict | None: """Returns the authorization to add to the request headers.""" if self.auth_type is AuthType.BASIC and self.username and self.password: credentials = f"{self.username}:{self.password}" diff --git a/py/selenium/webdriver/remote/fedcm.py b/py/selenium/webdriver/remote/fedcm.py index 2733bc6006f8e..d2b93e03459df 100644 --- a/py/selenium/webdriver/remote/fedcm.py +++ b/py/selenium/webdriver/remote/fedcm.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.remote.command import Command @@ -30,7 +29,7 @@ def title(self) -> str: return self._driver.execute(Command.GET_FEDCM_TITLE)["value"].get("title") @property - def subtitle(self) -> Optional[str]: + def subtitle(self) -> str | None: """Gets the subtitle of the dialog.""" return self._driver.execute(Command.GET_FEDCM_TITLE)["value"].get("subtitle") diff --git a/py/selenium/webdriver/remote/file_detector.py b/py/selenium/webdriver/remote/file_detector.py index a72cb205be39a..a0ada9b5ffabf 100644 --- a/py/selenium/webdriver/remote/file_detector.py +++ b/py/selenium/webdriver/remote/file_detector.py @@ -18,7 +18,6 @@ from abc import ABCMeta, abstractmethod from contextlib import suppress from pathlib import Path -from typing import Optional from selenium.types import AnyKey from selenium.webdriver.common.utils import keys_to_typing @@ -28,21 +27,21 @@ class FileDetector(metaclass=ABCMeta): """Identify whether a sequence of characters represents a file path.""" @abstractmethod - def is_local_file(self, *keys: AnyKey) -> Optional[str]: + def is_local_file(self, *keys: AnyKey) -> str | None: raise NotImplementedError class UselessFileDetector(FileDetector): """A file detector that never finds anything.""" - def is_local_file(self, *keys: AnyKey) -> Optional[str]: + def is_local_file(self, *keys: AnyKey) -> str | None: return None class LocalFileDetector(FileDetector): """Detects files on the local disk.""" - def is_local_file(self, *keys: AnyKey) -> Optional[str]: + def is_local_file(self, *keys: AnyKey) -> str | None: file_path = "".join(keys_to_typing(keys)) with suppress(OSError): diff --git a/py/selenium/webdriver/remote/remote_connection.py b/py/selenium/webdriver/remote/remote_connection.py index 2b3751ef3b8ef..0718908724e52 100644 --- a/py/selenium/webdriver/remote/remote_connection.py +++ b/py/selenium/webdriver/remote/remote_connection.py @@ -20,7 +20,6 @@ import sys import warnings from base64 import b64encode -from typing import Optional from urllib import parse from urllib.parse import unquote, urlparse @@ -144,7 +143,7 @@ class RemoteConnection: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol """ - browser_name: Optional[str] = None + browser_name: str | None = None # Keep backward compatibility for AppiumConnection - https://github.com/SeleniumHQ/selenium/issues/14694 import os import socket @@ -153,7 +152,7 @@ class RemoteConnection: _timeout = socket.getdefaulttimeout() _ca_certs = os.getenv("REQUESTS_CA_BUNDLE") if "REQUESTS_CA_BUNDLE" in os.environ else certifi.where() - _client_config: Optional[ClientConfig] = None + _client_config: ClientConfig | None = None system = sys.platform if system == "darwin": @@ -307,12 +306,12 @@ def _get_connection_manager(self): def __init__( self, - remote_server_addr: Optional[str] = None, - keep_alive: Optional[bool] = True, - ignore_proxy: Optional[bool] = False, - ignore_certificates: Optional[bool] = False, - init_args_for_pool_manager: Optional[dict] = None, - client_config: Optional[ClientConfig] = None, + remote_server_addr: str | None = None, + keep_alive: bool | None = True, + ignore_proxy: bool | None = False, + ignore_certificates: bool | None = False, + init_args_for_pool_manager: dict | None = None, + client_config: ClientConfig | None = None, ): self._client_config = client_config or ClientConfig( remote_server_addr=remote_server_addr, diff --git a/py/selenium/webdriver/remote/switch_to.py b/py/selenium/webdriver/remote/switch_to.py index 89aabfef79773..a37fbcdf831ed 100644 --- a/py/selenium/webdriver/remote/switch_to.py +++ b/py/selenium/webdriver/remote/switch_to.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional, Union from selenium.common.exceptions import NoSuchElementException, NoSuchFrameException, NoSuchWindowException from selenium.webdriver.common.alert import Alert @@ -58,7 +57,7 @@ def default_content(self) -> None: """ self._driver.execute(Command.SWITCH_TO_FRAME, {"id": None}) - def frame(self, frame_reference: Union[str, int, WebElement]) -> None: + def frame(self, frame_reference: str | int | WebElement) -> None: """Switch focus to the specified frame by index, name, or element. Args: @@ -81,7 +80,7 @@ def frame(self, frame_reference: Union[str, int, WebElement]) -> None: self._driver.execute(Command.SWITCH_TO_FRAME, {"id": frame_reference}) - def new_window(self, type_hint: Optional[str] = None) -> None: + def new_window(self, type_hint: str | None = None) -> None: """Switches to a new top-level browsing context. The type hint can be one of "tab" or "window". If not specified the diff --git a/py/selenium/webdriver/remote/utils.py b/py/selenium/webdriver/remote/utils.py index 8e440e0e1246e..4ab7a2df88264 100644 --- a/py/selenium/webdriver/remote/utils.py +++ b/py/selenium/webdriver/remote/utils.py @@ -16,12 +16,12 @@ # under the License. import json -from typing import Any, Union +from typing import Any def dump_json(json_struct: Any) -> str: return json.dumps(json_struct) -def load_json(s: Union[str, bytes]) -> Any: +def load_json(s: str | bytes) -> Any: return json.loads(s) diff --git a/py/selenium/webdriver/remote/webdriver.py b/py/selenium/webdriver/remote/webdriver.py index 42ac76404822b..41f5169957fab 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, Optional, Union, cast +from typing import Any, cast from selenium.common.exceptions import ( InvalidArgumentException, @@ -105,10 +105,10 @@ def _create_caps(caps) -> dict: def get_remote_connection( capabilities: dict, - command_executor: Union[str, RemoteConnection], + command_executor: str | RemoteConnection, keep_alive: bool, ignore_local_proxy: bool, - client_config: Optional[ClientConfig] = None, + client_config: ClientConfig | None = None, ) -> RemoteConnection: if isinstance(command_executor, str): client_config = client_config or ClientConfig(remote_server_addr=command_executor) @@ -197,13 +197,13 @@ class WebDriver(BaseWebDriver): def __init__( self, - command_executor: Union[str, RemoteConnection] = "http://127.0.0.1:4444", + command_executor: str | RemoteConnection = "http://127.0.0.1:4444", keep_alive: bool = True, - file_detector: Optional[FileDetector] = None, - options: Optional[Union[BaseOptions, list[BaseOptions]]] = None, - locator_converter: Optional[LocatorConverter] = None, - web_element_cls: Optional[type[WebElement]] = None, - client_config: Optional[ClientConfig] = None, + file_detector: FileDetector | None = None, + options: BaseOptions | list[BaseOptions] | None = None, + locator_converter: LocatorConverter | None = None, + web_element_cls: type[WebElement] | None = None, + client_config: ClientConfig | None = None, ) -> None: """Create a new driver instance that issues commands using the WebDriver protocol. @@ -243,7 +243,7 @@ def __init__( client_config=client_config, ) self._is_remote = True - self.session_id: Optional[str] = None + self.session_id: str | None = None self.caps: dict[str, Any] = {} self.pinned_scripts: dict[str, Any] = {} self.error_handler = ErrorHandler() @@ -257,18 +257,18 @@ def __init__( self.start_session(capabilities) self._fedcm = FedCM(self) - self._websocket_connection: Optional[WebSocketConnection] = None - self._script: Optional[Script] = None - self._network: Optional[Network] = None - self._browser: Optional[Browser] = None - self._bidi_session: Optional[Session] = None - self._browsing_context: Optional[BrowsingContext] = None - self._storage: Optional[Storage] = None - self._webextension: Optional[WebExtension] = None - self._permissions: Optional[Permissions] = None - self._emulation: Optional[Emulation] = None - self._input: Optional[Input] = None - self._devtools: Optional[Any] = None + self._websocket_connection: WebSocketConnection | None = None + self._script: Script | None = None + self._network: Network | None = None + self._browser: Browser | None = None + self._bidi_session: Session | None = None + self._browsing_context: BrowsingContext | None = None + self._storage: Storage | None = None + self._webextension: WebExtension | None = None + self._permissions: Permissions | None = None + self._emulation: Emulation | None = None + self._input: Input | None = None + self._devtools: Any | None = None def __repr__(self) -> str: return f'<{type(self).__module__}.{type(self).__name__} (session="{self.session_id}")>' @@ -278,9 +278,9 @@ def __enter__(self) -> "WebDriver": def __exit__( self, - exc_type: Optional[type[BaseException]], - exc: Optional[BaseException], - traceback: Optional[types.TracebackType], + exc_type: type[BaseException] | None, + exc: BaseException | None, + traceback: types.TracebackType | None, ): self.quit() @@ -408,7 +408,7 @@ def execute_cdp_cmd(self, cmd: str, cmd_args: dict): """ return self.execute("executeCdpCommand", {"cmd": cmd, "params": cmd_args})["value"] - def execute(self, driver_command: str, params: Optional[dict[str, Any]] = None) -> dict[str, Any]: + def execute(self, driver_command: str, params: dict[str, Any] | None = None) -> dict[str, Any]: """Sends a command to be executed by a command.CommandExecutor. Args: @@ -582,13 +582,13 @@ def minimize_window(self) -> None: """Invokes the window manager-specific 'minimize' operation.""" self.execute(Command.MINIMIZE_WINDOW) - def print_page(self, print_options: Optional[PrintOptions] = None) -> str: + def print_page(self, print_options: PrintOptions | None = None) -> str: """Takes PDF of the current page. The driver makes a best effort to return a PDF based on the provided parameters. """ - options: Union[dict[str, Any], Any] = {} + options: dict[str, Any] | Any = {} if print_options: options = print_options.to_dict() @@ -635,7 +635,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) -> dict | None: """Get a single cookie by name (case-sensitive,). Returns: @@ -775,7 +775,7 @@ def timeouts(self, timeouts) -> None: """ _ = self.execute(Command.SET_TIMEOUTS, timeouts._to_json())["value"] - def find_element(self, by=By.ID, value: Optional[str] = None) -> WebElement: + def find_element(self, by=By.ID, value: str | None = None) -> WebElement: """Find an element given a By strategy and locator. Args: @@ -801,7 +801,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: str | None = None) -> list[WebElement]: """Find elements given a By strategy and locator. Args: @@ -1325,7 +1325,7 @@ def add_virtual_authenticator(self, options: VirtualAuthenticatorOptions) -> Non self._authenticator_id = self.execute(Command.ADD_VIRTUAL_AUTHENTICATOR, options.to_dict())["value"] @property - def virtual_authenticator_id(self) -> Optional[str]: + def virtual_authenticator_id(self) -> str | None: """Returns the id of the virtual authenticator.""" return self._authenticator_id @@ -1360,7 +1360,7 @@ def get_credentials(self) -> list[Credential]: return [Credential.from_dict(credential) for credential in credential_data["value"]] @required_virtual_authenticator - def remove_credential(self, credential_id: Union[str, bytearray]) -> None: + def remove_credential(self, credential_id: str | bytearray) -> None: """Removes a credential from the authenticator. Example: @@ -1497,7 +1497,7 @@ def fedcm_dialog(self, timeout=5, poll_frequency=0.5, ignored_exceptions=None): if ignored_exceptions is None: ignored_exceptions = (NoAlertPresentException,) - def _check_fedcm() -> Optional[Dialog]: + def _check_fedcm() -> Dialog | None: try: dialog = Dialog(self) return dialog if dialog.type else None diff --git a/py/selenium/webdriver/safari/remote_connection.py b/py/selenium/webdriver/safari/remote_connection.py index cd8762da4ce92..03720d4ee0b75 100644 --- a/py/selenium/webdriver/safari/remote_connection.py +++ b/py/selenium/webdriver/safari/remote_connection.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.remote.client_config import ClientConfig @@ -29,8 +28,8 @@ def __init__( self, remote_server_addr: str, keep_alive: bool = True, - ignore_proxy: Optional[bool] = False, - client_config: Optional[ClientConfig] = None, + ignore_proxy: bool | None = False, + client_config: ClientConfig | None = None, ) -> None: client_config = client_config or ClientConfig( remote_server_addr=remote_server_addr, keep_alive=keep_alive, timeout=120 diff --git a/py/selenium/webdriver/safari/service.py b/py/selenium/webdriver/safari/service.py index 46595cf8da318..c0590f6d3156c 100644 --- a/py/selenium/webdriver/safari/service.py +++ b/py/selenium/webdriver/safari/service.py @@ -16,7 +16,6 @@ # under the License. from collections.abc import Mapping, Sequence -from typing import Optional from selenium.webdriver.common import service @@ -38,13 +37,13 @@ class Service(service.Service): def __init__( self, - executable_path: Optional[str] = None, + executable_path: str | None = None, port: int = 0, - service_args: Optional[Sequence[str]] = None, - env: Optional[Mapping[str, str]] = None, + service_args: Sequence[str] | None = None, + env: Mapping[str, str] | None = None, reuse_service=False, enable_logging: bool = False, - driver_path_env_key: Optional[str] = None, + driver_path_env_key: str | None = None, **kwargs, ) -> None: self._service_args = list(service_args or []) diff --git a/py/selenium/webdriver/safari/webdriver.py b/py/selenium/webdriver/safari/webdriver.py index ed16c6df90ccc..8f17758f1b96d 100644 --- a/py/selenium/webdriver/safari/webdriver.py +++ b/py/selenium/webdriver/safari/webdriver.py @@ -15,7 +15,6 @@ # specific language governing permissions and limitations # under the License. -from typing import Optional from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.driver_finder import DriverFinder @@ -31,8 +30,8 @@ class WebDriver(RemoteWebDriver): def __init__( self, keep_alive=True, - options: Optional[Options] = None, - service: Optional[Service] = None, + options: Options | None = None, + service: Service | None = None, ) -> None: """Create a new Safari driver instance and launch or find a running safaridriver service. diff --git a/py/selenium/webdriver/support/expected_conditions.py b/py/selenium/webdriver/support/expected_conditions.py index 0349d0cf84a02..e4412aef9d4a0 100644 --- a/py/selenium/webdriver/support/expected_conditions.py +++ b/py/selenium/webdriver/support/expected_conditions.py @@ -16,8 +16,8 @@ # under the License. import re -from collections.abc import Iterable -from typing import Any, Callable, Literal, TypeVar, Union +from collections.abc import Callable, Iterable +from typing import Any, Literal, TypeVar, Union from selenium.common.exceptions import ( NoAlertPresentException, @@ -163,7 +163,7 @@ def _predicate(driver: WebDriver): def visibility_of_element_located( locator: tuple[str, str], -) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]: +) -> Callable[[WebDriverOrWebElement], Literal[False] | WebElement]: """Check that an element is visible (present in DOM and width/height greater than zero). Args: @@ -188,7 +188,7 @@ def _predicate(driver: WebDriverOrWebElement): return _predicate -def visibility_of(element: WebElement) -> Callable[[Any], Union[Literal[False], WebElement]]: +def visibility_of(element: WebElement) -> Callable[[Any], Literal[False] | WebElement]: """Check that an element is visible (present in DOM and width/height greater than zero). Args: @@ -210,7 +210,7 @@ def _predicate(_): return _predicate -def _element_if_visible(element: WebElement, visibility: bool = True) -> Union[Literal[False], WebElement]: +def _element_if_visible(element: WebElement, visibility: bool = True) -> Literal[False] | WebElement: """Check if an element has the expected visibility state. Args: @@ -269,7 +269,7 @@ def _predicate(driver: WebDriverOrWebElement): def visibility_of_all_elements_located( locator: tuple[str, str], -) -> Callable[[WebDriverOrWebElement], Union[list[WebElement], Literal[False]]]: +) -> Callable[[WebDriverOrWebElement], list[WebElement] | Literal[False]]: """Check that all elements are visible (present in DOM and width/height greater than zero). Args: @@ -395,7 +395,7 @@ def _predicate(driver: WebDriverOrWebElement): def frame_to_be_available_and_switch_to_it( - locator: Union[tuple[str, str], str, WebElement], + locator: tuple[str, str] | str | WebElement, ) -> Callable[[WebDriver], bool]: """Check that the given frame is available and switch to it. @@ -425,8 +425,8 @@ def _predicate(driver: WebDriver): def invisibility_of_element_located( - locator: Union[WebElement, tuple[str, str]], -) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]: + locator: WebElement | tuple[str, str], +) -> Callable[[WebDriverOrWebElement], WebElement | bool]: """Check that an element is either invisible or not present on the DOM. Args: @@ -467,8 +467,8 @@ def _predicate(driver: WebDriverOrWebElement): def invisibility_of_element( - element: Union[WebElement, tuple[str, str]], -) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]: + element: WebElement | tuple[str, str], +) -> Callable[[WebDriverOrWebElement], WebElement | bool]: """Check that an element is either invisible or not present on the DOM. Args: @@ -489,8 +489,8 @@ def invisibility_of_element( def element_to_be_clickable( - mark: Union[WebElement, tuple[str, str]], -) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]: + mark: WebElement | tuple[str, str], +) -> Callable[[WebDriverOrWebElement], Literal[False] | WebElement]: """Check that an element is visible and enabled so it can be clicked. Args: @@ -692,7 +692,7 @@ def _predicate(driver: WebDriver): return _predicate -def alert_is_present() -> Callable[[WebDriver], Union[Alert, bool]]: +def alert_is_present() -> Callable[[WebDriver], Alert | bool]: """Check that an alert is present and switch to it. Returns: @@ -745,7 +745,7 @@ def _predicate(driver: WebDriverOrWebElement): return _predicate -def any_of(*expected_conditions: Callable[[D], T]) -> Callable[[D], Union[Literal[False], T]]: +def any_of(*expected_conditions: Callable[[D], T]) -> Callable[[D], Literal[False] | T]: """An expectation that any of multiple expected conditions is true. Equivalent to a logical 'OR'. Returns results of the first matching @@ -781,8 +781,8 @@ def any_of_condition(driver: D): def all_of( - *expected_conditions: Callable[[D], Union[T, Literal[False]]], -) -> Callable[[D], Union[list[T], Literal[False]]]: + *expected_conditions: Callable[[D], T | Literal[False]], +) -> Callable[[D], list[T] | Literal[False]]: """An expectation that all of multiple expected conditions is true. Equivalent to a logical 'AND'. When any ExpectedCondition is not met, diff --git a/py/selenium/webdriver/support/relative_locator.py b/py/selenium/webdriver/support/relative_locator.py index 3863cb3010ae9..697dab9354c25 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 NoReturn, Optional, Union, overload +from typing import NoReturn, overload from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.by import By, ByType @@ -79,7 +79,7 @@ class RelativeBy: LocatorType = dict[ByType, str] - def __init__(self, root: Optional[dict[ByType, str]] = None, filters: Optional[list] = None): + def __init__(self, root: dict[ByType, str] | None = None, filters: list | None = None): """Create a RelativeBy object (prefer using `locate_with` instead). Args: @@ -91,12 +91,12 @@ def __init__(self, root: Optional[dict[ByType, str]] = None, filters: Optional[l self.filters = filters or [] @overload - def above(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def above(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @overload def above(self, element_or_locator: None = None) -> "NoReturn": ... - def above(self, element_or_locator: Union[WebElement, LocatorType, None] = None) -> "RelativeBy": + def above(self, element_or_locator: WebElement | LocatorType | None = None) -> "RelativeBy": """Add a filter to look for elements above. Args: @@ -120,12 +120,12 @@ def above(self, element_or_locator: Union[WebElement, LocatorType, None] = None) return self @overload - def below(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def below(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @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: WebElement | dict | None = None) -> "RelativeBy": """Add a filter to look for elements below. Args: @@ -148,12 +148,12 @@ def below(self, element_or_locator: Union[WebElement, dict, None] = None) -> "Re return self @overload - def to_left_of(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def to_left_of(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @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: WebElement | dict | None = None) -> "RelativeBy": """Add a filter to look for elements to the left of. Args: @@ -176,12 +176,12 @@ def to_left_of(self, element_or_locator: Union[WebElement, dict, None] = None) - return self @overload - def to_right_of(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def to_right_of(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @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: WebElement | dict | None = None) -> "RelativeBy": """Add a filter to look for elements right of. Args: @@ -204,12 +204,12 @@ def to_right_of(self, element_or_locator: Union[WebElement, dict, None] = None) return self @overload - def straight_above(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def straight_above(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @overload def straight_above(self, element_or_locator: None = None) -> "NoReturn": ... - def straight_above(self, element_or_locator: Union[WebElement, LocatorType, None] = None) -> "RelativeBy": + def straight_above(self, element_or_locator: WebElement | LocatorType | None = None) -> "RelativeBy": """Add a filter to look for elements above. Args: @@ -222,12 +222,12 @@ def straight_above(self, element_or_locator: Union[WebElement, LocatorType, None return self @overload - def straight_below(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def straight_below(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @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: WebElement | dict | None = None) -> "RelativeBy": """Add a filter to look for elements below. Args: @@ -240,12 +240,12 @@ def straight_below(self, element_or_locator: Union[WebElement, dict, None] = Non return self @overload - def straight_left_of(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def straight_left_of(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @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: WebElement | dict | None = None) -> "RelativeBy": """Add a filter to look for elements to the left of. Args: @@ -258,12 +258,12 @@ def straight_left_of(self, element_or_locator: Union[WebElement, dict, None] = N return self @overload - def straight_right_of(self, element_or_locator: Union[WebElement, LocatorType]) -> "RelativeBy": ... + def straight_right_of(self, element_or_locator: WebElement | LocatorType) -> "RelativeBy": ... @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: WebElement | dict | None = None) -> "RelativeBy": """Add a filter to look for elements right of. Args: @@ -276,12 +276,12 @@ def straight_right_of(self, element_or_locator: Union[WebElement, dict, None] = return self @overload - def near(self, element_or_locator: Union[WebElement, LocatorType], distance: int = 50) -> "RelativeBy": ... + def near(self, element_or_locator: WebElement | LocatorType, distance: int = 50) -> "RelativeBy": ... @overload def near(self, element_or_locator: None = None, distance: int = 50) -> "NoReturn": ... - def near(self, element_or_locator: Union[WebElement, LocatorType, None] = None, distance: int = 50) -> "RelativeBy": + def near(self, element_or_locator: WebElement | LocatorType | None = None, distance: int = 50) -> "RelativeBy": """Add a filter to look for elements near. Args: diff --git a/py/selenium/webdriver/support/wait.py b/py/selenium/webdriver/support/wait.py index 88c1a276ce1fa..937e5ba55d138 100644 --- a/py/selenium/webdriver/support/wait.py +++ b/py/selenium/webdriver/support/wait.py @@ -16,7 +16,8 @@ # under the License. import time -from typing import Callable, Generic, Literal, Optional, TypeVar, Union +from collections.abc import Callable +from typing import Generic, Literal, TypeVar, Union from selenium.common.exceptions import NoSuchElementException, TimeoutException from selenium.types import WaitExcTypes @@ -36,7 +37,7 @@ def __init__( driver: D, timeout: float, poll_frequency: float = POLL_FREQUENCY, - ignored_exceptions: Optional[WaitExcTypes] = None, + ignored_exceptions: WaitExcTypes | None = None, ): """Constructor, takes a WebDriver instance and timeout in seconds. @@ -75,7 +76,7 @@ def __init__( def __repr__(self) -> str: return f'<{type(self).__module__}.{type(self).__name__} (session="{self._driver.session_id}")>' - def until(self, method: Callable[[D], Union[Literal[False], T]], message: str = "") -> T: + def until(self, method: Callable[[D], Literal[False] | T], message: str = "") -> T: """Wait until the method returns a value that is not False. Calls the method provided with the driver as an argument until the @@ -120,7 +121,7 @@ def until(self, method: Callable[[D], Union[Literal[False], T]], message: str = time.sleep(self._poll) raise TimeoutException(message, screen, stacktrace) - def until_not(self, method: Callable[[D], T], message: str = "") -> Union[T, Literal[True]]: + def until_not(self, method: Callable[[D], T], message: str = "") -> T | Literal[True]: """Wait until the method returns a value that is False. Calls the method provided with the driver as an argument until the diff --git a/py/selenium/webdriver/webkitgtk/service.py b/py/selenium/webdriver/webkitgtk/service.py index 996e798c2ab7c..672ffc1401776 100644 --- a/py/selenium/webdriver/webkitgtk/service.py +++ b/py/selenium/webdriver/webkitgtk/service.py @@ -18,7 +18,6 @@ import shutil import warnings from collections.abc import Mapping, Sequence -from typing import Optional from selenium.webdriver.common import service @@ -45,10 +44,10 @@ def __init__( self, executable_path: str = DEFAULT_EXECUTABLE_PATH, port: int = 0, - log_path: Optional[str] = None, - log_output: Optional[str] = None, - service_args: Optional[Sequence[str]] = None, - env: Optional[Mapping[str, str]] = None, + log_path: str | None = None, + log_output: str | None = None, + service_args: Sequence[str] | None = None, + env: Mapping[str, str] | None = None, **kwargs, ) -> None: self._service_args = list(service_args or []) diff --git a/py/selenium/webdriver/webkitgtk/webdriver.py b/py/selenium/webdriver/webkitgtk/webdriver.py index feccdedb9b0bb..a2ca221659fbe 100644 --- a/py/selenium/webdriver/webkitgtk/webdriver.py +++ b/py/selenium/webdriver/webkitgtk/webdriver.py @@ -16,7 +16,6 @@ # under the License. import http.client as http_client -from typing import Optional from selenium.webdriver.common.driver_finder import DriverFinder from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver @@ -30,7 +29,7 @@ class WebDriver(RemoteWebDriver): def __init__( self, options=None, - service: Optional[Service] = None, + service: Service | None = None, ): """Creates a new instance of the WebKitGTK driver. diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index 6cc8f84eadba1..e040cad65def5 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -17,7 +17,6 @@ import shutil from collections.abc import Mapping, Sequence -from typing import Optional from selenium.webdriver.common import service @@ -44,9 +43,9 @@ def __init__( self, executable_path: str = DEFAULT_EXECUTABLE_PATH, port: int = 0, - log_output: Optional[str] = None, - service_args: Optional[Sequence[str]] = None, - env: Optional[Mapping[str, str]] = None, + log_output: str | None = None, + service_args: Sequence[str] | None = None, + env: Mapping[str, str] | None = None, **kwargs, ): self._service_args = list(service_args or []) diff --git a/py/selenium/webdriver/wpewebkit/webdriver.py b/py/selenium/webdriver/wpewebkit/webdriver.py index ef5cf28dd7e5b..aa1cb3ce8683b 100644 --- a/py/selenium/webdriver/wpewebkit/webdriver.py +++ b/py/selenium/webdriver/wpewebkit/webdriver.py @@ -16,7 +16,6 @@ # under the License. import http.client as http_client -from typing import Optional from selenium.webdriver.common.driver_finder import DriverFinder from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver @@ -30,7 +29,7 @@ class WebDriver(RemoteWebDriver): def __init__( self, options=None, - service: Optional[Service] = None, + service: Service | None = None, ): """Creates a new instance of the WPEWebKit driver. diff --git a/py/test/unit/selenium/webdriver/remote/remote_connection_tests.py b/py/test/unit/selenium/webdriver/remote/remote_connection_tests.py index 3fcb12646fc0a..280a63541ce52 100644 --- a/py/test/unit/selenium/webdriver/remote/remote_connection_tests.py +++ b/py/test/unit/selenium/webdriver/remote/remote_connection_tests.py @@ -570,7 +570,7 @@ def test_proxy_auth_with_special_characters_url_encoded(): conn = remote_connection._get_connection_manager() assert isinstance(conn, ProxyManager) - expected_auth = base64.b64encode("user:passw#rd".encode()).decode() # Decoded password + expected_auth = base64.b64encode(b"user:passw#rd").decode() # Decoded password expected_headers = make_headers(proxy_basic_auth="user:passw#rd") # Unquoted password assert conn.proxy_headers == expected_headers