Skip to content

Commit

Permalink
[py] Typing package import enhancement (SeleniumHQ#14283)
Browse files Browse the repository at this point in the history
  • Loading branch information
iampopovich authored Dec 4, 2024
1 parent 454ae25 commit 875f0a6
Show file tree
Hide file tree
Showing 21 changed files with 152 additions and 111 deletions.
52 changes: 26 additions & 26 deletions py/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from pathlib import Path
import re
from textwrap import dedent, indent as tw_indent
import typing
from typing import Optional , cast, List, Union, Iterator

import inflection # type: ignore

Expand Down Expand Up @@ -206,11 +206,11 @@ def from_json(cls, type):
class CdpProperty:
''' A property belonging to a non-primitive CDP type. '''
name: str
description: typing.Optional[str]
type: typing.Optional[str]
ref: typing.Optional[str]
enum: typing.List[str]
items: typing.Optional[CdpItems]
description: Optional[str]
type: Optional[str]
ref: Optional[str]
enum: List[str]
items: Optional[CdpItems]
optional: bool
experimental: bool
deprecated: bool
Expand All @@ -236,7 +236,7 @@ def py_annotation(self):
ann = py_ref
else:
ann = CdpPrimitiveType.get_annotation(
typing.cast(str, self.type))
cast(str, self.type))
if self.optional:
ann = f'typing.Optional[{ann}]'
return ann
Expand Down Expand Up @@ -316,11 +316,11 @@ def generate_from_json(self, dict_):
class CdpType:
''' A top-level CDP type. '''
id: str
description: typing.Optional[str]
description: Optional[str]
type: str
items: typing.Optional[CdpItems]
enum: typing.List[str]
properties: typing.List[CdpProperty]
items: Optional[CdpItems]
enum: List[str]
properties: List[CdpProperty]

@classmethod
def from_json(cls, type_):
Expand Down Expand Up @@ -500,7 +500,7 @@ def generate_code(self):
py_type = f"{ref_to_python(self.ref)}"
else:
py_type = CdpPrimitiveType.get_annotation(
typing.cast(str, self.type))
cast(str, self.type))
if self.optional:
py_type = f'typing.Optional[{py_type}]'
code = f"{self.py_name}: {py_type}"
Expand Down Expand Up @@ -585,8 +585,8 @@ class CdpCommand:
description: str
experimental: bool
deprecated: bool
parameters: typing.List[CdpParameter]
returns: typing.List[CdpReturn]
parameters: List[CdpParameter]
returns: List[CdpReturn]
domain: str

@property
Expand All @@ -605,8 +605,8 @@ def from_json(cls, command, domain) -> 'CdpCommand':
command.get('description'),
command.get('experimental', False),
command.get('deprecated', False),
[typing.cast(CdpParameter, CdpParameter.from_json(p)) for p in parameters],
[typing.cast(CdpReturn, CdpReturn.from_json(r)) for r in returns],
[cast(CdpParameter, CdpParameter.from_json(p)) for p in parameters],
[cast(CdpReturn, CdpReturn.from_json(r)) for r in returns],
domain,
)

Expand Down Expand Up @@ -712,10 +712,10 @@ def get_refs(self):
class CdpEvent:
''' A CDP event object. '''
name: str
description: typing.Optional[str]
description: Optional[str]
deprecated: bool
experimental: bool
parameters: typing.List[CdpParameter]
parameters: List[CdpParameter]
domain: str

@property
Expand All @@ -731,7 +731,7 @@ def from_json(cls, json: dict, domain: str):
json.get('description'),
json.get('deprecated', False),
json.get('experimental', False),
[typing.cast(CdpParameter, CdpParameter.from_json(p))
[cast(CdpParameter, CdpParameter.from_json(p))
for p in json.get('parameters', [])],
domain
)
Expand Down Expand Up @@ -786,12 +786,12 @@ def get_refs(self):
class CdpDomain:
''' A CDP domain contains metadata, types, commands, and events. '''
domain: str
description: typing.Optional[str]
description: Optional[str]
experimental: bool
dependencies: typing.List[str]
types: typing.List[CdpType]
commands: typing.List[CdpCommand]
events: typing.List[CdpEvent]
dependencies: List[str]
types: List[CdpType]
commands: List[CdpCommand]
events: List[CdpEvent]

