From e5ad8583e60899397eff4ccdae913992a8e272b0 Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:00:26 -0400 Subject: [PATCH 1/8] [py] Add properties (getter/setter) for service args --- py/selenium/webdriver/chrome/service.py | 6 ++--- py/selenium/webdriver/chromium/service.py | 23 +++++++++++----- py/selenium/webdriver/common/service.py | 1 + py/selenium/webdriver/edge/service.py | 18 ++++++++++--- py/selenium/webdriver/firefox/service.py | 27 +++++++++++++------ py/selenium/webdriver/ie/service.py | 31 +++++++++++++++------- py/selenium/webdriver/safari/service.py | 23 +++++++++++----- py/selenium/webdriver/webkitgtk/service.py | 21 +++++++++++---- py/selenium/webdriver/wpewebkit/service.py | 19 ++++++++++--- 9 files changed, 123 insertions(+), 46 deletions(-) diff --git a/py/selenium/webdriver/chrome/service.py b/py/selenium/webdriver/chrome/service.py index 036b35ef99623..8b2643357ec83 100644 --- a/py/selenium/webdriver/chrome/service.py +++ b/py/selenium/webdriver/chrome/service.py @@ -17,7 +17,7 @@ from collections.abc import Mapping -from typing import Optional +from typing import Optional, Sequence from selenium.types import SubprocessStdAlias from selenium.webdriver.chromium import service @@ -29,7 +29,7 @@ class Service(service.ChromiumService): :param executable_path: install path of the chromedriver executable, defaults to `chromedriver`. :param port: Port for the service to run on, defaults to 0 where the operating system will decide. - :param service_args: (Optional) List of args to be passed to the subprocess when launching the executable. + :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. :param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file. :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. """ @@ -38,7 +38,7 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[list[str]] = None, + service_args: Optional[Sequence[str]] = None, log_output: Optional[SubprocessStdAlias] = None, env: Optional[Mapping[str, str]] = None, **kwargs, diff --git a/py/selenium/webdriver/chromium/service.py b/py/selenium/webdriver/chromium/service.py index 9f50e21e8e36f..5b57726c33715 100644 --- a/py/selenium/webdriver/chromium/service.py +++ b/py/selenium/webdriver/chromium/service.py @@ -14,9 +14,10 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + from collections.abc import Mapping from io import IOBase -from typing import Optional +from typing import Optional, Sequence from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service @@ -28,7 +29,7 @@ class ChromiumService(service.Service): :param executable_path: install path of the executable. :param port: Port for the service to run on, defaults to 0 where the operating system will decide. - :param service_args: (Optional) List of args to be passed to the subprocess when launching the executable. + :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. :param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file. :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. :param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable. @@ -38,17 +39,17 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[list[str]] = None, + service_args: Optional[Sequence[str]] = None, log_output: Optional[SubprocessStdAlias] = None, env: Optional[Mapping[str, str]] = None, driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self.service_args = service_args or [] + self._service_args = service_args or [] driver_path_env_key = driver_path_env_key or "SE_CHROMEDRIVER" if isinstance(log_output, str): - self.service_args.append(f"--log-path={log_output}") + self._service_args.append(f"--log-path={log_output}") self.log_output: Optional[IOBase] = None elif isinstance(log_output, IOBase): self.log_output = log_output @@ -65,4 +66,14 @@ def __init__( ) def command_line_args(self) -> list[str]: - return [f"--port={self.port}"] + self.service_args + return [f"--port={self.port}"] + self._service_args + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value diff --git a/py/selenium/webdriver/common/service.py b/py/selenium/webdriver/common/service.py index e03adb6202f84..7dbaaacbf2861 100644 --- a/py/selenium/webdriver/common/service.py +++ b/py/selenium/webdriver/common/service.py @@ -14,6 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + import errno import logging import os diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index 7a152e58c6ca8..ba86fe009c847 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -16,7 +16,7 @@ # under the License. from collections.abc import Mapping -from typing import Optional +from typing import Optional, Sequence from selenium.types import SubprocessStdAlias from selenium.webdriver.chromium import service @@ -29,7 +29,7 @@ class Service(service.ChromiumService): :param executable_path: install path of the msedgedriver executable, defaults to `msedgedriver`. :param port: Port for the service to run on, defaults to 0 where the operating system will decide. :param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file. - :param service_args: (Optional) List of args to be passed to the subprocess when launching the executable. + :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. :param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable. """ @@ -39,12 +39,12 @@ def __init__( executable_path: Optional[str] = None, port: int = 0, log_output: Optional[SubprocessStdAlias] = None, - service_args: Optional[list[str]] = None, + service_args: Optional[Sequence[str]] = None, env: Optional[Mapping[str, str]] = None, driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self.service_args = service_args or [] + self._service_args = service_args or [] driver_path_env_key = driver_path_env_key or "SE_EDGEDRIVER" super().__init__( @@ -56,3 +56,13 @@ def __init__( driver_path_env_key=driver_path_env_key, **kwargs, ) + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value diff --git a/py/selenium/webdriver/firefox/service.py b/py/selenium/webdriver/firefox/service.py index 55ff4c6ec89e9..3c41d09110e6e 100644 --- a/py/selenium/webdriver/firefox/service.py +++ b/py/selenium/webdriver/firefox/service.py @@ -14,8 +14,9 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + from collections.abc import Mapping -from typing import Optional +from typing import Optional, Sequence from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service, utils @@ -27,7 +28,7 @@ class Service(service.Service): :param executable_path: install path of the geckodriver executable, defaults to `geckodriver`. :param port: Port for the service to run on, defaults to 0 where the operating system will decide. - :param service_args: (Optional) List of args to be passed to the subprocess when launching the executable. + :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. :param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file. :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. :param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable. @@ -37,13 +38,13 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[list[str]] = None, + service_args: Optional[Sequence[str]] = None, log_output: Optional[SubprocessStdAlias] = None, env: Optional[Mapping[str, str]] = None, driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self.service_args = service_args or [] + self._service_args = service_args or [] driver_path_env_key = driver_path_env_key or "SE_GECKODRIVER" super().__init__( @@ -56,9 +57,19 @@ def __init__( ) # Set a port for CDP - if "--connect-existing" not in self.service_args: - self.service_args.append("--websocket-port") - self.service_args.append(f"{utils.free_port()}") + if "--connect-existing" not in self._service_args: + self._service_args.append("--websocket-port") + self._service_args.append(f"{utils.free_port()}") def command_line_args(self) -> list[str]: - return ["--port", f"{self.port}"] + self.service_args + return ["--port", f"{self.port}"] + self._service_args + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value diff --git a/py/selenium/webdriver/ie/service.py b/py/selenium/webdriver/ie/service.py index 3b1be6be13307..c9b5779a36c89 100644 --- a/py/selenium/webdriver/ie/service.py +++ b/py/selenium/webdriver/ie/service.py @@ -14,7 +14,8 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -from typing import Optional + +from typing import Optional, Sequence from selenium.types import SubprocessStdAlias from selenium.webdriver.common import service @@ -28,7 +29,7 @@ def __init__( executable_path: Optional[str] = None, port: int = 0, host: Optional[str] = None, - service_args: Optional[list[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, @@ -39,19 +40,21 @@ def __init__( :Args: - executable_path : Path to the IEDriver - port : Port the service is running on - - host : IP address the service port is bound - - log_level : Level of logging of service, may be "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE". - Default is "FATAL". + - host : (Optional) IP address the service port is bound + - service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. + - log_level : (Optional) Level of logging of service, may be "FATAL", "ERROR", "WARN", "INFO", "DEBUG", + "TRACE". Default is "FATAL". - log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file. Default is "stdout". + - driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable. """ - self.service_args = service_args or [] + self._service_args = service_args or [] driver_path_env_key = driver_path_env_key or "SE_IEDRIVER" if host: - self.service_args.append(f"--host={host}") + self._service_args.append(f"--host={host}") if log_level: - self.service_args.append(f"--log-level={log_level}") + self._service_args.append(f"--log-level={log_level}") super().__init__( executable_path=executable_path, @@ -62,4 +65,14 @@ def __init__( ) def command_line_args(self) -> list[str]: - return [f"--port={self.port}"] + self.service_args + return [f"--port={self.port}"] + self._service_args + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value diff --git a/py/selenium/webdriver/safari/service.py b/py/selenium/webdriver/safari/service.py index 4d9f5a35e9774..f7ab9cf2b6273 100644 --- a/py/selenium/webdriver/safari/service.py +++ b/py/selenium/webdriver/safari/service.py @@ -15,9 +15,8 @@ # specific language governing permissions and limitations # under the License. - from collections.abc import Mapping -from typing import Optional +from typing import Optional, Sequence from selenium.webdriver.common import service @@ -28,7 +27,7 @@ class Service(service.Service): :param executable_path: install path of the safaridriver executable, defaults to `/usr/bin/safaridriver`. :param port: Port for the service to run on, defaults to 0 where the operating system will decide. - :param service_args: (Optional) List of args to be passed to the subprocess when launching the executable. + :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. :param enable_logging: (Optional) Enable logging of the service. Logs can be located at `~/Library/Logs/com.apple.WebDriver/` @@ -39,18 +38,18 @@ def __init__( self, executable_path: Optional[str] = None, port: int = 0, - service_args: Optional[list[str]] = None, + service_args: Optional[Sequence[str]] = None, env: Optional[Mapping[str, str]] = None, reuse_service=False, enable_logging: bool = False, driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self.service_args = service_args or [] + self._service_args = service_args or [] driver_path_env_key = driver_path_env_key or "SE_SAFARIDRIVER" if enable_logging: - self.service_args.append("--diagnose") + self._service_args.append("--diagnose") self.reuse_service = reuse_service super().__init__( @@ -62,7 +61,7 @@ def __init__( ) def command_line_args(self) -> list[str]: - return ["-p", f"{self.port}"] + self.service_args + return ["-p", f"{self.port}"] + self._service_args @property def service_url(self) -> str: @@ -78,3 +77,13 @@ def reuse_service(self, reuse: bool) -> None: if not isinstance(reuse, bool): raise TypeError("reuse must be a boolean") self._reuse_service = reuse + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value diff --git a/py/selenium/webdriver/webkitgtk/service.py b/py/selenium/webdriver/webkitgtk/service.py index e7f300019c838..d6fad7fcb8328 100644 --- a/py/selenium/webdriver/webkitgtk/service.py +++ b/py/selenium/webdriver/webkitgtk/service.py @@ -14,10 +14,11 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + import shutil import warnings from collections.abc import Mapping -from typing import Optional +from typing import Optional, Sequence from selenium.webdriver.common import service @@ -31,7 +32,7 @@ class Service(service.Service): :param executable_path: install path of the WebKitWebDriver executable, defaults to the first `WebKitWebDriver` in `$PATH`. :param port: Port for the service to run on, defaults to 0 where the operating system will decide. - :param service_args: (Optional) List of args to be passed to the subprocess when launching the executable. + :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. :param log_output: (Optional) File path for the file to be opened and passed as the subprocess stdout/stderr handler. :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. @@ -43,11 +44,11 @@ def __init__( port: int = 0, log_path: Optional[str] = None, log_output: Optional[str] = None, - service_args: Optional[list[str]] = None, + service_args: Optional[Sequence[str]] = None, env: Optional[Mapping[str, str]] = None, **kwargs, ) -> None: - self.service_args = service_args or [] + self._service_args = service_args or [] if log_path is not None: warnings.warn("log_path is deprecated, use log_output instead", DeprecationWarning, stacklevel=2) log_path = open(log_path, "wb") @@ -61,4 +62,14 @@ def __init__( ) def command_line_args(self) -> list[str]: - return ["-p", f"{self.port}"] + self.service_args + return ["-p", f"{self.port}"] + self._service_args + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index 1f2b244807583..213d4365970a4 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -14,9 +14,10 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. + import shutil from collections.abc import Mapping -from typing import Optional +from typing import Optional, Sequence from selenium.webdriver.common import service @@ -30,7 +31,7 @@ class Service(service.Service): :param executable_path: install path of the WPEWebDriver executable, defaults to the first `WPEWebDriver` in `$PATH`. :param port: Port for the service to run on, defaults to 0 where the operating system will decide. - :param service_args: (Optional) List of args to be passed to the subprocess when launching the executable. + :param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable. :param log_output: (Optional) File path for the file to be opened and passed as the subprocess stdout/stderr handler. :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`. @@ -41,7 +42,7 @@ def __init__( executable_path: str = DEFAULT_EXECUTABLE_PATH, port: int = 0, log_output: Optional[str] = None, - service_args: Optional[list[str]] = None, + service_args: Optional[Sequence[str]] = None, env: Optional[Mapping[str, str]] = None, **kwargs, ): @@ -55,4 +56,14 @@ def __init__( ) def command_line_args(self) -> list[str]: - return ["-p", f"{self.port}"] + self.service_args + return ["-p", f"{self.port}"] + self._service_args + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value From 0074e0b6464ea9e1a9c07153e2a4ff29d1421e15 Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:21:56 -0400 Subject: [PATCH 2/8] [py] Check for string instance also --- py/selenium/webdriver/chrome/service.py | 12 ++++++++++++ py/selenium/webdriver/chromium/service.py | 2 +- py/selenium/webdriver/firefox/service.py | 2 +- py/selenium/webdriver/ie/service.py | 2 +- py/selenium/webdriver/safari/service.py | 2 +- py/selenium/webdriver/webkitgtk/service.py | 3 ++- py/selenium/webdriver/wpewebkit/service.py | 3 ++- 7 files changed, 20 insertions(+), 6 deletions(-) diff --git a/py/selenium/webdriver/chrome/service.py b/py/selenium/webdriver/chrome/service.py index 8b2643357ec83..6ae7e22e15392 100644 --- a/py/selenium/webdriver/chrome/service.py +++ b/py/selenium/webdriver/chrome/service.py @@ -43,6 +43,8 @@ def __init__( env: Optional[Mapping[str, str]] = None, **kwargs, ) -> None: + self._service_args = service_args or [] + super().__init__( executable_path=executable_path, port=port, @@ -51,3 +53,13 @@ def __init__( env=env, **kwargs, ) + + @property + def service_args(self) -> Sequence[str]: + return self._service_args + + @service_args.setter + def service_args(self, value: Sequence[str]): + if not isinstance(value, Sequence): + raise TypeError("service_args must be a sequence") + self._service_args = value diff --git a/py/selenium/webdriver/chromium/service.py b/py/selenium/webdriver/chromium/service.py index 5b57726c33715..04adb587a0c43 100644 --- a/py/selenium/webdriver/chromium/service.py +++ b/py/selenium/webdriver/chromium/service.py @@ -74,6 +74,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value diff --git a/py/selenium/webdriver/firefox/service.py b/py/selenium/webdriver/firefox/service.py index 3c41d09110e6e..d9873bd3b3156 100644 --- a/py/selenium/webdriver/firefox/service.py +++ b/py/selenium/webdriver/firefox/service.py @@ -70,6 +70,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value diff --git a/py/selenium/webdriver/ie/service.py b/py/selenium/webdriver/ie/service.py index c9b5779a36c89..2e332447574a9 100644 --- a/py/selenium/webdriver/ie/service.py +++ b/py/selenium/webdriver/ie/service.py @@ -73,6 +73,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value diff --git a/py/selenium/webdriver/safari/service.py b/py/selenium/webdriver/safari/service.py index f7ab9cf2b6273..11e654ab2549b 100644 --- a/py/selenium/webdriver/safari/service.py +++ b/py/selenium/webdriver/safari/service.py @@ -84,6 +84,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value diff --git a/py/selenium/webdriver/webkitgtk/service.py b/py/selenium/webdriver/webkitgtk/service.py index d6fad7fcb8328..c30ceb70879ac 100644 --- a/py/selenium/webdriver/webkitgtk/service.py +++ b/py/selenium/webdriver/webkitgtk/service.py @@ -53,6 +53,7 @@ def __init__( warnings.warn("log_path is deprecated, use log_output instead", DeprecationWarning, stacklevel=2) log_path = open(log_path, "wb") log_output = open(log_output, "wb") if log_output else None + super().__init__( executable_path=executable_path, port=port, @@ -70,6 +71,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index 213d4365970a4..231e734b3120f 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -47,6 +47,7 @@ def __init__( **kwargs, ): self.service_args = service_args or [] + super().__init__( executable_path=executable_path, port=port, @@ -64,6 +65,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value From 67272a217679112f3e304d65ff7925de100d72e6 Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:23:12 -0400 Subject: [PATCH 3/8] [py] Assign to private --- py/selenium/webdriver/wpewebkit/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index 231e734b3120f..c9a88a2797be0 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -46,7 +46,7 @@ def __init__( env: Optional[Mapping[str, str]] = None, **kwargs, ): - self.service_args = service_args or [] + self._service_args = service_args or [] super().__init__( executable_path=executable_path, From c657676dc0f5279d030173a789b23370cf7726ec Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:27:10 -0400 Subject: [PATCH 4/8] [py] Convert args to list --- py/selenium/webdriver/chromium/service.py | 2 +- py/selenium/webdriver/edge/service.py | 2 +- py/selenium/webdriver/firefox/service.py | 2 +- py/selenium/webdriver/ie/service.py | 2 +- py/selenium/webdriver/safari/service.py | 2 +- py/selenium/webdriver/webkitgtk/service.py | 2 +- py/selenium/webdriver/wpewebkit/service.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/py/selenium/webdriver/chromium/service.py b/py/selenium/webdriver/chromium/service.py index 04adb587a0c43..7c265ba848be8 100644 --- a/py/selenium/webdriver/chromium/service.py +++ b/py/selenium/webdriver/chromium/service.py @@ -45,7 +45,7 @@ def __init__( driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self._service_args = service_args or [] + self._service_args = list(service_args or []) driver_path_env_key = driver_path_env_key or "SE_CHROMEDRIVER" if isinstance(log_output, str): diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index ba86fe009c847..3a9ec4cee3b93 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -44,7 +44,7 @@ def __init__( driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self._service_args = service_args or [] + self._service_args = list(service_args or []) driver_path_env_key = driver_path_env_key or "SE_EDGEDRIVER" super().__init__( diff --git a/py/selenium/webdriver/firefox/service.py b/py/selenium/webdriver/firefox/service.py index d9873bd3b3156..bb07b11915669 100644 --- a/py/selenium/webdriver/firefox/service.py +++ b/py/selenium/webdriver/firefox/service.py @@ -44,7 +44,7 @@ def __init__( driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self._service_args = service_args or [] + self._service_args = list(service_args or []) driver_path_env_key = driver_path_env_key or "SE_GECKODRIVER" super().__init__( diff --git a/py/selenium/webdriver/ie/service.py b/py/selenium/webdriver/ie/service.py index 2e332447574a9..d5cc77aa22477 100644 --- a/py/selenium/webdriver/ie/service.py +++ b/py/selenium/webdriver/ie/service.py @@ -48,7 +48,7 @@ def __init__( Default is "stdout". - driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable. """ - self._service_args = service_args or [] + self._service_args = list(service_args or []) driver_path_env_key = driver_path_env_key or "SE_IEDRIVER" if host: diff --git a/py/selenium/webdriver/safari/service.py b/py/selenium/webdriver/safari/service.py index 11e654ab2549b..4a373e7d4dc27 100644 --- a/py/selenium/webdriver/safari/service.py +++ b/py/selenium/webdriver/safari/service.py @@ -45,7 +45,7 @@ def __init__( driver_path_env_key: Optional[str] = None, **kwargs, ) -> None: - self._service_args = service_args or [] + self._service_args = list(service_args or []) driver_path_env_key = driver_path_env_key or "SE_SAFARIDRIVER" if enable_logging: diff --git a/py/selenium/webdriver/webkitgtk/service.py b/py/selenium/webdriver/webkitgtk/service.py index c30ceb70879ac..6c95648598f4e 100644 --- a/py/selenium/webdriver/webkitgtk/service.py +++ b/py/selenium/webdriver/webkitgtk/service.py @@ -48,7 +48,7 @@ def __init__( env: Optional[Mapping[str, str]] = None, **kwargs, ) -> None: - self._service_args = service_args or [] + self._service_args = list(service_args or []) if log_path is not None: warnings.warn("log_path is deprecated, use log_output instead", DeprecationWarning, stacklevel=2) log_path = open(log_path, "wb") diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index c9a88a2797be0..e24eec6073403 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -46,7 +46,7 @@ def __init__( env: Optional[Mapping[str, str]] = None, **kwargs, ): - self._service_args = service_args or [] + self._service_args = list(service_args or []) super().__init__( executable_path=executable_path, From ac0f6e50a04cc715650a8018d7880ae1ff162343 Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:30:02 -0400 Subject: [PATCH 5/8] [py] Add instance check --- py/selenium/webdriver/edge/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index 3a9ec4cee3b93..d2104b367595a 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -63,6 +63,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value From 64a076849989ee4682f2e6af61ad488b5b7fdf9e Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:33:19 -0400 Subject: [PATCH 6/8] [py] Add instance check --- py/selenium/webdriver/chrome/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/py/selenium/webdriver/chrome/service.py b/py/selenium/webdriver/chrome/service.py index 6ae7e22e15392..34c169bb4181b 100644 --- a/py/selenium/webdriver/chrome/service.py +++ b/py/selenium/webdriver/chrome/service.py @@ -60,6 +60,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence): + if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") self._service_args = value From e54bffe44b1f9f0d1dc4e58bd736af51c2488d47 Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:36:34 -0400 Subject: [PATCH 7/8] [py] convert args to list --- py/selenium/webdriver/chrome/service.py | 2 +- py/selenium/webdriver/chromium/service.py | 2 +- py/selenium/webdriver/edge/service.py | 2 +- py/selenium/webdriver/firefox/service.py | 2 +- py/selenium/webdriver/ie/service.py | 2 +- py/selenium/webdriver/safari/service.py | 2 +- py/selenium/webdriver/webkitgtk/service.py | 2 +- py/selenium/webdriver/wpewebkit/service.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/py/selenium/webdriver/chrome/service.py b/py/selenium/webdriver/chrome/service.py index 34c169bb4181b..e7d984e732920 100644 --- a/py/selenium/webdriver/chrome/service.py +++ b/py/selenium/webdriver/chrome/service.py @@ -62,4 +62,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) diff --git a/py/selenium/webdriver/chromium/service.py b/py/selenium/webdriver/chromium/service.py index 7c265ba848be8..008b071685ef5 100644 --- a/py/selenium/webdriver/chromium/service.py +++ b/py/selenium/webdriver/chromium/service.py @@ -76,4 +76,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index d2104b367595a..d2c7bb30377eb 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -65,4 +65,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) diff --git a/py/selenium/webdriver/firefox/service.py b/py/selenium/webdriver/firefox/service.py index bb07b11915669..7f395dffb05f7 100644 --- a/py/selenium/webdriver/firefox/service.py +++ b/py/selenium/webdriver/firefox/service.py @@ -72,4 +72,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) diff --git a/py/selenium/webdriver/ie/service.py b/py/selenium/webdriver/ie/service.py index d5cc77aa22477..6c8e2465033b8 100644 --- a/py/selenium/webdriver/ie/service.py +++ b/py/selenium/webdriver/ie/service.py @@ -75,4 +75,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) diff --git a/py/selenium/webdriver/safari/service.py b/py/selenium/webdriver/safari/service.py index 4a373e7d4dc27..18d4a47dc1733 100644 --- a/py/selenium/webdriver/safari/service.py +++ b/py/selenium/webdriver/safari/service.py @@ -86,4 +86,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) diff --git a/py/selenium/webdriver/webkitgtk/service.py b/py/selenium/webdriver/webkitgtk/service.py index 6c95648598f4e..a19d51c49f7bf 100644 --- a/py/selenium/webdriver/webkitgtk/service.py +++ b/py/selenium/webdriver/webkitgtk/service.py @@ -73,4 +73,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index e24eec6073403..f7234d2544ac1 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -67,4 +67,4 @@ def service_args(self) -> Sequence[str]: def service_args(self, value: Sequence[str]): if not isinstance(value, Sequence) or isinstance(value, str): raise TypeError("service_args must be a sequence") - self._service_args = value + self._service_args = list(value) From 9653812cea58b8bb74a625d23535f229941c5a07 Mon Sep 17 00:00:00 2001 From: Corey Goldberg <1113081+cgoldberg@users.noreply.github.com> Date: Wed, 11 Jun 2025 14:41:32 -0400 Subject: [PATCH 8/8] [py] Reverse validation logic --- py/selenium/webdriver/chrome/service.py | 2 +- py/selenium/webdriver/chromium/service.py | 2 +- py/selenium/webdriver/edge/service.py | 2 +- py/selenium/webdriver/firefox/service.py | 2 +- py/selenium/webdriver/ie/service.py | 2 +- py/selenium/webdriver/safari/service.py | 2 +- py/selenium/webdriver/webkitgtk/service.py | 2 +- py/selenium/webdriver/wpewebkit/service.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/py/selenium/webdriver/chrome/service.py b/py/selenium/webdriver/chrome/service.py index e7d984e732920..a16692664ba60 100644 --- a/py/selenium/webdriver/chrome/service.py +++ b/py/selenium/webdriver/chrome/service.py @@ -60,6 +60,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) diff --git a/py/selenium/webdriver/chromium/service.py b/py/selenium/webdriver/chromium/service.py index 008b071685ef5..a428648f8ef9b 100644 --- a/py/selenium/webdriver/chromium/service.py +++ b/py/selenium/webdriver/chromium/service.py @@ -74,6 +74,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) diff --git a/py/selenium/webdriver/edge/service.py b/py/selenium/webdriver/edge/service.py index d2c7bb30377eb..f9171e0d46ba1 100644 --- a/py/selenium/webdriver/edge/service.py +++ b/py/selenium/webdriver/edge/service.py @@ -63,6 +63,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) diff --git a/py/selenium/webdriver/firefox/service.py b/py/selenium/webdriver/firefox/service.py index 7f395dffb05f7..4e0180d1100c5 100644 --- a/py/selenium/webdriver/firefox/service.py +++ b/py/selenium/webdriver/firefox/service.py @@ -70,6 +70,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) diff --git a/py/selenium/webdriver/ie/service.py b/py/selenium/webdriver/ie/service.py index 6c8e2465033b8..53b3f4bd1c237 100644 --- a/py/selenium/webdriver/ie/service.py +++ b/py/selenium/webdriver/ie/service.py @@ -73,6 +73,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) diff --git a/py/selenium/webdriver/safari/service.py b/py/selenium/webdriver/safari/service.py index 18d4a47dc1733..89c3afe53d203 100644 --- a/py/selenium/webdriver/safari/service.py +++ b/py/selenium/webdriver/safari/service.py @@ -84,6 +84,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) diff --git a/py/selenium/webdriver/webkitgtk/service.py b/py/selenium/webdriver/webkitgtk/service.py index a19d51c49f7bf..5e7d181aa2dcc 100644 --- a/py/selenium/webdriver/webkitgtk/service.py +++ b/py/selenium/webdriver/webkitgtk/service.py @@ -71,6 +71,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value) diff --git a/py/selenium/webdriver/wpewebkit/service.py b/py/selenium/webdriver/wpewebkit/service.py index f7234d2544ac1..2941633aa91bb 100644 --- a/py/selenium/webdriver/wpewebkit/service.py +++ b/py/selenium/webdriver/wpewebkit/service.py @@ -65,6 +65,6 @@ def service_args(self) -> Sequence[str]: @service_args.setter def service_args(self, value: Sequence[str]): - if not isinstance(value, Sequence) or isinstance(value, str): + if isinstance(value, str) or not isinstance(value, Sequence): raise TypeError("service_args must be a sequence") self._service_args = list(value)