From 7113c90503a84f5d35cc28a8c37502ea96b36856 Mon Sep 17 00:00:00 2001 From: Vishal Anton Date: Sun, 20 Sep 2026 12:56:49 +0530 Subject: [PATCH 1/2] Improve Python SDK linting rules --- packages/sdk-python/pyproject.toml | 22 +++++++++- packages/sdk-python/src/stagehand/__init__.py | 14 +++--- packages/sdk-python/src/stagehand/browser.py | 6 +-- packages/sdk-python/tests/test_browser.py | 8 ++-- .../tests/test_browserbase_session.py | 8 ++-- packages/sdk-python/tests/test_cdp_client.py | 4 +- packages/sdk-python/tests/test_page.py | 4 +- packages/sdk-python/tests/test_response.py | 4 +- packages/sdk-python/tests/test_stagehand.py | 6 +-- packages/sdk-python/uv.lock | 44 +++++++++---------- 10 files changed, 69 insertions(+), 51 deletions(-) diff --git a/packages/sdk-python/pyproject.toml b/packages/sdk-python/pyproject.toml index 09b2206a1f..a628959c64 100644 --- a/packages/sdk-python/pyproject.toml +++ b/packages/sdk-python/pyproject.toml @@ -35,7 +35,25 @@ exclude = ["src/stagehand/_generated"] preview = true [tool.ruff.lint] -select = ["ANN", "E", "F", "I", "PYI", "UP"] +select = [ + "ANN", + "B006", + "B015", + "B018", + "B904", + "E", + "F", + "I", + "PYI", + "RUF018", + "RUF022", + "RUF023", + "RUF043", + "RUF100", + "TID252", + "UP", +] +external = ["S"] [tool.ty.environment] python-version = "3.11" @@ -59,6 +77,6 @@ dev = [ "openai>=2,<3", "pytest==9.0.2", "pytest-asyncio==1.3.0", - "ruff==0.15.7", + "ruff==0.16.8", "ty==0.0.82", ] diff --git a/packages/sdk-python/src/stagehand/__init__.py b/packages/sdk-python/src/stagehand/__init__.py index cebd069f42..5cd3fa2f5a 100644 --- a/packages/sdk-python/src/stagehand/__init__.py +++ b/packages/sdk-python/src/stagehand/__init__.py @@ -106,17 +106,17 @@ "BrowserbaseRegion", "BrowserbaseSearchResult", "BrowserbaseSearchResultItem", - "CacheOptions", + "CDPSubscription", "CacheMetadata", + "CacheOptions", "CacheStatus", "CacheTokenSavings", "Caret", - "CDPSubscription", "Cookie", "CookieParam", + "DefaultExtract", "DomainPolicy", "DomainPolicyInput", - "DefaultExtract", "ExternalProxyConfig", "ExtractResult", "FileInput", @@ -143,14 +143,11 @@ "PageCDPEvent", "PageDragAndDropRoutePoint", "PageEventListener", - "ToolsAddedListener", - "ToolsRemovedListener", - "WebMCPToolIdentity", "PageEventName", "PageScreenshotClip", "ProtocolLocator", - "RgbaColor", "Response", + "RgbaColor", "Scale", "ScreenshotType", "Stagehand", @@ -161,11 +158,14 @@ "StagehandRuntimeIncompatibleError", "State", "TelemetryConfig", + "ToolsAddedListener", + "ToolsRemovedListener", "Variables", "WebMCPAnnotation", "WebMCPInvocation", "WebMCPInvocationStatus", "WebMCPTool", + "WebMCPToolIdentity", "WebMCPToolResponse", "browserbase", "local_browser", diff --git a/packages/sdk-python/src/stagehand/browser.py b/packages/sdk-python/src/stagehand/browser.py index ed4f7bee2a..9895011997 100644 --- a/packages/sdk-python/src/stagehand/browser.py +++ b/packages/sdk-python/src/stagehand/browser.py @@ -121,12 +121,12 @@ class StagehandBrowser: "_attachment", "_claimed", "_close_callback", - "_invalidate_callback", - "_terminal_task", "_context", + "_invalidate_callback", "_origin", "_provider", "_session_id", + "_terminal_task", ) def __init__( @@ -336,7 +336,7 @@ async def _connect_browser( raise for cleanup_error in cleanup_errors: if not isinstance(cleanup_error, Exception): - raise cleanup_error + raise cleanup_error from error if cleanup_errors: raise BaseExceptionGroup( "Browser connection failed and browser cleanup also failed", diff --git a/packages/sdk-python/tests/test_browser.py b/packages/sdk-python/tests/test_browser.py index da677673f5..45e105a65a 100644 --- a/packages/sdk-python/tests/test_browser.py +++ b/packages/sdk-python/tests/test_browser.py @@ -800,13 +800,13 @@ async def test_browserbase_validation_precedes_api_calls( _, api_keys = _install_browserbase_client(monkeypatch) with pytest.raises(ValueError, match="api_key"): await browserbase.launch(api_key="") - with pytest.raises(ValueError, match="^base_url must not be empty$"): + with pytest.raises(ValueError, match=r"^base_url must not be empty$"): await browserbase.launch(api_key="api-key", base_url=" ") - with pytest.raises(ValueError, match="^extension_id must not be empty$"): + with pytest.raises(ValueError, match=r"^extension_id must not be empty$"): await browserbase.launch(api_key="api-key", extension_id=" ") with pytest.raises( ValueError, - match="^browser_settings.extension_id must not be empty$", + match=r"^browser_settings.extension_id must not be empty$", ): await browserbase.launch( api_key="api-key", @@ -987,7 +987,7 @@ def create_profile(**_kwargs: object) -> str: monkeypatch.setattr(browser.tempfile, "mkdtemp", create_profile) - with pytest.raises(RuntimeError, match="Chrome executable.*does not exist"): + with pytest.raises(RuntimeError, match=r"Chrome executable.*does not exist"): await _launch_local_browser(LocalBrowserLaunchOptions(executable_path="/missing/chrome")) diff --git a/packages/sdk-python/tests/test_browserbase_session.py b/packages/sdk-python/tests/test_browserbase_session.py index cbe610aa2a..37ade2b073 100644 --- a/packages/sdk-python/tests/test_browserbase_session.py +++ b/packages/sdk-python/tests/test_browserbase_session.py @@ -259,7 +259,7 @@ async def test_create_failure_deletes_owned_extension_best_effort( fake_api.delete_errors = [OSError("cleanup failed")] with pytest.raises( BrowserbaseSessionError, - match="^Failed to create a Browserbase session$", + match=r"^Failed to create a Browserbase session$", ) as raised: await _BrowserbaseSessionClient(fake_api).create_session(BrowserbaseSessionCreateParams()) assert raised.value.__cause__ is None @@ -362,12 +362,12 @@ async def test_connect_validates_sanitizes_and_normalizes( fake_api: FakeBrowserbaseAPI, ) -> None: client = _BrowserbaseSessionClient(fake_api) - with pytest.raises(BrowserbaseSessionError, match="^A Browserbase session ID is required$"): + with pytest.raises(BrowserbaseSessionError, match=r"^A Browserbase session ID is required$"): await client.connect_session(" ") fake_api.retrieve_error = OSError("secret") with pytest.raises( BrowserbaseSessionError, - match="^Failed to retrieve the Browserbase session$", + match=r"^Failed to retrieve the Browserbase session$", ) as raised: await client.connect_session(" session ") assert raised.value.__cause__ is None @@ -375,7 +375,7 @@ async def test_connect_validates_sanitizes_and_normalizes( fake_api.retrieve_result = (" ", None, None) with pytest.raises( BrowserbaseSessionError, - match="^Browserbase session is not available for connection$", + match=r"^Browserbase session is not available for connection$", ): await client.connect_session(" session ") diff --git a/packages/sdk-python/tests/test_cdp_client.py b/packages/sdk-python/tests/test_cdp_client.py index b52f55aaf7..2e0809ab9d 100644 --- a/packages/sdk-python/tests/test_cdp_client.py +++ b/packages/sdk-python/tests/test_cdp_client.py @@ -453,7 +453,7 @@ async def connect(_: str) -> FakeWebSocket: monkeypatch.setattr(cdp_client, "_resolve_browser_web_socket_url", resolve) monkeypatch.setattr(cdp_client, "_connect_web_socket", connect) - with pytest.raises(RuntimeError, match="does not support Extensions.loadUnpacked"): + with pytest.raises(RuntimeError, match=r"does not support Extensions.loadUnpacked"): await CDPClient.connect( cdp_url="http://127.0.0.1:9222", extension_dir="/tmp/stagehand-extension", @@ -594,7 +594,7 @@ async def test_installed_extension_discovery_propagates_cdp_command_errors() -> socket = FakeWebSocket(lambda _: {"error": {"code": -32601, "message": "Method not available"}}) client = CDPClient(socket, "ws://127.0.0.1/devtools/browser/test") try: - with pytest.raises(RuntimeError, match="Extensions.getExtensions: Method not available"): + with pytest.raises(RuntimeError, match=r"Extensions.getExtensions: Method not available"): await client._discover_installed_stagehand_extension_id() finally: await client.close() diff --git a/packages/sdk-python/tests/test_page.py b/packages/sdk-python/tests/test_page.py index f4f97a05b9..e005cb5787 100644 --- a/packages/sdk-python/tests/test_page.py +++ b/packages/sdk-python/tests/test_page.py @@ -185,7 +185,7 @@ async def test_page_url_returns_a_scalar_string() -> None: async def test_page_on_rejects_unsupported_events_before_subscribing(event: str) -> None: recording = RecordingRPCClient({}) page = Page(cast(RPCClient, recording), PageRef(page_id="page-1")) - with pytest.raises(ValueError, match='page.on only supports "console" events'): + with pytest.raises(ValueError, match=r'page.on only supports "console" events'): await page.on(cast(PageEventName, event), lambda _: None) assert recording.calls == [] assert recording.notifications == {} @@ -552,7 +552,7 @@ async def test_unsubscribe_retries_after_page_off_failure() -> None: page = Page(cast(RPCClient, recording), PageRef(page_id="page-1")) subscription = await page.on("console", lambda _: None) - with pytest.raises(RuntimeError, match="temporary page.off failure"): + with pytest.raises(RuntimeError, match=r"temporary page.off failure"): await subscription.unsubscribe() assert "page.cdp_event" in recording.notifications diff --git a/packages/sdk-python/tests/test_response.py b/packages/sdk-python/tests/test_response.py index d03fe19528..ded034b594 100644 --- a/packages/sdk-python/tests/test_response.py +++ b/packages/sdk-python/tests/test_response.py @@ -128,7 +128,7 @@ async def test_response_surfaces_finished_failures_transport_errors_and_malforme finished_error = await response.finished() assert isinstance(finished_error, RuntimeError) assert str(finished_error) == "net::ERR_FAILED" - with pytest.raises(ValueError, match="response.body returned invalid base64"): + with pytest.raises(ValueError, match=r"response.body returned invalid base64"): await response.body() with pytest.raises(RuntimeError, match="handle unavailable"): await response.all_headers() @@ -139,7 +139,7 @@ async def test_response_rejects_noncanonical_base64_pad_bits() -> None: recording = RecordingRPCClient({"response.body": {"body": "Zh==", "base64_encoded": True}}) response = Response(cast(RPCClient, recording), descriptor()) - with pytest.raises(ValueError, match="response.body returned invalid base64"): + with pytest.raises(ValueError, match=r"response.body returned invalid base64"): await response.body() diff --git a/packages/sdk-python/tests/test_stagehand.py b/packages/sdk-python/tests/test_stagehand.py index 2f1336ea9a..08f8441261 100644 --- a/packages/sdk-python/tests/test_stagehand.py +++ b/packages/sdk-python/tests/test_stagehand.py @@ -133,7 +133,7 @@ def build_rpc_client( def test_stagehand_constructor_is_private() -> None: - with pytest.raises(TypeError, match="Stagehand.create"): + with pytest.raises(TypeError, match=r"Stagehand.create"): Stagehand() @@ -691,9 +691,9 @@ async def test_close_is_memoized_and_never_closes_browser_or_transport( assert recording.close_transport_flags == [False] assert browser.closed is False assert transport.close_calls == 0 - with pytest.raises(RuntimeError, match="Browser context is unavailable.*Stagehand.create"): + with pytest.raises(RuntimeError, match=r"Browser context is unavailable.*Stagehand.create"): _ = stagehand.browser.context - with pytest.raises(RuntimeError, match="Stagehand is unavailable.*Stagehand.create"): + with pytest.raises(RuntimeError, match=r"Stagehand is unavailable.*Stagehand.create"): await stagehand.metrics() next_recording = _recording() diff --git a/packages/sdk-python/uv.lock b/packages/sdk-python/uv.lock index 32ba0367b9..ed6f591bf6 100644 --- a/packages/sdk-python/uv.lock +++ b/packages/sdk-python/uv.lock @@ -738,27 +738,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/22/9e4f66ee588588dc6c9af6a994e12d26e19efbe874d1a909d09a6dac7a59/ruff-0.15.7.tar.gz", hash = "sha256:04f1ae61fc20fe0b148617c324d9d009b5f63412c0b16474f3d5f1a1a665f7ac", size = 4601277, upload-time = "2026-03-19T16:26:22.605Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/41/2f/0b08ced94412af091807b6119ca03755d651d3d93a242682bf020189db94/ruff-0.15.7-py3-none-linux_armv6l.whl", hash = "sha256:a81cc5b6910fb7dfc7c32d20652e50fa05963f6e13ead3c5915c41ac5d16668e", size = 10489037, upload-time = "2026-03-19T16:26:32.47Z" }, - { url = "https://files.pythonhosted.org/packages/91/4a/82e0fa632e5c8b1eba5ee86ecd929e8ff327bbdbfb3c6ac5d81631bef605/ruff-0.15.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:722d165bd52403f3bdabc0ce9e41fc47070ac56d7a91b4e0d097b516a53a3477", size = 10955433, upload-time = "2026-03-19T16:27:00.205Z" }, - { url = "https://files.pythonhosted.org/packages/ab/10/12586735d0ff42526ad78c049bf51d7428618c8b5c467e72508c694119df/ruff-0.15.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7fbc2448094262552146cbe1b9643a92f66559d3761f1ad0656d4991491af49e", size = 10269302, upload-time = "2026-03-19T16:26:26.183Z" }, - { url = "https://files.pythonhosted.org/packages/eb/5d/32b5c44ccf149a26623671df49cbfbd0a0ae511ff3df9d9d2426966a8d57/ruff-0.15.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b39329b60eba44156d138275323cc726bbfbddcec3063da57caa8a8b1d50adf", size = 10607625, upload-time = "2026-03-19T16:27:03.263Z" }, - { url = "https://files.pythonhosted.org/packages/5d/f1/f0001cabe86173aaacb6eb9bb734aa0605f9a6aa6fa7d43cb49cbc4af9c9/ruff-0.15.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87768c151808505f2bfc93ae44e5f9e7c8518943e5074f76ac21558ef5627c85", size = 10324743, upload-time = "2026-03-19T16:27:09.791Z" }, - { url = "https://files.pythonhosted.org/packages/7a/87/b8a8f3d56b8d848008559e7c9d8bf367934d5367f6d932ba779456e2f73b/ruff-0.15.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb0511670002c6c529ec66c0e30641c976c8963de26a113f3a30456b702468b0", size = 11138536, upload-time = "2026-03-19T16:27:06.101Z" }, - { url = "https://files.pythonhosted.org/packages/e4/f2/4fd0d05aab0c5934b2e1464784f85ba2eab9d54bffc53fb5430d1ed8b829/ruff-0.15.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0d19644f801849229db8345180a71bee5407b429dd217f853ec515e968a6912", size = 11994292, upload-time = "2026-03-19T16:26:48.718Z" }, - { url = "https://files.pythonhosted.org/packages/64/22/fc4483871e767e5e95d1622ad83dad5ebb830f762ed0420fde7dfa9d9b08/ruff-0.15.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4806d8e09ef5e84eb19ba833d0442f7e300b23fe3f0981cae159a248a10f0036", size = 11398981, upload-time = "2026-03-19T16:26:54.513Z" }, - { url = "https://files.pythonhosted.org/packages/b0/99/66f0343176d5eab02c3f7fcd2de7a8e0dd7a41f0d982bee56cd1c24db62b/ruff-0.15.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dce0896488562f09a27b9c91b1f58a097457143931f3c4d519690dea54e624c5", size = 11242422, upload-time = "2026-03-19T16:26:29.277Z" }, - { url = "https://files.pythonhosted.org/packages/5d/3a/a7060f145bfdcce4c987ea27788b30c60e2c81d6e9a65157ca8afe646328/ruff-0.15.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:1852ce241d2bc89e5dc823e03cff4ce73d816b5c6cdadd27dbfe7b03217d2a12", size = 11232158, upload-time = "2026-03-19T16:26:42.321Z" }, - { url = "https://files.pythonhosted.org/packages/a7/53/90fbb9e08b29c048c403558d3cdd0adf2668b02ce9d50602452e187cd4af/ruff-0.15.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5f3e4b221fb4bd293f79912fc5e93a9063ebd6d0dcbd528f91b89172a9b8436c", size = 10577861, upload-time = "2026-03-19T16:26:57.459Z" }, - { url = "https://files.pythonhosted.org/packages/2f/aa/5f486226538fe4d0f0439e2da1716e1acf895e2a232b26f2459c55f8ddad/ruff-0.15.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b15e48602c9c1d9bdc504b472e90b90c97dc7d46c7028011ae67f3861ceba7b4", size = 10327310, upload-time = "2026-03-19T16:26:35.909Z" }, - { url = "https://files.pythonhosted.org/packages/99/9e/271afdffb81fe7bfc8c43ba079e9d96238f674380099457a74ccb3863857/ruff-0.15.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:1b4705e0e85cedc74b0a23cf6a179dbb3df184cb227761979cc76c0440b5ab0d", size = 10840752, upload-time = "2026-03-19T16:26:45.723Z" }, - { url = "https://files.pythonhosted.org/packages/bf/29/a4ae78394f76c7759953c47884eb44de271b03a66634148d9f7d11e721bd/ruff-0.15.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:112c1fa316a558bb34319282c1200a8bf0495f1b735aeb78bfcb2991e6087580", size = 11336961, upload-time = "2026-03-19T16:26:39.076Z" }, - { url = "https://files.pythonhosted.org/packages/26/6b/8786ba5736562220d588a2f6653e6c17e90c59ced34a2d7b512ef8956103/ruff-0.15.7-py3-none-win32.whl", hash = "sha256:6d39e2d3505b082323352f733599f28169d12e891f7dd407f2d4f54b4c2886de", size = 10582538, upload-time = "2026-03-19T16:26:15.992Z" }, - { url = "https://files.pythonhosted.org/packages/2b/e9/346d4d3fffc6871125e877dae8d9a1966b254fbd92a50f8561078b88b099/ruff-0.15.7-py3-none-win_amd64.whl", hash = "sha256:4d53d712ddebcd7dace1bc395367aec12c057aacfe9adbb6d832302575f4d3a1", size = 11755839, upload-time = "2026-03-19T16:26:19.897Z" }, - { url = "https://files.pythonhosted.org/packages/8f/e8/726643a3ea68c727da31570bde48c7a10f1aa60eddd628d94078fec586ff/ruff-0.15.7-py3-none-win_arm64.whl", hash = "sha256:18e8d73f1c3fdf27931497972250340f92e8c861722161a9caeb89a58ead6ed2", size = 11023304, upload-time = "2026-03-19T16:26:51.669Z" }, +version = "0.16.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/78/449cb84790bd5cc3823b2652ee405a4558856e5c4195aee3a16bf7b3eb5d/ruff-0.16.8.tar.gz", hash = "sha256:9247bf92b5f04d825c8639a4fe423ec2e4222acd9222e58412b0dab7e442798b", size = 4938814, upload-time = "2026-09-16T15:54:46.688Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/25/6071aabc530e9be7e2c195e8fe3f7aea2735405b6cf447212832d7811831/ruff-0.16.8-py3-none-linux_armv6l.whl", hash = "sha256:6ffbd6d87383c1edf5f6fa890f10200950240d7c1a16052a19a09d3a2307dd38", size = 10048966, upload-time = "2026-09-16T15:53:57.605Z" }, + { url = "https://files.pythonhosted.org/packages/54/98/07f90ecbc74dd5fb5764f11f2bc774d6a7cffef92d2ff5f5b4e9e23c754e/ruff-0.16.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:42ed6b878ed61e3acca92f2730a17acff39286944ea82398544696366a6f925e", size = 10165498, upload-time = "2026-09-16T15:54:01.14Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1f/e6a712e3b47cad4a40600134105ed193cb773f618a42eb7ba323cb812cc0/ruff-0.16.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7ea781c7f2afba8c6a505ea0fb3f994020249e0c450635f5381286fea6b46170", size = 9830004, upload-time = "2026-09-16T15:54:03.998Z" }, + { url = "https://files.pythonhosted.org/packages/23/f2/311a08776d75d81c7676e20b6b020ae63cbe881fcdc7a8dd64e6e18bdd93/ruff-0.16.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8efeae3bbe414a5efefda11a792dfb51ef90ac48d50c4830de2f644caf3e8659", size = 9986558, upload-time = "2026-09-16T15:54:06.804Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ed/37b6cb3d3ba8c73e68ae3eb1d502383beb5aa05a582bb7bb3a922f929f54/ruff-0.16.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a79b795469fef7fc6e908b218eed2eb17332afd85031db6480dc864560e69b2", size = 9877332, upload-time = "2026-09-16T15:54:09.552Z" }, + { url = "https://files.pythonhosted.org/packages/22/cc/40873a8f36ad084cc540d55fcca7077264d5b13b24659e9180c176fb2b08/ruff-0.16.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fdc5563cdc50555e6fba39322850860e9267c1b3d12c26a74729d8604c3c812", size = 10507125, upload-time = "2026-09-16T15:54:12.152Z" }, + { url = "https://files.pythonhosted.org/packages/c3/e4/fc91a642b78ccbab6b9477720f3644ae7a10a9bcce69a934679cd64f62bc/ruff-0.16.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:34508983c70665578dab88f5223d8e6228307e1135398ca8bfc8b7e9501e282b", size = 11336694, upload-time = "2026-09-16T15:54:15.489Z" }, + { url = "https://files.pythonhosted.org/packages/c2/3d/bbd2a9a600a4e73dc3e7548a249c8d1671273464b55822c6fae50f602dff/ruff-0.16.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:644bb578569e0ffc575741232bd385dacdd6fbe123f1a729e7a225f54aa3957f", size = 10774448, upload-time = "2026-09-16T15:54:18.16Z" }, + { url = "https://files.pythonhosted.org/packages/1a/41/d83af9879a7b6e8bf5fe16b1da0b134049d2f5d3afac12defb0897cb84bd/ruff-0.16.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15e7d226246961db9235098333caa13063906d3851136b84c2900b82f5daa1df", size = 10323796, upload-time = "2026-09-16T15:54:20.743Z" }, + { url = "https://files.pythonhosted.org/packages/f5/2c/cefd07bfe914b84943ea769ade8d607bd22750b965d3228eefd7cebd15d0/ruff-0.16.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a2bf6bc3e9ebdd4449abc6f06cf64b98051a2c61cf94d2fe9596518c881f1a1e", size = 10514115, upload-time = "2026-09-16T15:54:23.497Z" }, + { url = "https://files.pythonhosted.org/packages/f3/9d/76a2e26c79a23be6e6e3664c57bec9e9fc8de155cfb9e4b67ea91b64f9d7/ruff-0.16.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6ca111ba0849539165e9e59d2b442542f3c1e8060ebbdea82494f1ffbccb1e1f", size = 10072582, upload-time = "2026-09-16T15:54:26.185Z" }, + { url = "https://files.pythonhosted.org/packages/2e/d4/f42edddb39668af1a559ceafa3823aedd65633a48dc9768e775485faa2c1/ruff-0.16.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:359a1e5b495448ee1e91018064382ebc86f90e8aac2fed222c7d0e4e8df85fd2", size = 9879644, upload-time = "2026-09-16T15:54:29.278Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/913e3195d95e0378786c6656945c865f534a3560e29139da4882aff630d1/ruff-0.16.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:59e8f5681349474110b24d62e93cfda6593f5fa3473446ca3705200cac1a08b9", size = 10231569, upload-time = "2026-09-16T15:54:32.036Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c4/8aa6ea0bdcedbd1bf87397e2fc4ed8406448ea5842f8660bc6e5f163039d/ruff-0.16.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:efa3e7a16d1baaa79957888dfdf8be9ef2e44db81cb032af06d76632ab59e773", size = 10663666, upload-time = "2026-09-16T15:54:34.838Z" }, + { url = "https://files.pythonhosted.org/packages/3d/02/7f10ef4700bc223c30a3fdd10631a29830c45524b810a3c7ed947af64591/ruff-0.16.8-py3-none-win32.whl", hash = "sha256:55793ba85c69921e89be061426d91a78652d6e50317c962240922747a4eb713f", size = 10093472, upload-time = "2026-09-16T15:54:37.47Z" }, + { url = "https://files.pythonhosted.org/packages/1e/5d/a509c07d714b6da88f2c518b4637cf6f1d46b074be8f0f1e5fb9ff5126fe/ruff-0.16.8-py3-none-win_amd64.whl", hash = "sha256:a6b85621fd3c81e31fc5f5add09c9c078b430db3595ca632efafdec9e64ebfaa", size = 10586899, upload-time = "2026-09-16T15:54:40.488Z" }, + { url = "https://files.pythonhosted.org/packages/fe/a0/50787329e4f20bf9dc9f6230015d46ec69c51a97ace5bc202dae4755365d/ruff-0.16.8-py3-none-win_arm64.whl", hash = "sha256:d075e820af612102ce217f07cc93e69f9490b10ec13ea85fa87bd03d996cef8a", size = 10386316, upload-time = "2026-09-16T15:54:43.332Z" }, ] [[package]] @@ -807,7 +807,7 @@ dev = [ { name = "openai", specifier = ">=2,<3" }, { name = "pytest", specifier = "==9.0.2" }, { name = "pytest-asyncio", specifier = "==1.3.0" }, - { name = "ruff", specifier = "==0.15.7" }, + { name = "ruff", specifier = "==0.16.8" }, { name = "ty", specifier = "==0.0.82" }, ] From 9e6d361efc6634c9c8a3964046a599ab127a8de4 Mon Sep 17 00:00:00 2001 From: Vishal Anton Date: Sun, 20 Sep 2026 13:03:55 +0530 Subject: [PATCH 2/2] Update Python SDK linting rules and fix regex pattern in tests --- packages/sdk-python/pyproject.toml | 5 +++++ packages/sdk-python/tests/test_browser_context.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/sdk-python/pyproject.toml b/packages/sdk-python/pyproject.toml index a628959c64..439838c177 100644 --- a/packages/sdk-python/pyproject.toml +++ b/packages/sdk-python/pyproject.toml @@ -41,17 +41,22 @@ select = [ "B015", "B018", "B904", + "C4", "E", "F", "I", + "PGH", "PYI", "RUF018", "RUF022", "RUF023", + "RUF039", "RUF043", "RUF100", + "T10", "TID252", "UP", + "W", ] external = ["S"] diff --git a/packages/sdk-python/tests/test_browser_context.py b/packages/sdk-python/tests/test_browser_context.py index c314ebb525..dc793c53f0 100644 --- a/packages/sdk-python/tests/test_browser_context.py +++ b/packages/sdk-python/tests/test_browser_context.py @@ -70,7 +70,7 @@ async def test_browser_context_serializes_python_cookie_filters() -> None: context = BrowserContext(cast(RPCClient, recording), _close_browser) await context.clear_cookies( - name=re.compile("^session$", re.IGNORECASE), + name=re.compile(r"^session$", re.IGNORECASE), domain="example.com", )