Skip to content

Commit 99e6fea

Browse files
committed
Merge branch 'custom-iterator-for-faster-stack-trace' of https://github.com/neoncube2/playwright-python into custom-iterator-for-faster-stack-trace
2 parents 2a08bac + 20c0c6b commit 99e6fea

File tree

1 file changed

+47
-11
lines changed

1 file changed

+47
-11
lines changed

playwright/_impl/_connection.py

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
import inspect
2020
import sys
2121
import traceback
22+
from inspect import FrameInfo
2223
from pathlib import Path
2324
from typing import (
2425
TYPE_CHECKING,
2526
Any,
2627
Callable,
2728
Dict,
29+
Generator,
2830
List,
2931
Mapping,
3032
Optional,
@@ -362,7 +364,7 @@ def _send_message_to_server(
362364
"params": self._replace_channels_with_guids(params),
363365
"metadata": metadata,
364366
}
365-
if self._tracing_count > 0 and frames and object._guid != "localUtils":
367+
if self.needs_full_stack_trace() and frames and object._guid != "localUtils":
366368
self.local_utils.add_stack_to_tracing_no_reply(id, frames)
367369

368370
self._transport.send(message)
@@ -508,17 +510,44 @@ def _replace_guids_with_channels(self, payload: Any) -> Any:
508510
return result
509511
return payload
510512

513+
def needs_full_stack_trace(self) -> bool:
514+
return self._tracing_count > 0
515+
516+
def get_frame_info(self) -> Generator[FrameInfo]:
517+
current_frame = inspect.currentframe()
518+
519+
if current_frame is None:
520+
return
521+
522+
# Don't include the current method ("get_frame_info()") in the callstack
523+
current_frame = current_frame.f_back
524+
525+
while current_frame:
526+
traceback_info = inspect.getframeinfo(current_frame, 0)
527+
528+
yield FrameInfo(
529+
current_frame,
530+
traceback_info.filename,
531+
traceback_info.lineno,
532+
traceback_info.function,
533+
traceback_info.code_context,
534+
traceback_info.index,
535+
)
536+
537+
current_frame = current_frame.f_back
538+
511539
async def wrap_api_call(
512540
self, cb: Callable[[], Any], is_internal: bool = False
513541
) -> Any:
514542
if self._api_zone.get():
515543
return await cb()
516544
task = asyncio.current_task(self._loop)
517-
st: List[inspect.FrameInfo] = getattr(
518-
task, "__pw_stack__", None
519-
) or inspect.stack(0)
520-
521-
parsed_st = _extract_stack_trace_information_from_stack(st, is_internal)
545+
st: Union[List[FrameInfo], Generator[FrameInfo]] = (
546+
getattr(task, "__pw_stack__", None) or self.get_frame_info()
547+
)
548+
parsed_st = _extract_stack_trace_information_from_stack(
549+
st, is_internal, self.needs_full_stack_trace()
550+
)
522551
self._api_zone.set(parsed_st)
523552
try:
524553
return await cb()
@@ -533,10 +562,12 @@ def wrap_api_call_sync(
533562
if self._api_zone.get():
534563
return cb()
535564
task = asyncio.current_task(self._loop)
536-
st: List[inspect.FrameInfo] = getattr(
537-
task, "__pw_stack__", None
538-
) or inspect.stack(0)
539-
parsed_st = _extract_stack_trace_information_from_stack(st, is_internal)
565+
st: Union[List[FrameInfo], Generator[FrameInfo]] = (
566+
getattr(task, "__pw_stack__", None) or self.get_frame_info()
567+
)
568+
parsed_st = _extract_stack_trace_information_from_stack(
569+
st, is_internal, self.needs_full_stack_trace()
570+
)
540571
self._api_zone.set(parsed_st)
541572
try:
542573
return cb()
@@ -567,7 +598,9 @@ class ParsedStackTrace(TypedDict):
567598

568599

569600
def _extract_stack_trace_information_from_stack(
570-
st: List[inspect.FrameInfo], is_internal: bool
601+
st: Union[List[FrameInfo], Generator[FrameInfo]],
602+
is_internal: bool,
603+
needs_full_stack: bool,
571604
) -> ParsedStackTrace:
572605
playwright_module_path = str(Path(playwright.__file__).parents[0])
573606
last_internal_api_name = ""
@@ -596,6 +629,9 @@ def _extract_stack_trace_information_from_stack(
596629
"function": method_name,
597630
}
598631
)
632+
633+
if not needs_full_stack:
634+
break
599635
if is_playwright_internal:
600636
last_internal_api_name = method_name
601637
elif last_internal_api_name:

0 commit comments

Comments
 (0)