Skip to content

Commit 7d82d92

Browse files
authored
Merge branch 'trunk' into greedy-slot-selector
2 parents 9f5ff01 + 3323450 commit 7d82d92

File tree

13 files changed

+218
-85
lines changed

13 files changed

+218
-85
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/remote/errorhandler.py

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

18+
import json
1819
from typing import Any
1920

2021
from selenium.common.exceptions import (
@@ -161,21 +162,20 @@ def check_response(self, response: dict[str, Any]) -> None:
161162
if isinstance(status, int):
162163
value_json = response.get("value", None)
163164
if value_json and isinstance(value_json, str):
164-
import json
165-
166165
try:
167166
value = json.loads(value_json)
168-
if len(value) == 1:
169-
value = value["value"]
170-
status = value.get("error", None)
171-
if not status:
172-
status = value.get("status", ErrorCode.UNKNOWN_ERROR)
173-
message = value.get("value") or value.get("message")
174-
if not isinstance(message, str):
175-
value = message
176-
message = message.get("message")
177-
else:
178-
message = value.get("message", None)
167+
if isinstance(value, dict):
168+
if len(value) == 1:
169+
value = value["value"]
170+
status = value.get("error", None)
171+
if not status:
172+
status = value.get("status", ErrorCode.UNKNOWN_ERROR)
173+
message = value.get("value") or value.get("message")
174+
if not isinstance(message, str):
175+
value = message
176+
message = message.get("message")
177+
else:
178+
message = value.get("message", None)
179179
except ValueError:
180180
pass
181181

0 commit comments

Comments
 (0)