Skip to content

Commit 79849c7

Browse files
fix(sync): filter shutdown console wait and remove callback before cancel
1 parent 8ff9ba6 commit 79849c7

2 files changed

Lines changed: 12 additions & 2 deletions

File tree

‎playwright/_impl/_greenlets.py‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,14 @@ def wait_for_future(
9494
) -> None:
9595
__tracebackhide__ = True
9696
g_self = greenlet.getcurrent()
97+
waiting = True
9798

9899
def resume(_: "asyncio.Future") -> None:
99-
g_self.switch()
100+
if waiting:
101+
g_self.switch()
100102

101103
# The wait owns the callback that resumes this greenlet, so that it can
102-
# remove it again when the wait is abandoned. A callback left behind would
104+
# remove it again when the wait ends. A callback left behind would
103105
# resume this greenlet at an arbitrary later point.
104106
future.add_done_callback(resume)
105107
try:
@@ -118,6 +120,10 @@ def resume(_: "asyncio.Future") -> None:
118120
future.cancel()
119121
raise
120122
finally:
123+
# A done future has already queued its callbacks; removing them from the
124+
# future cannot stop them, so also make a queued callback inactive.
125+
waiting = False
126+
future.remove_done_callback(resume)
121127
# The loop is only running for as long as the dispatcher fiber is alive.
122128
# Also after a signal handler interrupted it: run_forever() cleared this
123129
# on its way out, but the dispatcher is going to run the loop again.

‎tests/sync/python/test_sync.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ def _test_call_sync_method_after_playwright_close_with_own_loop(
186186
context = browser.new_context()
187187
page = context.new_page()
188188
page.goto(empty_page)
189+
with page.expect_console_message(lambda m: m.text == "hello") as console_info:
190+
page.evaluate("console.log('hello')")
191+
assert console_info.value.text == "hello"
189192
playwright.stop()
190193
with pytest.raises(Error) as exc:
191194
page.evaluate("1+1")
@@ -196,6 +199,7 @@ def _test_call_sync_method_after_playwright_close_with_own_loop(
196199
def test_call_sync_method_after_playwright_close_with_own_loop(
197200
server: Server, browser_name: str, launch_arguments: Dict[str, Any]
198201
) -> None:
202+
# Regression test for https://github.com/microsoft/playwright-python/issues/3307.
199203
p = multiprocessing.get_context("spawn").Process(
200204
target=_test_call_sync_method_after_playwright_close_with_own_loop,
201205
args=[browser_name, launch_arguments, server.EMPTY_PAGE],

0 commit comments

Comments
 (0)