@property
def module(self):
Expand Down Expand Up @@ -826,8 +826,8 @@ def generate_code(self):
code += import_code
code += '\n\n'
code += '\n'
item_iter_t = typing.Union[CdpEvent, CdpCommand, CdpType]
item_iter: typing.Iterator[item_iter_t] = itertools.chain(
item_iter_t = Union[CdpEvent, CdpCommand, CdpType]
item_iter: Iterator[item_iter_t] = itertools.chain(
iter(self.types),
iter(self.commands),
iter(self.events),
Expand Down
12 changes: 8 additions & 4 deletions py/selenium/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@
# under the License.
"""Selenium type definitions."""

import typing
from typing import IO
from typing import Any
from typing import Iterable
from typing import Type
from typing import Union

AnyKey = typing.Union[str, int, float]
WaitExcTypes = typing.Iterable[typing.Type[Exception]]
AnyKey = Union[str, int, float]
WaitExcTypes = Iterable[Type[Exception]]

# Service Types
SubprocessStdAlias = typing.Union[int, str, typing.IO[typing.Any]]
SubprocessStdAlias = Union[int, str, IO[Any]]
10 changes: 7 additions & 3 deletions py/selenium/webdriver/chrome/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import typing


from typing import List
from typing import Mapping
from typing import Optional

from selenium.types import SubprocessStdAlias
from selenium.webdriver.chromium import service
Expand All @@ -35,9 +39,9 @@ def __init__(
self,
executable_path=None,
port: int = 0,
service_args: typing.Optional[typing.List[str]] = None,
service_args: Optional[List[str]] = None,
log_output: SubprocessStdAlias = None,
env: typing.Optional[typing.Mapping[str, str]] = None,
env: Optional[Mapping[str, str]] = None,
**kwargs,
) -> None:
super().__init__(
Expand Down
12 changes: 7 additions & 5 deletions py/selenium/webdriver/chromium/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import typing
from io import IOBase
from typing import List
from typing import Mapping
from typing import Optional

from selenium.types import SubprocessStdAlias
from selenium.webdriver.common import service
Expand All @@ -36,9 +38,9 @@ def __init__(
self,
executable_path: str = None,
port: int = 0,
service_args: typing.Optional[typing.List[str]] = None,
service_args: Optional[List[str]] = None,
log_output: SubprocessStdAlias = None,
env: typing.Optional[typing.Mapping[str, str]] = None,
env: Optional[Mapping[str, str]] = None,
driver_path_env_key: str = None,
**kwargs,
) -> None:
Expand All @@ -47,7 +49,7 @@ def __init__(

if isinstance(log_output, str):
self.service_args.append(f"--log-path={log_output}")
self.log_output: typing.Optional[IOBase] = None
self.log_output: Optional[IOBase] = None
elif isinstance(log_output, IOBase):
self.log_output = log_output
else:
Expand All @@ -62,5 +64,5 @@ def __init__(
**kwargs,
)

def command_line_args(self) -> typing.List[str]:
def command_line_args(self) -> List[str]:
return [f"--port={self.port}"] + self.service_args
9 changes: 6 additions & 3 deletions py/selenium/webdriver/common/actions/pointer_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import typing

from typing import Any
from typing import Dict
from typing import Optional
from typing import Union

from selenium.common.exceptions import InvalidArgumentException
Expand All @@ -41,7 +44,7 @@ def create_pointer_move(
duration=DEFAULT_MOVE_DURATION,
x: float = 0,
y: float = 0,
origin: typing.Optional[WebElement] = None,
origin: Optional[WebElement] = None,
**kwargs,
):
action = {"type": "pointerMove", "duration": duration, "x": x, "y": y, **kwargs}
Expand All @@ -67,7 +70,7 @@ def create_pause(self, pause_duration: Union[int, float] = 0) -> None:
def encode(self):
return {"type": self.type, "parameters": {"pointerType": self.kind}, "id": self.name, "actions": self.actions}

def _convert_keys(self, actions: typing.Dict[str, typing.Any]):
def _convert_keys(self, actions: Dict[str, Any]):
out = {}
for k, v in actions.items():
if v is None:
Expand Down
19 changes: 12 additions & 7 deletions py/selenium/webdriver/common/bidi/cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,23 @@
import json
import logging
import pathlib
import typing
from collections import defaultdict
from contextlib import asynccontextmanager
from contextlib import contextmanager
from dataclasses import dataclass
from typing import Any
from typing import AsyncGenerator
from typing import AsyncIterator
from typing import Generator
from typing import Type
from typing import TypeVar

import trio
from trio_websocket import ConnectionClosed as WsConnectionClosed
from trio_websocket import connect_websocket_url

logger = logging.getLogger("trio_cdp")
T = typing.TypeVar("T")
T = TypeVar("T")
MAX_WS_MESSAGE_SIZE = 2**24

devtools = None
Expand Down Expand Up @@ -184,7 +189,7 @@ class CmEventProxy:
value set that contains the returned event.
"""

value: typing.Any = None
value: Any = None


class CdpBase:
Expand All @@ -197,7 +202,7 @@ def __init__(self, ws, session_id, target_id):
self.inflight_cmd = {}
self.inflight_result = {}

async def execute(self, cmd: typing.Generator[dict, T, typing.Any]) -> T:
async def execute(self, cmd: Generator[dict, T, Any]) -> T:
"""Execute a command on the server and wait for the result.
:param cmd: any CDP command
Expand Down Expand Up @@ -236,7 +241,7 @@ def listen(self, *event_types, buffer_size=10):
return receiver

@asynccontextmanager
async def wait_for(self, event_type: typing.Type[T], buffer_size=10) -> typing.AsyncGenerator[CmEventProxy, None]:
async def wait_for(self, event_type: Type[T], buffer_size=10) -> AsyncGenerator[CmEventProxy, None]:
"""Wait for an event of the given type and return it.
This is an async context manager, so you should open it inside
Expand Down Expand Up @@ -406,7 +411,7 @@ async def aclose(self):
await self.ws.aclose()

@asynccontextmanager
async def open_session(self, target_id) -> typing.AsyncIterator[CdpSession]:
async def open_session(self, target_id) -> AsyncIterator[CdpSession]:
"""This context manager opens a session and enables the "simple" style
of calling CDP APIs.
Expand Down Expand Up @@ -468,7 +473,7 @@ async def _reader_task(self):


@asynccontextmanager
async def open_cdp(url) -> typing.AsyncIterator[CdpConnection]:
async def open_cdp(url) -> AsyncIterator[CdpConnection]:
"""This async context manager opens a connection to the browser specified
by ``url`` before entering the block, then closes the connection when the
block exits.
Expand Down
4 changes: 2 additions & 2 deletions py/selenium/webdriver/common/bidi/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
# specific language governing permissions and limitations
# under the License.

import typing
from dataclasses import dataclass
from typing import List

from .session import session_subscribe
from .session import session_unsubscribe
Expand Down Expand Up @@ -76,7 +76,7 @@ class ConsoleLogEntry:
text: str
timestamp: str
method: str
args: typing.List[dict]
args: List[dict]
type_: str

@classmethod
Expand Down
9 changes: 5 additions & 4 deletions py/selenium/webdriver/common/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import typing

import warnings
from abc import ABCMeta
from abc import abstractmethod
from enum import Enum
from typing import Optional

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.common.proxy import Proxy
Expand Down Expand Up @@ -457,9 +458,9 @@ def set_capability(self, name, value) -> None:

def enable_mobile(
self,
android_package: typing.Optional[str] = None,
android_activity: typing.Optional[str] = None,
device_serial: typing.Optional[str] = None,
android_package: Optional[str] = None,
android_activity: Optional[str] = None,
device_serial: Optional[str] = None,
) -> None:
"""Enables mobile browser use for browsers that support it.
Expand Down
Loading

0 comments on commit 875f0a6

Please sign in to comment.