Skip to content

Commit 8d92f98

Browse files
committed
refactor: refactor type hints from List to built-in list for consistency
1 parent 23f7155 commit 8d92f98

40 files changed

Lines changed: 256 additions & 234 deletions

pydoll/browser/chromium/base.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from abc import ABC, abstractmethod
33
from functools import partial
44
from random import randint
5-
from typing import Any, Callable, List, Optional, TypeVar
5+
from typing import Any, Callable, Optional, TypeVar
66

77
from pydoll.browser.interfaces import BrowserOptionsManager
88
from pydoll.browser.managers import (
@@ -22,6 +22,7 @@
2222
from pydoll.constants import (
2323
AuthChallengeResponseValues,
2424
DownloadBehavior,
25+
NetworkErrorReason,
2526
PermissionType,
2627
)
2728
from pydoll.exceptions import BrowserNotRunning, FailedToStartBrowser, NoValidTabFound
@@ -33,6 +34,7 @@
3334
)
3435
from pydoll.protocol.browser.types import WindowBoundsDict
3536
from pydoll.protocol.fetch.events import FetchEvent
37+
from pydoll.protocol.fetch.types import HeaderEntry
3638
from pydoll.protocol.network.types import Cookie, CookieParam, RequestPausedEvent
3739
from pydoll.protocol.storage.responses import GetCookiesResponse
3840
from pydoll.protocol.target.responses import (
@@ -70,6 +72,7 @@ def __init__(
7072
Note:
7173
Call start() to actually launch the browser.
7274
"""
75+
self._validate_connection_port(connection_port)
7376
self.options = options_manager.initialize_options()
7477
self._proxy_manager = ProxyManager(self.options)
7578
self._connection_port = connection_port if connection_port else randint(9223, 9322)
@@ -178,7 +181,7 @@ async def delete_browser_context(self, browser_context_id: str):
178181
TargetCommands.dispose_browser_context(browser_context_id)
179182
)
180183

181-
async def get_browser_contexts(self) -> List[str]:
184+
async def get_browser_contexts(self) -> list[str]:
182185
"""Get all browser context IDs including the default context."""
183186
response: GetBrowserContextsResponse = await self._execute_command(
184187
TargetCommands.get_browser_contexts()
@@ -205,7 +208,7 @@ async def new_tab(self, url: str = '', browser_context_id: Optional[str] = None)
205208
target_id = response['result']['targetId']
206209
return Tab(self, self._connection_port, target_id, browser_context_id)
207210

208-
async def get_targets(self) -> List[TargetInfo]:
211+
async def get_targets(self) -> list[TargetInfo]:
209212
"""
210213
Get all active targets/pages in browser.
211214
@@ -248,12 +251,12 @@ async def delete_all_cookies(self, browser_context_id: Optional[str] = None):
248251
return await self._execute_command(StorageCommands.clear_cookies(browser_context_id))
249252

250253
async def set_cookies(
251-
self, cookies: List[CookieParam], browser_context_id: Optional[str] = None
254+
self, cookies: list[CookieParam], browser_context_id: Optional[str] = None
252255
):
253256
"""Set multiple cookies in browser or context."""
254257
return await self._execute_command(StorageCommands.set_cookies(cookies, browser_context_id))
255258

256-
async def get_cookies(self, browser_context_id: Optional[str] = None) -> List[Cookie]:
259+
async def get_cookies(self, browser_context_id: Optional[str] = None) -> list[Cookie]:
257260
"""Get all cookies from browser or context."""
258261
response: GetCookiesResponse = await self._execute_command(
259262
StorageCommands.get_cookies(browser_context_id)
@@ -310,7 +313,7 @@ async def set_window_bounds(self, bounds: WindowBoundsDict):
310313

311314
async def grant_permissions(
312315
self,
313-
permissions: List[PermissionType],
316+
permissions: list[PermissionType],
314317
origin: Optional[str] = None,
315318
browser_context_id: Optional[str] = None,
316319
):
@@ -401,6 +404,33 @@ async def continue_request(self, request_id: str):
401404
"""
402405
return await self._execute_command(FetchCommands.continue_request(request_id))
403406

407+
async def fail_request(self, request_id: str, error_reason: NetworkErrorReason):
408+
"""Fail request with error code."""
409+
return await self._execute_command(FetchCommands.fail_request(request_id, error_reason))
410+
411+
async def fulfill_request(
412+
self,
413+
request_id: str,
414+
response_code: int,
415+
response_headers: list[HeaderEntry],
416+
response_body: dict[Any, Any],
417+
):
418+
"""Fulfill request with response data."""
419+
return await self._execute_command(
420+
FetchCommands.fulfill_request(
421+
request_id,
422+
response_code,
423+
response_headers,
424+
response_body,
425+
)
426+
)
427+
428+
@staticmethod
429+
def _validate_connection_port(connection_port: Optional[int]):
430+
"""Validate connection port."""
431+
if connection_port and connection_port < 0:
432+
raise ValueError('Connection port must be a positive integer')
433+
404434
async def _continue_request_callback(self, event: RequestPausedEvent):
405435
"""Internal callback to continue paused requests."""
406436
request_id = event['params']['requestId']
@@ -461,7 +491,7 @@ def _is_valid_tab(target: TargetInfo) -> bool:
461491
return target.get('type') == 'page' and 'chrome-extension://' not in target.get('url', '')
462492

463493
@staticmethod
464-
async def _get_valid_tab_id(targets: List[TargetInfo]) -> str:
494+
async def _get_valid_tab_id(targets: list[TargetInfo]) -> str:
465495
"""
466496
Find valid attached tab ID.
467497

pydoll/browser/interfaces.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from abc import ABC, abstractmethod
2-
from typing import List
32

43

54
class Options(ABC):
65
@property
76
@abstractmethod
8-
def arguments(self) -> List[str]:
7+
def arguments(self) -> list[str]:
98
pass
109

1110
@property

pydoll/browser/options.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from typing import List
2-
31
from pydoll.browser.interfaces import Options
42
from pydoll.exceptions import ArgumentAlreadyExistsInOptions
53

@@ -23,7 +21,7 @@ def __init__(self):
2321
self._binary_location = ''
2422

2523
@property
26-
def arguments(self) -> List[str]:
24+
def arguments(self) -> list[str]:
2725
"""
2826
Gets the list of command-line arguments.
2927
@@ -33,7 +31,7 @@ def arguments(self) -> List[str]:
3331
return self._arguments
3432

3533
@arguments.setter
36-
def arguments(self, args_list: List[str]):
34+
def arguments(self, args_list: list[str]):
3735
"""
3836
Sets the list of command-line arguments.
3937

pydoll/browser/tab.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@
88
Any,
99
AsyncGenerator,
1010
Callable,
11-
Dict,
12-
List,
1311
Optional,
14-
Tuple,
1512
TypeAlias,
1613
Union,
1714
cast,
@@ -38,6 +35,7 @@
3835
NoDialogPresent,
3936
NotAnIFrame,
4037
PageLoadTimeout,
38+
WaitElementTimeout,
4139
)
4240
from pydoll.protocol.base import Response
4341
from pydoll.protocol.network.types import Cookie, CookieParam
@@ -203,7 +201,7 @@ async def enable_intercept_file_chooser_dialog(self):
203201

204202
async def enable_auto_solve_cloudflare_captcha(
205203
self,
206-
custom_selector: Optional[Tuple[By, str]] = None,
204+
custom_selector: Optional[tuple[By, str]] = None,
207205
time_before_click: int = 2,
208206
time_to_wait_captcha: int = 5,
209207
):
@@ -312,14 +310,14 @@ async def get_frame(self, frame: WebElement) -> IFrame:
312310

313311
return Tab(self._browser, self._connection_port, iframe_target['targetId'])
314312

315-
async def get_cookies(self) -> List[Cookie]:
313+
async def get_cookies(self) -> list[Cookie]:
316314
"""Get all cookies accessible from current page."""
317315
response: GetCookiesResponse = await self._execute_command(
318316
StorageCommands.get_cookies(self._browser_context_id)
319317
)
320318
return response['result']['cookies']
321319

322-
async def set_cookies(self, cookies: List[CookieParam]):
320+
async def set_cookies(self, cookies: list[CookieParam]):
323321
"""
324322
Set multiple cookies for current page.
325323
@@ -357,7 +355,7 @@ async def go_to(self, url: str, timeout: int = 300):
357355

358356
try:
359357
await self._wait_page_load(timeout=timeout)
360-
except asyncio.TimeoutError:
358+
except WaitElementTimeout:
361359
raise PageLoadTimeout()
362360

363361
async def refresh(
@@ -382,7 +380,7 @@ async def refresh(
382380
)
383381
try:
384382
await self._wait_page_load()
385-
except asyncio.TimeoutError:
383+
except WaitElementTimeout:
386384
raise PageLoadTimeout()
387385

388386
async def take_screenshot(
@@ -534,7 +532,7 @@ async def execute_script(self, script: str, element: Optional[WebElement] = None
534532

535533
@asynccontextmanager
536534
async def expect_file_chooser(
537-
self, files: Union[str, Path, List[Union[str, Path]]]
535+
self, files: Union[str, Path, list[Union[str, Path]]]
538536
) -> AsyncGenerator[None, None]:
539537
"""
540538
Context manager for automatic file upload handling.
@@ -571,7 +569,7 @@ async def event_handler(event):
571569
@asynccontextmanager
572570
async def expect_and_bypass_cloudflare_captcha(
573571
self,
574-
custom_selector: Optional[Tuple[By, str]] = None,
572+
custom_selector: Optional[tuple[By, str]] = None,
575573
time_before_click: int = 2,
576574
time_to_wait_captcha: int = 5,
577575
) -> AsyncGenerator[None, None]:
@@ -585,7 +583,7 @@ async def expect_and_bypass_cloudflare_captcha(
585583
"""
586584
captcha_processed = asyncio.Event()
587585

588-
async def bypass_cloudflare(_: Dict):
586+
async def bypass_cloudflare(_: dict):
589587
try:
590588
await self._bypass_cloudflare(
591589
_,
@@ -611,7 +609,7 @@ async def bypass_cloudflare(_: Dict):
611609
if not _before_page_events_enabled:
612610
await self.disable_page_events()
613611

614-
async def on(self, event_name: str, callback: Callable[[Dict], Any], temporary: bool = False):
612+
async def on(self, event_name: str, callback: Callable[[dict], Any], temporary: bool = False):
615613
"""
616614
Register CDP event listener.
617615
@@ -664,13 +662,13 @@ async def _wait_page_load(self, timeout: int = 300):
664662
if response['result']['result']['value'] == 'complete':
665663
break
666664
if asyncio.get_event_loop().time() - start_time > timeout:
667-
raise asyncio.TimeoutError('Page load timed out')
665+
raise WaitElementTimeout('Page load timed out')
668666
await asyncio.sleep(0.5)
669667

670668
async def _bypass_cloudflare(
671669
self,
672670
event: dict,
673-
custom_selector: Optional[Tuple[By, str]] = None,
671+
custom_selector: Optional[tuple[By, str]] = None,
674672
time_before_click: int = 2,
675673
time_to_wait_captcha: int = 5,
676674
):

pydoll/commands/browser_commands.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List, Optional
1+
from typing import Optional
22

33
from pydoll.constants import (
44
DownloadBehavior,
@@ -210,15 +210,15 @@ def set_window_minimized(window_id: int) -> Command[Response]:
210210

211211
@staticmethod
212212
def grant_permissions(
213-
permissions: List[PermissionType],
213+
permissions: list[PermissionType],
214214
origin: Optional[str] = None,
215215
browser_context_id: Optional[str] = None,
216216
) -> Command[Response]:
217217
"""
218218
Generates a command to grant specific permissions to the given origin.
219219
220220
Args:
221-
permissions (List[PermissionType]): List of permissions to grant.
221+
permissions (list[PermissionType]): list of permissions to grant.
222222
See PermissionType enum for available permissions.
223223
origin (Optional[str]): The origin to grant permissions to.
224224
If not specified, grants for all origins.

pydoll/commands/dom_commands.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List, Optional
1+
from typing import Optional
22

33
from pydoll.constants import ElementRelation, IncludeWhitespace, LogicalAxes, PhysicalAxes
44
from pydoll.protocol.base import Command, Response
@@ -673,7 +673,7 @@ def set_attribute_value(
673673

674674
@staticmethod
675675
def set_file_input_files(
676-
files: List[str],
676+
files: list[str],
677677
node_id: Optional[int] = None,
678678
backend_node_id: Optional[int] = None,
679679
object_id: Optional[str] = None,
@@ -686,7 +686,7 @@ def set_file_input_files(
686686
a file input, allowing automated tests to provide files programmatically.
687687
688688
Args:
689-
files: List of file paths to set.
689+
files: list of file paths to set.
690690
node_id: Identifier of the node.
691691
backend_node_id: Identifier of the backend node.
692692
object_id: JavaScript object id of the node wrapper.
@@ -1005,7 +1005,7 @@ def get_frame_owner(
10051005
@staticmethod
10061006
def get_nodes_for_subtree_by_style(
10071007
node_id: int,
1008-
computed_styles: List[CSSComputedStyleProperty],
1008+
computed_styles: list[CSSComputedStyleProperty],
10091009
pierce: Optional[bool] = None,
10101010
) -> Command[GetNodesForSubtreeByStyleResponse]:
10111011
"""
@@ -1017,7 +1017,7 @@ def get_nodes_for_subtree_by_style(
10171017
10181018
Args:
10191019
node_id: Node to start the search from.
1020-
computed_styles: List of computed style properties to match against.
1020+
computed_styles: list of computed style properties to match against.
10211021
pierce: Whether or not iframes and shadow roots should be traversed.
10221022
10231023
Returns:
@@ -1186,7 +1186,7 @@ def push_node_by_path_to_frontend(
11861186

11871187
@staticmethod
11881188
def push_nodes_by_backend_ids_to_frontend(
1189-
backend_node_ids: List[int],
1189+
backend_node_ids: list[int],
11901190
) -> Command[PushNodesByBackendIdsToFrontendResponse]:
11911191
"""
11921192
Requests that a batch of nodes is sent to the caller given their backend node ids.

0 commit comments

Comments
 (0)