From ac5cd71cbb8c93eeff1a27aa356734eb31a39936 Mon Sep 17 00:00:00 2001 From: Eli Black Date: Thu, 8 May 2025 15:36:35 +0800 Subject: [PATCH 1/3] Use stack(0) in more places, to avoid requesting expensive stack context information --- playwright/_impl/_network.py | 2 +- playwright/_impl/_path_utils.py | 6 ++++-- playwright/_impl/_sync_base.py | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/playwright/_impl/_network.py b/playwright/_impl/_network.py index 6492c4311..768c22f0c 100644 --- a/playwright/_impl/_network.py +++ b/playwright/_impl/_network.py @@ -530,7 +530,7 @@ async def _race_with_page_close(self, future: Coroutine) -> None: setattr( fut, "__pw_stack__", - getattr(asyncio.current_task(self._loop), "__pw_stack__", inspect.stack()), + getattr(asyncio.current_task(self._loop), "__pw_stack__", inspect.stack(0)), ) target_closed_future = self.request._target_closed_future() await asyncio.wait( diff --git a/playwright/_impl/_path_utils.py b/playwright/_impl/_path_utils.py index 267a82ab0..b405a0675 100644 --- a/playwright/_impl/_path_utils.py +++ b/playwright/_impl/_path_utils.py @@ -14,12 +14,14 @@ import inspect from pathlib import Path +from types import FrameType +from typing import cast def get_file_dirname() -> Path: """Returns the callee (`__file__`) directory name""" - frame = inspect.stack()[1] - module = inspect.getmodule(frame[0]) + frame = cast(FrameType, inspect.currentframe()).f_back + module = inspect.getmodule(frame) assert module assert module.__file__ return Path(module.__file__).parent.absolute() diff --git a/playwright/_impl/_sync_base.py b/playwright/_impl/_sync_base.py index b50c7479d..21bf2d00a 100644 --- a/playwright/_impl/_sync_base.py +++ b/playwright/_impl/_sync_base.py @@ -105,7 +105,7 @@ def _sync( g_self = greenlet.getcurrent() task: asyncio.tasks.Task[Any] = self._loop.create_task(coro) - setattr(task, "__pw_stack__", inspect.stack()) + setattr(task, "__pw_stack__", inspect.stack(0)) setattr(task, "__pw_stack_trace__", traceback.extract_stack()) task.add_done_callback(lambda _: g_self.switch()) From 822dcaca30a7b84b9334eafeabf34759abbf6eb7 Mon Sep 17 00:00:00 2001 From: Eli Black Date: Thu, 8 May 2025 15:50:24 +0800 Subject: [PATCH 2/3] Only retrieve first 10 frames from callstack, for performance reasons --- playwright/_impl/_connection.py | 4 ++-- playwright/_impl/_sync_base.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/playwright/_impl/_connection.py b/playwright/_impl/_connection.py index 2d1dad933..f58239715 100644 --- a/playwright/_impl/_connection.py +++ b/playwright/_impl/_connection.py @@ -333,7 +333,7 @@ def _send_message_to_server( task = asyncio.current_task(self._loop) callback.stack_trace = cast( traceback.StackSummary, - getattr(task, "__pw_stack_trace__", traceback.extract_stack()), + getattr(task, "__pw_stack_trace__", traceback.extract_stack(limit=10)), ) callback.no_reply = no_reply self._callbacks[id] = callback @@ -388,7 +388,7 @@ def dispatch(self, msg: ParsedMessagePayload) -> None: error["error"], format_call_log(msg.get("log")) # type: ignore ) parsed_error._stack = "".join( - traceback.format_list(callback.stack_trace)[-10:] + traceback.format_list(callback.stack_trace) ) callback.future.set_exception(parsed_error) else: diff --git a/playwright/_impl/_sync_base.py b/playwright/_impl/_sync_base.py index 21bf2d00a..e6fac9750 100644 --- a/playwright/_impl/_sync_base.py +++ b/playwright/_impl/_sync_base.py @@ -106,7 +106,7 @@ def _sync( g_self = greenlet.getcurrent() task: asyncio.tasks.Task[Any] = self._loop.create_task(coro) setattr(task, "__pw_stack__", inspect.stack(0)) - setattr(task, "__pw_stack_trace__", traceback.extract_stack()) + setattr(task, "__pw_stack_trace__", traceback.extract_stack(limit=10)) task.add_done_callback(lambda _: g_self.switch()) while not task.done(): From 81c7357873ae299a0447d942fc931f29b5d41ebb Mon Sep 17 00:00:00 2001 From: Eli Black Date: Thu, 8 May 2025 17:23:08 +0800 Subject: [PATCH 3/3] Use format() instead of traceback.format_list() --- playwright/_impl/_connection.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/playwright/_impl/_connection.py b/playwright/_impl/_connection.py index f58239715..1328e7c97 100644 --- a/playwright/_impl/_connection.py +++ b/playwright/_impl/_connection.py @@ -387,9 +387,7 @@ def dispatch(self, msg: ParsedMessagePayload) -> None: parsed_error = parse_error( error["error"], format_call_log(msg.get("log")) # type: ignore ) - parsed_error._stack = "".join( - traceback.format_list(callback.stack_trace) - ) + parsed_error._stack = "".join(callback.stack_trace.format()) callback.future.set_exception(parsed_error) else: result = self._replace_guids_with_channels(msg.get("result"))