diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5198070e1..5c8c8f1db 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v5.0.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -15,16 +15,16 @@ repos: - id: check-executables-have-shebangs - id: check-merge-conflict - repo: https://github.com/psf/black - rev: 23.9.1 + rev: 24.8.0 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.8.0 + rev: v1.11.2 hooks: - id: mypy - additional_dependencies: [types-pyOpenSSL==23.2.0.2, types-requests==2.31.0.10] + additional_dependencies: [types-pyOpenSSL==24.1.0.20240722, types-requests==2.32.0.20240914] - repo: https://github.com/pycqa/flake8 - rev: 6.1.0 + rev: 7.1.1 hooks: - id: flake8 - repo: https://github.com/pycqa/isort @@ -39,7 +39,7 @@ repos: language: node pass_filenames: false types: [python] - additional_dependencies: ["pyright@1.1.278"] + additional_dependencies: ["pyright@1.1.384"] - repo: local hooks: - id: check-license-header diff --git a/local-requirements.txt b/local-requirements.txt index 775d3b850..8826bc3d5 100644 --- a/local-requirements.txt +++ b/local-requirements.txt @@ -7,7 +7,7 @@ mypy==1.11.2 objgraph==3.6.1 Pillow==10.4.0 pixelmatch==0.3.0 -pre-commit==3.4.0 +pre-commit==3.5.0 pyOpenSSL==24.2.1 pytest==8.3.3 pytest-asyncio==0.21.2 diff --git a/playwright/_impl/_assertions.py b/playwright/_impl/_assertions.py index 5841eca5a..163b156ed 100644 --- a/playwright/_impl/_assertions.py +++ b/playwright/_impl/_assertions.py @@ -512,9 +512,11 @@ async def to_be_attached( ) -> None: __tracebackhide__ = True await self._expect_impl( - "to.be.attached" - if (attached is None or attached is True) - else "to.be.detached", + ( + "to.be.attached" + if (attached is None or attached is True) + else "to.be.detached" + ), FrameExpectOptions(timeout=timeout), None, "Locator expected to be attached", @@ -527,9 +529,11 @@ async def to_be_checked( ) -> None: __tracebackhide__ = True await self._expect_impl( - "to.be.checked" - if checked is None or checked is True - else "to.be.unchecked", + ( + "to.be.checked" + if checked is None or checked is True + else "to.be.unchecked" + ), FrameExpectOptions(timeout=timeout), None, "Locator expected to be checked", diff --git a/playwright/_impl/_async_base.py b/playwright/_impl/_async_base.py index e9544b733..b06994a65 100644 --- a/playwright/_impl/_async_base.py +++ b/playwright/_impl/_async_base.py @@ -15,7 +15,7 @@ import asyncio from contextlib import AbstractAsyncContextManager from types import TracebackType -from typing import Any, Callable, Generic, Optional, Type, TypeVar +from typing import Any, Callable, Generic, Optional, Type, TypeVar, Union from playwright._impl._impl_to_api_mapping import ImplToApiMapping, ImplWrapper @@ -68,7 +68,9 @@ def __init__(self, impl_obj: Any) -> None: def __str__(self) -> str: return self._impl_obj.__str__() - def _wrap_handler(self, handler: Any) -> Callable[..., None]: + def _wrap_handler( + self, handler: Union[Callable[..., Any], Any] + ) -> Callable[..., None]: if callable(handler): return mapping.wrap_handler(handler) return handler @@ -100,5 +102,4 @@ async def __aexit__( ) -> None: await self.close() - async def close(self) -> None: - ... + async def close(self) -> None: ... diff --git a/playwright/_impl/_browser_context.py b/playwright/_impl/_browser_context.py index 455bf3410..7da85e9a4 100644 --- a/playwright/_impl/_browser_context.py +++ b/playwright/_impl/_browser_context.py @@ -316,21 +316,21 @@ async def clear_cookies( { "name": name if isinstance(name, str) else None, "nameRegexSource": name.pattern if isinstance(name, Pattern) else None, - "nameRegexFlags": escape_regex_flags(name) - if isinstance(name, Pattern) - else None, + "nameRegexFlags": ( + escape_regex_flags(name) if isinstance(name, Pattern) else None + ), "domain": domain if isinstance(domain, str) else None, - "domainRegexSource": domain.pattern - if isinstance(domain, Pattern) - else None, - "domainRegexFlags": escape_regex_flags(domain) - if isinstance(domain, Pattern) - else None, + "domainRegexSource": ( + domain.pattern if isinstance(domain, Pattern) else None + ), + "domainRegexFlags": ( + escape_regex_flags(domain) if isinstance(domain, Pattern) else None + ), "path": path if isinstance(path, str) else None, "pathRegexSource": path.pattern if isinstance(path, Pattern) else None, - "pathRegexFlags": escape_regex_flags(path) - if isinstance(path, Pattern) - else None, + "pathRegexFlags": ( + escape_regex_flags(path) if isinstance(path, Pattern) else None + ), }, ) diff --git a/playwright/_impl/_connection.py b/playwright/_impl/_connection.py index eb4d182d3..c15d82e79 100644 --- a/playwright/_impl/_connection.py +++ b/playwright/_impl/_connection.py @@ -197,9 +197,9 @@ def cb(task: asyncio.Task) -> None: if current_task: current_task.add_done_callback(cb) self.future.add_done_callback( - lambda _: current_task.remove_done_callback(cb) - if current_task - else None + lambda _: ( + current_task.remove_done_callback(cb) if current_task else None + ) ) @@ -243,9 +243,9 @@ def __init__( self._error: Optional[BaseException] = None self.is_remote = False self._init_task: Optional[asyncio.Task] = None - self._api_zone: contextvars.ContextVar[ - Optional[ParsedStackTrace] - ] = contextvars.ContextVar("ApiZone", default=None) + self._api_zone: contextvars.ContextVar[Optional[ParsedStackTrace]] = ( + contextvars.ContextVar("ApiZone", default=None) + ) self._local_utils: Optional["LocalUtils"] = local_utils self._tracing_count = 0 self._closed_error: Optional[Exception] = None diff --git a/playwright/_impl/_impl_to_api_mapping.py b/playwright/_impl/_impl_to_api_mapping.py index 4315e1868..e26d22025 100644 --- a/playwright/_impl/_impl_to_api_mapping.py +++ b/playwright/_impl/_impl_to_api_mapping.py @@ -117,7 +117,7 @@ def to_impl( except RecursionError: raise Error("Maximum argument depth exceeded") - def wrap_handler(self, handler: Callable[..., None]) -> Callable[..., None]: + def wrap_handler(self, handler: Callable[..., Any]) -> Callable[..., None]: def wrapper_func(*args: Any) -> Any: arg_count = len(inspect.signature(handler).parameters) return handler( diff --git a/playwright/_impl/_js_handle.py b/playwright/_impl/_js_handle.py index a8be0ee18..572d4975e 100644 --- a/playwright/_impl/_js_handle.py +++ b/playwright/_impl/_js_handle.py @@ -145,13 +145,17 @@ def serialize_value( return { "e": { "m": str(value), - "n": (value.name or "") - if isinstance(value, Error) - else value.__class__.__name__, - "s": (value.stack or "") - if isinstance(value, Error) - else "".join( - traceback.format_exception(type(value), value=value, tb=None) + "n": ( + (value.name or "") + if isinstance(value, Error) + else value.__class__.__name__ + ), + "s": ( + (value.stack or "") + if isinstance(value, Error) + else "".join( + traceback.format_exception(type(value), value=value, tb=None) + ) ), } } diff --git a/playwright/_impl/_json_pipe.py b/playwright/_impl/_json_pipe.py index f76bc7175..3a6973baf 100644 --- a/playwright/_impl/_json_pipe.py +++ b/playwright/_impl/_json_pipe.py @@ -33,7 +33,6 @@ def __init__( Transport.__init__(self, loop) self._stop_requested = False self._pipe_channel = pipe_channel - self._loop: asyncio.AbstractEventLoop def request_stop(self) -> None: self._stop_requested = True diff --git a/playwright/_impl/_sync_base.py b/playwright/_impl/_sync_base.py index f07b947b2..b50c7479d 100644 --- a/playwright/_impl/_sync_base.py +++ b/playwright/_impl/_sync_base.py @@ -114,7 +114,9 @@ def _sync( asyncio._set_running_loop(self._loop) return task.result() - def _wrap_handler(self, handler: Any) -> Callable[..., None]: + def _wrap_handler( + self, handler: Union[Callable[..., Any], Any] + ) -> Callable[..., None]: if callable(handler): return mapping.wrap_handler(handler) return handler @@ -146,5 +148,4 @@ def __exit__( ) -> None: self.close() - def close(self) -> None: - ... + def close(self) -> None: ... diff --git a/playwright/async_api/__init__.py b/playwright/async_api/__init__.py index 554e83927..12ea5febd 100644 --- a/playwright/async_api/__init__.py +++ b/playwright/async_api/__init__.py @@ -107,20 +107,19 @@ def set_options(self, timeout: Optional[float] = _unset) -> None: self._timeout = timeout @overload - def __call__(self, actual: Page, message: Optional[str] = None) -> PageAssertions: - ... + def __call__( + self, actual: Page, message: Optional[str] = None + ) -> PageAssertions: ... @overload def __call__( self, actual: Locator, message: Optional[str] = None - ) -> LocatorAssertions: - ... + ) -> LocatorAssertions: ... @overload def __call__( self, actual: APIResponse, message: Optional[str] = None - ) -> APIResponseAssertions: - ... + ) -> APIResponseAssertions: ... def __call__( self, actual: Union[Page, Locator, APIResponse], message: Optional[str] = None diff --git a/playwright/async_api/_generated.py b/playwright/async_api/_generated.py index 98bf96cc0..1d4badbe7 100644 --- a/playwright/async_api/_generated.py +++ b/playwright/async_api/_generated.py @@ -85,6 +85,7 @@ class Request(AsyncBase): + @property def url(self) -> str: """Request.url @@ -385,6 +386,7 @@ async def header_value(self, name: str) -> typing.Optional[str]: class Response(AsyncBase): + @property def url(self) -> str: """Response.url @@ -621,6 +623,7 @@ async def json(self) -> typing.Any: class Route(AsyncBase): + @property def request(self) -> "Request": """Route.request @@ -951,6 +954,7 @@ async def handle(route, request): class WebSocket(AsyncBase): + @typing.overload def on( self, @@ -1143,6 +1147,7 @@ def is_closed(self) -> bool: class Keyboard(AsyncBase): + async def down(self, key: str) -> None: """Keyboard.down @@ -1306,6 +1311,7 @@ async def press(self, key: str, *, delay: typing.Optional[float] = None) -> None class Mouse(AsyncBase): + async def move( self, x: float, y: float, *, steps: typing.Optional[int] = None ) -> None: @@ -1457,6 +1463,7 @@ async def wheel(self, delta_x: float, delta_y: float) -> None: class Touchscreen(AsyncBase): + async def tap(self, x: float, y: float) -> None: """Touchscreen.tap @@ -1479,6 +1486,7 @@ async def tap(self, x: float, y: float) -> None: class JSHandle(AsyncBase): + async def evaluate( self, expression: str, arg: typing.Optional[typing.Any] = None ) -> typing.Any: @@ -1634,6 +1642,7 @@ async def json_value(self) -> typing.Any: class ElementHandle(JSHandle): + def as_element(self) -> typing.Optional["ElementHandle"]: """ElementHandle.as_element @@ -2948,6 +2957,7 @@ async def wait_for_selector( class Accessibility(AsyncBase): + async def snapshot( self, *, @@ -3013,6 +3023,7 @@ def find_focused_node(node): class FileChooser(AsyncBase): + @property def page(self) -> "Page": """FileChooser.page @@ -3089,6 +3100,7 @@ async def set_files( class Frame(AsyncBase): + @property def page(self) -> "Page": """Frame.page @@ -5851,6 +5863,7 @@ async def set_checked( class FrameLocator(AsyncBase): + @property def first(self) -> "FrameLocator": """FrameLocator.first @@ -6458,6 +6471,7 @@ def nth(self, index: int) -> "FrameLocator": class Worker(AsyncBase): + def on( self, event: Literal["close"], @@ -6558,6 +6572,7 @@ async def evaluate_handle( class Selectors(AsyncBase): + async def register( self, name: str, @@ -6655,6 +6670,7 @@ def set_test_id_attribute(self, attribute_name: str) -> None: class Clock(AsyncBase): + async def install( self, *, @@ -6813,6 +6829,7 @@ async def set_system_time( class ConsoleMessage(AsyncBase): + @property def type(self) -> str: """ConsoleMessage.type @@ -6878,6 +6895,7 @@ def page(self) -> typing.Optional["Page"]: class Dialog(AsyncBase): + @property def type(self) -> str: """Dialog.type @@ -6954,6 +6972,7 @@ async def dismiss(self) -> None: class Download(AsyncBase): + @property def page(self) -> "Page": """Download.page @@ -7063,6 +7082,7 @@ async def cancel(self) -> None: class Video(AsyncBase): + async def path(self) -> pathlib.Path: """Video.path @@ -7103,6 +7123,7 @@ async def delete(self) -> None: class Page(AsyncContextManager): + @typing.overload def on( self, @@ -11999,6 +12020,7 @@ async def remove_locator_handler(self, locator: "Locator") -> None: class WebError(AsyncBase): + @property def page(self) -> typing.Optional["Page"]: """WebError.page @@ -12028,6 +12050,7 @@ def error(self) -> "Error": class BrowserContext(AsyncContextManager): + @typing.overload def on( self, @@ -13283,6 +13306,7 @@ async def new_cdp_session( class CDPSession(AsyncBase): + async def send( self, method: str, params: typing.Optional[typing.Dict] = None ) -> typing.Dict: @@ -13318,6 +13342,7 @@ async def detach(self) -> None: class Browser(AsyncContextManager): + def on( self, event: Literal["disconnected"], @@ -13973,6 +13998,7 @@ async def stop_tracing(self) -> bytes: class BrowserType(AsyncBase): + @property def name(self) -> str: """BrowserType.name @@ -14554,6 +14580,7 @@ async def connect( class Playwright(AsyncBase): + @property def devices(self) -> typing.Dict: """Playwright.devices @@ -14648,6 +14675,7 @@ def request(self) -> "APIRequest": return mapping.from_impl(self._impl_obj.request) def __getitem__(self, value: str) -> "BrowserType": + return mapping.from_impl(self._impl_obj.__getitem__(value=value)) async def stop(self) -> None: @@ -14678,6 +14706,7 @@ async def stop(self) -> None: class Tracing(AsyncBase): + async def start( self, *, @@ -14804,6 +14833,7 @@ async def stop( class Locator(AsyncBase): + @property def page(self) -> "Page": """Locator.page @@ -17409,6 +17439,7 @@ async def highlight(self) -> None: class APIResponse(AsyncBase): + @property def ok(self) -> bool: """APIResponse.ok @@ -17533,6 +17564,7 @@ async def dispose(self) -> None: class APIRequestContext(AsyncBase): + async def dispose(self, *, reason: typing.Optional[str] = None) -> None: """APIRequestContext.dispose @@ -18203,6 +18235,7 @@ async def storage_state( class APIRequest(AsyncBase): + async def new_context( self, *, @@ -18291,6 +18324,7 @@ async def new_context( class PageAssertions(AsyncBase): + async def to_have_title( self, title_or_reg_exp: typing.Union[typing.Pattern[str], str], @@ -18424,6 +18458,7 @@ async def not_to_have_url( class LocatorAssertions(AsyncBase): + async def to_contain_text( self, expected: typing.Union[ @@ -20072,6 +20107,7 @@ async def not_to_have_role( class APIResponseAssertions(AsyncBase): + async def to_be_ok(self) -> None: """APIResponseAssertions.to_be_ok diff --git a/playwright/sync_api/__init__.py b/playwright/sync_api/__init__.py index e17c0e305..e326fd9f5 100644 --- a/playwright/sync_api/__init__.py +++ b/playwright/sync_api/__init__.py @@ -107,20 +107,19 @@ def set_options(self, timeout: Optional[float] = _unset) -> None: self._timeout = timeout @overload - def __call__(self, actual: Page, message: Optional[str] = None) -> PageAssertions: - ... + def __call__( + self, actual: Page, message: Optional[str] = None + ) -> PageAssertions: ... @overload def __call__( self, actual: Locator, message: Optional[str] = None - ) -> LocatorAssertions: - ... + ) -> LocatorAssertions: ... @overload def __call__( self, actual: APIResponse, message: Optional[str] = None - ) -> APIResponseAssertions: - ... + ) -> APIResponseAssertions: ... def __call__( self, actual: Union[Page, Locator, APIResponse], message: Optional[str] = None diff --git a/playwright/sync_api/_generated.py b/playwright/sync_api/_generated.py index 69eb53b79..1553c2598 100644 --- a/playwright/sync_api/_generated.py +++ b/playwright/sync_api/_generated.py @@ -85,6 +85,7 @@ class Request(SyncBase): + @property def url(self) -> str: """Request.url @@ -387,6 +388,7 @@ def header_value(self, name: str) -> typing.Optional[str]: class Response(SyncBase): + @property def url(self) -> str: """Response.url @@ -627,6 +629,7 @@ def json(self) -> typing.Any: class Route(SyncBase): + @property def request(self) -> "Request": """Route.request @@ -967,6 +970,7 @@ def handle(route, request): class WebSocket(SyncBase): + @typing.overload def on( self, event: Literal["close"], f: typing.Callable[["WebSocket"], "None"] @@ -1139,6 +1143,7 @@ def is_closed(self) -> bool: class Keyboard(SyncBase): + def down(self, key: str) -> None: """Keyboard.down @@ -1306,6 +1311,7 @@ def press(self, key: str, *, delay: typing.Optional[float] = None) -> None: class Mouse(SyncBase): + def move(self, x: float, y: float, *, steps: typing.Optional[int] = None) -> None: """Mouse.move @@ -1459,6 +1465,7 @@ def wheel(self, delta_x: float, delta_y: float) -> None: class Touchscreen(SyncBase): + def tap(self, x: float, y: float) -> None: """Touchscreen.tap @@ -1481,6 +1488,7 @@ def tap(self, x: float, y: float) -> None: class JSHandle(SyncBase): + def evaluate( self, expression: str, arg: typing.Optional[typing.Any] = None ) -> typing.Any: @@ -1638,6 +1646,7 @@ def json_value(self) -> typing.Any: class ElementHandle(JSHandle): + def as_element(self) -> typing.Optional["ElementHandle"]: """ElementHandle.as_element @@ -2992,6 +3001,7 @@ def wait_for_selector( class Accessibility(SyncBase): + def snapshot( self, *, @@ -3059,6 +3069,7 @@ def find_focused_node(node): class FileChooser(SyncBase): + @property def page(self) -> "Page": """FileChooser.page @@ -3139,6 +3150,7 @@ def set_files( class Frame(SyncBase): + @property def page(self) -> "Page": """Frame.page @@ -5965,6 +5977,7 @@ def set_checked( class FrameLocator(SyncBase): + @property def first(self) -> "FrameLocator": """FrameLocator.first @@ -6572,6 +6585,7 @@ def nth(self, index: int) -> "FrameLocator": class Worker(SyncBase): + def on( self, event: Literal["close"], f: typing.Callable[["Worker"], "None"] ) -> None: @@ -6670,6 +6684,7 @@ def evaluate_handle( class Selectors(SyncBase): + def register( self, name: str, @@ -6765,6 +6780,7 @@ def set_test_id_attribute(self, attribute_name: str) -> None: class Clock(SyncBase): + def install( self, *, @@ -6927,6 +6943,7 @@ def set_system_time( class ConsoleMessage(SyncBase): + @property def type(self) -> str: """ConsoleMessage.type @@ -6992,6 +7009,7 @@ def page(self) -> typing.Optional["Page"]: class Dialog(SyncBase): + @property def type(self) -> str: """Dialog.type @@ -7068,6 +7086,7 @@ def dismiss(self) -> None: class Download(SyncBase): + @property def page(self) -> "Page": """Download.page @@ -7177,6 +7196,7 @@ def cancel(self) -> None: class Video(SyncBase): + def path(self) -> pathlib.Path: """Video.path @@ -7217,6 +7237,7 @@ def delete(self) -> None: class Page(SyncContextManager): + @typing.overload def on(self, event: Literal["close"], f: typing.Callable[["Page"], "None"]) -> None: """ @@ -12090,6 +12111,7 @@ def remove_locator_handler(self, locator: "Locator") -> None: class WebError(SyncBase): + @property def page(self) -> typing.Optional["Page"]: """WebError.page @@ -12119,6 +12141,7 @@ def error(self) -> "Error": class BrowserContext(SyncContextManager): + @typing.overload def on( self, event: Literal["backgroundpage"], f: typing.Callable[["Page"], "None"] @@ -13317,6 +13340,7 @@ def new_cdp_session(self, page: typing.Union["Page", "Frame"]) -> "CDPSession": class CDPSession(SyncBase): + def send( self, method: str, params: typing.Optional[typing.Dict] = None ) -> typing.Dict: @@ -13354,6 +13378,7 @@ def detach(self) -> None: class Browser(SyncContextManager): + def on( self, event: Literal["disconnected"], f: typing.Callable[["Browser"], "None"] ) -> None: @@ -14011,6 +14036,7 @@ def stop_tracing(self) -> bytes: class BrowserType(SyncBase): + @property def name(self) -> str: """BrowserType.name @@ -14600,6 +14626,7 @@ def connect( class Playwright(SyncBase): + @property def devices(self) -> typing.Dict: """Playwright.devices @@ -14691,6 +14718,7 @@ def request(self) -> "APIRequest": return mapping.from_impl(self._impl_obj.request) def __getitem__(self, value: str) -> "BrowserType": + return mapping.from_impl(self._impl_obj.__getitem__(value=value)) def stop(self) -> None: @@ -14721,6 +14749,7 @@ def stop(self) -> None: class Tracing(SyncBase): + def start( self, *, @@ -14849,6 +14878,7 @@ def stop( class Locator(SyncBase): + @property def page(self) -> "Page": """Locator.page @@ -17511,6 +17541,7 @@ def highlight(self) -> None: class APIResponse(SyncBase): + @property def ok(self) -> bool: """APIResponse.ok @@ -17635,6 +17666,7 @@ def dispose(self) -> None: class APIRequestContext(SyncBase): + def dispose(self, *, reason: typing.Optional[str] = None) -> None: """APIRequestContext.dispose @@ -18325,6 +18357,7 @@ def storage_state( class APIRequest(SyncBase): + def new_context( self, *, @@ -18415,6 +18448,7 @@ def new_context( class PageAssertions(SyncBase): + def to_have_title( self, title_or_reg_exp: typing.Union[typing.Pattern[str], str], @@ -18556,6 +18590,7 @@ def not_to_have_url( class LocatorAssertions(SyncBase): + def to_contain_text( self, expected: typing.Union[ @@ -20246,6 +20281,7 @@ def not_to_have_role( class APIResponseAssertions(SyncBase): + def to_be_ok(self) -> None: """APIResponseAssertions.to_be_ok diff --git a/pyproject.toml b/pyproject.toml index 34504380f..709e0ffa1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ profile = "black" [tool.pyright] include = ["playwright", "tests", "scripts"] +exclude = ["**/node_modules", "**/__pycache__", "**/.*", "./build"] pythonVersion = "3.8" reportMissingImports = false reportTypedDictNotRequiredAccess = false @@ -42,3 +43,4 @@ reportCallInDefaultInitializer = true reportOptionalSubscript = false reportUnboundVariable = false strictParameterNoneValue = false +reportIncompatibleVariableOverride = false diff --git a/scripts/documentation_provider.py b/scripts/documentation_provider.py index 82e3f4bb6..9acbe6c7d 100644 --- a/scripts/documentation_provider.py +++ b/scripts/documentation_provider.py @@ -96,9 +96,9 @@ def _add_link(self, kind: str, clazz: str, member: str, alias: str) -> None: new_name = to_snake_case(alias) if kind == "event": new_name = new_name.lower() - self.links[ - f"[`event: {clazz}.{member}`]" - ] = f"`{var_name}.on('{new_name}')`" + self.links[f"[`event: {clazz}.{member}`]"] = ( + f"`{var_name}.on('{new_name}')`" + ) elif kind == "property": self.links[f"[`property: {clazz}.{member}`]"] = f"`{var_name}.{new_name}`" else: diff --git a/setup.cfg b/setup.cfg index 5594a677b..35d6f7007 100644 --- a/setup.cfg +++ b/setup.cfg @@ -3,3 +3,5 @@ ignore = E501 W503 E302 + # Conflicts with black https://github.com/PyCQA/flake8/issues/1921 + E704 diff --git a/tests/async/test_accessibility.py b/tests/async/test_accessibility.py index 201ba8483..ec7b42190 100644 --- a/tests/async/test_accessibility.py +++ b/tests/async/test_accessibility.py @@ -100,12 +100,14 @@ async def test_accessibility_should_work( {"role": "textbox", "name": "placeholder", "value": "and a value"}, { "role": "textbox", - "name": "placeholder" - if ( - sys.platform == "darwin" - and int(os.uname().release.split(".")[0]) >= 21 - ) - else "This is a description!", + "name": ( + "placeholder" + if ( + sys.platform == "darwin" + and int(os.uname().release.split(".")[0]) >= 21 + ) + else "This is a description!" + ), "value": "and a value", }, # webkit uses the description over placeholder for the name ], diff --git a/tests/async/test_keyboard.py b/tests/async/test_keyboard.py index d94f036e7..e175f429a 100644 --- a/tests/async/test_keyboard.py +++ b/tests/async/test_keyboard.py @@ -109,7 +109,9 @@ async def test_should_send_a_character_with_send_character( '() => window.addEventListener("keydown", e => e.preventDefault(), true)' ) await page.keyboard.insert_text("a") - assert await page.evaluate('() => document.querySelector("textarea").value') == "嗨a" + assert ( + await page.evaluate('() => document.querySelector("textarea").value') == "嗨a" + ) async def test_should_only_emit_input_event(page: Page, server: Server) -> None: diff --git a/tests/async/test_page_route.py b/tests/async/test_page_route.py index 8e0b74130..017bdac9a 100644 --- a/tests/async/test_page_route.py +++ b/tests/async/test_page_route.py @@ -605,9 +605,9 @@ async def test_page_route_should_support_cors_with_GET( async def handle_route(route: Route, request: Request) -> None: headers = { - "access-control-allow-origin": "*" - if request.url.endswith("allow") - else "none" + "access-control-allow-origin": ( + "*" if request.url.endswith("allow") else "none" + ) } await route.fulfill( content_type="application/json", diff --git a/tests/server.py b/tests/server.py index 23d7ff374..f9072d448 100644 --- a/tests/server.py +++ b/tests/server.py @@ -185,7 +185,7 @@ def start(self) -> None: ws_factory = WebSocketServerFactory() ws_factory.protocol = WebSocketProtocol - ws_factory.server_instance = self + setattr(ws_factory, "server_instance", self) self._ws_resource = WebSocketResource(ws_factory) self.listen(factory) @@ -281,8 +281,8 @@ def listen(self, factory: http.HTTPFactory) -> None: class WebSocketProtocol(WebSocketServerProtocol): def onOpen(self) -> None: - for handler in self.factory.server_instance._ws_handlers.copy(): - self.factory.server_instance._ws_handlers.remove(handler) + for handler in getattr(self.factory, "server_instance")._ws_handlers.copy(): + getattr(self.factory, "server_instance")._ws_handlers.remove(handler) handler(self) diff --git a/tests/sync/test_accessibility.py b/tests/sync/test_accessibility.py index d7516d6d9..625a46999 100644 --- a/tests/sync/test_accessibility.py +++ b/tests/sync/test_accessibility.py @@ -100,12 +100,14 @@ def test_accessibility_should_work( {"role": "textbox", "name": "placeholder", "value": "and a value"}, { "role": "textbox", - "name": "placeholder" - if ( - sys.platform == "darwin" - and int(os.uname().release.split(".")[0]) >= 21 - ) - else "This is a description!", + "name": ( + "placeholder" + if ( + sys.platform == "darwin" + and int(os.uname().release.split(".")[0]) >= 21 + ) + else "This is a description!" + ), "value": "and a value", }, # webkit uses the description over placeholder for the name ], diff --git a/tests/test_reference_count_async.py b/tests/test_reference_count_async.py index cc1564aa6..4f4cac102 100644 --- a/tests/test_reference_count_async.py +++ b/tests/test_reference_count_async.py @@ -59,6 +59,7 @@ def handle_network_response_received(event: Any) -> None: pw_objects: defaultdict = defaultdict(int) for o in objgraph.by_type("dict"): + assert isinstance(o, dict) name = o.get("_type") # https://github.com/microsoft/playwright-python/issues/1602 if o.get("__pw__is_last_network_response_received_event", False):