From 7c62d27d2c53141f5ee3b438bded66a442518df2 Mon Sep 17 00:00:00 2001 From: Waket Zheng Date: Thu, 18 Sep 2025 11:33:03 +0800 Subject: [PATCH 1/2] fix: windows asyncio raises NotImplementedError --- src/ptpython/repl.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ptpython/repl.py b/src/ptpython/repl.py index 9077268..41b7dc7 100644 --- a/src/ptpython/repl.py +++ b/src/ptpython/repl.py @@ -12,6 +12,7 @@ import asyncio import builtins +import inspect import os import signal import sys @@ -192,6 +193,7 @@ def run(self) -> None: async def run_and_show_expression_async(self, text: str) -> Any: loop = asyncio.get_running_loop() system_exit: SystemExit | None = None + is_signal_handled = False try: try: @@ -208,7 +210,10 @@ async def eval() -> Any: system_exit = e task = asyncio.create_task(eval()) - loop.add_signal_handler(signal.SIGINT, lambda *_: task.cancel()) + f = loop.add_signal_handler + if "raise NotImplementedError" not in inspect.getsource(f): + f(signal.SIGINT, lambda *_: task.cancel()) + is_signal_handled = True result = await task if system_exit is not None: @@ -231,7 +236,8 @@ async def eval() -> Any: # Return the result for future consumers. return result finally: - loop.remove_signal_handler(signal.SIGINT) + if is_signal_handled: + loop.remove_signal_handler(signal.SIGINT) except KeyboardInterrupt as e: # Handle all possible `KeyboardInterrupt` errors. This can From 600fc17763b6408a20867df76b70b0e55d6766a4 Mon Sep 17 00:00:00 2001 From: Waket Zheng Date: Sun, 24 May 2026 15:24:32 +0800 Subject: [PATCH 2/2] refactor: use `contextlib.suppress` instead of `inspect.getsource` --- src/ptpython/repl.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ptpython/repl.py b/src/ptpython/repl.py index 41b7dc7..8106f03 100644 --- a/src/ptpython/repl.py +++ b/src/ptpython/repl.py @@ -12,7 +12,7 @@ import asyncio import builtins -import inspect +import contextlib import os import signal import sys @@ -210,9 +210,9 @@ async def eval() -> Any: system_exit = e task = asyncio.create_task(eval()) - f = loop.add_signal_handler - if "raise NotImplementedError" not in inspect.getsource(f): - f(signal.SIGINT, lambda *_: task.cancel()) + with contextlib.suppress(NotImplementedError): + # Some event loops, notably on Windows, don't support add_signal_handler(). + loop.add_signal_handler(signal.SIGINT, lambda *_: task.cancel()) is_signal_handled = True result = await task