Skip to content

Commit 4a6303e

Browse files
authored
[py] Add properties (getter/setter) for service args (SeleniumHQ#15889)
1 parent 9be77c1 commit 4a6303e

File tree

9 files changed

+138
-47
lines changed

9 files changed

+138
-47
lines changed

py/selenium/webdriver/chrome/service.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818

1919
from collections.abc import Mapping
20-
from typing import Optional
20+
from typing import Optional, Sequence
2121

2222
from selenium.types import SubprocessStdAlias
2323
from selenium.webdriver.chromium import service
@@ -29,7 +29,7 @@ class Service(service.ChromiumService):
2929
3030
:param executable_path: install path of the chromedriver executable, defaults to `chromedriver`.
3131
:param port: Port for the service to run on, defaults to 0 where the operating system will decide.
32-
:param service_args: (Optional) List of args to be passed to the subprocess when launching the executable.
32+
:param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable.
3333
:param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file.
3434
:param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`.
3535
"""
@@ -38,11 +38,13 @@ def __init__(
3838
self,
3939
executable_path: Optional[str] = None,
4040
port: int = 0,
41-
service_args: Optional[list[str]] = None,
41+
service_args: Optional[Sequence[str]] = None,
4242
log_output: Optional[SubprocessStdAlias] = None,
4343
env: Optional[Mapping[str, str]] = None,
4444
**kwargs,
4545
) -> None:
46+
self._service_args = service_args or []
47+
4648
super().__init__(
4749
executable_path=executable_path,
4850
port=port,
@@ -51,3 +53,13 @@ def __init__(
5153
env=env,
5254
**kwargs,
5355
)
56+
57+
@property
58+
def service_args(self) -> Sequence[str]:
59+
return self._service_args
60+
61+
@service_args.setter
62+
def service_args(self, value: Sequence[str]):
63+
if isinstance(value, str) or not isinstance(value, Sequence):
64+
raise TypeError("service_args must be a sequence")
65+
self._service_args = list(value)

py/selenium/webdriver/chromium/service.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17+
1718
from collections.abc import Mapping
1819
from io import IOBase
19-
from typing import Optional
20+
from typing import Optional, Sequence
2021

2122
from selenium.types import SubprocessStdAlias
2223
from selenium.webdriver.common import service
@@ -28,7 +29,7 @@ class ChromiumService(service.Service):
2829
2930
:param executable_path: install path of the executable.
3031
:param port: Port for the service to run on, defaults to 0 where the operating system will decide.
31-
:param service_args: (Optional) List of args to be passed to the subprocess when launching the executable.
32+
:param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable.
3233
:param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file.
3334
:param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`.
3435
:param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable.
@@ -38,17 +39,17 @@ def __init__(
3839
self,
3940
executable_path: Optional[str] = None,
4041
port: int = 0,
41-
service_args: Optional[list[str]] = None,
42+
service_args: Optional[Sequence[str]] = None,
4243
log_output: Optional[SubprocessStdAlias] = None,
4344
env: Optional[Mapping[str, str]] = None,
4445
driver_path_env_key: Optional[str] = None,
4546
**kwargs,
4647
) -> None:
47-
self.service_args = service_args or []
48+
self._service_args = list(service_args or [])
4849
driver_path_env_key = driver_path_env_key or "SE_CHROMEDRIVER"
4950

5051
if isinstance(log_output, str):
51-
self.service_args.append(f"--log-path={log_output}")
52+
self._service_args.append(f"--log-path={log_output}")
5253
self.log_output: Optional[IOBase] = None
5354
elif isinstance(log_output, IOBase):
5455
self.log_output = log_output
@@ -65,4 +66,14 @@ def __init__(
6566
)
6667

6768
def command_line_args(self) -> list[str]:
68-
return [f"--port={self.port}"] + self.service_args
69+
return [f"--port={self.port}"] + self._service_args
70+
71+
@property
72+
def service_args(self) -> Sequence[str]:
73+
return self._service_args
74+
75+
@service_args.setter
76+
def service_args(self, value: Sequence[str]):
77+
if isinstance(value, str) or not isinstance(value, Sequence):
78+
raise TypeError("service_args must be a sequence")
79+
self._service_args = list(value)

py/selenium/webdriver/common/service.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17+
1718
import errno
1819
import logging
1920
import os

py/selenium/webdriver/edge/service.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
# under the License.
1717

1818
from collections.abc import Mapping
19-
from typing import Optional
19+
from typing import Optional, Sequence
2020

2121
from selenium.types import SubprocessStdAlias
2222
from selenium.webdriver.chromium import service
@@ -29,7 +29,7 @@ class Service(service.ChromiumService):
2929
:param executable_path: install path of the msedgedriver executable, defaults to `msedgedriver`.
3030
:param port: Port for the service to run on, defaults to 0 where the operating system will decide.
3131
:param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file.
32-
:param service_args: (Optional) List of args to be passed to the subprocess when launching the executable.
32+
:param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable.
3333
:param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`.
3434
:param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable.
3535
"""
@@ -39,12 +39,12 @@ def __init__(
3939
executable_path: Optional[str] = None,
4040
port: int = 0,
4141
log_output: Optional[SubprocessStdAlias] = None,
42-
service_args: Optional[list[str]] = None,
42+
service_args: Optional[Sequence[str]] = None,
4343
env: Optional[Mapping[str, str]] = None,
4444
driver_path_env_key: Optional[str] = None,
4545
**kwargs,
4646
) -> None:
47-
self.service_args = service_args or []
47+
self._service_args = list(service_args or [])
4848
driver_path_env_key = driver_path_env_key or "SE_EDGEDRIVER"
4949

5050
super().__init__(
@@ -56,3 +56,13 @@ def __init__(
5656
driver_path_env_key=driver_path_env_key,
5757
**kwargs,
5858
)
59+
60+
@property
61+
def service_args(self) -> Sequence[str]:
62+
return self._service_args
63+
64+
@service_args.setter
65+
def service_args(self, value: Sequence[str]):
66+
if isinstance(value, str) or not isinstance(value, Sequence):
67+
raise TypeError("service_args must be a sequence")
68+
self._service_args = list(value)

py/selenium/webdriver/firefox/service.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17+
1718
from collections.abc import Mapping
18-
from typing import Optional
19+
from typing import Optional, Sequence
1920

2021
from selenium.types import SubprocessStdAlias
2122
from selenium.webdriver.common import service, utils
@@ -27,7 +28,7 @@ class Service(service.Service):
2728
2829
:param executable_path: install path of the geckodriver executable, defaults to `geckodriver`.
2930
:param port: Port for the service to run on, defaults to 0 where the operating system will decide.
30-
:param service_args: (Optional) List of args to be passed to the subprocess when launching the executable.
31+
:param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable.
3132
:param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file.
3233
:param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`.
3334
:param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable.
@@ -37,13 +38,13 @@ def __init__(
3738
self,
3839
executable_path: Optional[str] = None,
3940
port: int = 0,
40-
service_args: Optional[list[str]] = None,
41+
service_args: Optional[Sequence[str]] = None,
4142
log_output: Optional[SubprocessStdAlias] = None,
4243
env: Optional[Mapping[str, str]] = None,
4344
driver_path_env_key: Optional[str] = None,
4445
**kwargs,
4546
) -> None:
46-
self.service_args = service_args or []
47+
self._service_args = list(service_args or [])
4748
driver_path_env_key = driver_path_env_key or "SE_GECKODRIVER"
4849

4950
super().__init__(
@@ -56,9 +57,19 @@ def __init__(
5657
)
5758

5859
# Set a port for CDP
59-
if "--connect-existing" not in self.service_args:
60-
self.service_args.append("--websocket-port")
61-
self.service_args.append(f"{utils.free_port()}")
60+
if "--connect-existing" not in self._service_args:
61+
self._service_args.append("--websocket-port")
62+
self._service_args.append(f"{utils.free_port()}")
6263

6364
def command_line_args(self) -> list[str]:
64-
return ["--port", f"{self.port}"] + self.service_args
65+
return ["--port", f"{self.port}"] + self._service_args
66+
67+
@property
68+
def service_args(self) -> Sequence[str]:
69+
return self._service_args
70+
71+
@service_args.setter
72+
def service_args(self, value: Sequence[str]):
73+
if isinstance(value, str) or not isinstance(value, Sequence):
74+
raise TypeError("service_args must be a sequence")
75+
self._service_args = list(value)

py/selenium/webdriver/ie/service.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17-
from typing import Optional
17+
18+
from typing import Optional, Sequence
1819

1920
from selenium.types import SubprocessStdAlias
2021
from selenium.webdriver.common import service
@@ -28,7 +29,7 @@ def __init__(
2829
executable_path: Optional[str] = None,
2930
port: int = 0,
3031
host: Optional[str] = None,
31-
service_args: Optional[list[str]] = None,
32+
service_args: Optional[Sequence[str]] = None,
3233
log_level: Optional[str] = None,
3334
log_output: Optional[SubprocessStdAlias] = None,
3435
driver_path_env_key: Optional[str] = None,
@@ -39,19 +40,21 @@ def __init__(
3940
:Args:
4041
- executable_path : Path to the IEDriver
4142
- port : Port the service is running on
42-
- host : IP address the service port is bound
43-
- log_level : Level of logging of service, may be "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE".
44-
Default is "FATAL".
43+
- host : (Optional) IP address the service port is bound
44+
- service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable.
45+
- log_level : (Optional) Level of logging of service, may be "FATAL", "ERROR", "WARN", "INFO", "DEBUG",
46+
"TRACE". Default is "FATAL".
4547
- log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file.
4648
Default is "stdout".
49+
- driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable.
4750
"""
48-
self.service_args = service_args or []
51+
self._service_args = list(service_args or [])
4952
driver_path_env_key = driver_path_env_key or "SE_IEDRIVER"
5053

5154
if host:
52-
self.service_args.append(f"--host={host}")
55+
self._service_args.append(f"--host={host}")
5356
if log_level:
54-
self.service_args.append(f"--log-level={log_level}")
57+
self._service_args.append(f"--log-level={log_level}")
5558

5659
super().__init__(
5760
executable_path=executable_path,
@@ -62,4 +65,14 @@ def __init__(
6265
)
6366

6467
def command_line_args(self) -> list[str]:
65-
return [f"--port={self.port}"] + self.service_args
68+
return [f"--port={self.port}"] + self._service_args
69+
70+
@property
71+
def service_args(self) -> Sequence[str]:
72+
return self._service_args
73+
74+
@service_args.setter
75+
def service_args(self, value: Sequence[str]):
76+
if isinstance(value, str) or not isinstance(value, Sequence):
77+
raise TypeError("service_args must be a sequence")
78+
self._service_args = list(value)

py/selenium/webdriver/safari/service.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
1918
from collections.abc import Mapping
20-
from typing import Optional
19+
from typing import Optional, Sequence
2120

2221
from selenium.webdriver.common import service
2322

@@ -28,7 +27,7 @@ class Service(service.Service):
2827
2928
:param executable_path: install path of the safaridriver executable, defaults to `/usr/bin/safaridriver`.
3029
:param port: Port for the service to run on, defaults to 0 where the operating system will decide.
31-
:param service_args: (Optional) List of args to be passed to the subprocess when launching the executable.
30+
:param service_args: (Optional) Sequence of args to be passed to the subprocess when launching the executable.
3231
:param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`.
3332
:param enable_logging: (Optional) Enable logging of the service. Logs can be located at
3433
`~/Library/Logs/com.apple.WebDriver/`
@@ -39,18 +38,18 @@ def __init__(
3938
self,
4039
executable_path: Optional[str] = None,
4140
port: int = 0,
42-
service_args: Optional[list[str]] = None,
41+
service_args: Optional[Sequence[str]] = None,
4342
env: Optional[Mapping[str, str]] = None,
4443
reuse_service=False,
4544
enable_logging: bool = False,
4645
driver_path_env_key: Optional[str] = None,
4746
**kwargs,
4847
) -> None:
49-
self.service_args = service_args or []
48+
self._service_args = list(service_args or [])
5049
driver_path_env_key = driver_path_env_key or "SE_SAFARIDRIVER"
5150

5251
if enable_logging:
53-
self.service_args.append("--diagnose")
52+
self._service_args.append("--diagnose")
5453

5554
self.reuse_service = reuse_service
5655
super().__init__(
@@ -62,7 +61,7 @@ def __init__(
6261
)
6362

6463
def command_line_args(self) -> list[str]:
65-
return ["-p", f"{self.port}"] + self.service_args
64+
return ["-p", f"{self.port}"] + self._service_args
6665

6766
@property
6867
def service_url(self) -> str:
@@ -78,3 +77,13 @@ def reuse_service(self, reuse: bool) -> None:
7877
if not isinstance(reuse, bool):
7978
raise TypeError("reuse must be a boolean")
8079
self._reuse_service = reuse
80+
81+
@property
82+
def service_args(self) -> Sequence[str]:
83+
return self._service_args
84+
85+
@service_args.setter
86+
def service_args(self, value: Sequence[str]):
87+
if isinstance(value, str) or not isinstance(value, Sequence):
88+
raise TypeError("service_args must be a sequence")
89+
self._service_args = list(value)

0 commit comments

Comments
 (0)