diff --git a/src/core/IronPython.Modules/signal.SimpleSignalState.cs b/src/core/IronPython.Modules/signal.SimpleSignalState.cs index 473c64151..b9084d6f6 100644 --- a/src/core/IronPython.Modules/signal.SimpleSignalState.cs +++ b/src/core/IronPython.Modules/signal.SimpleSignalState.cs @@ -14,9 +14,15 @@ namespace IronPython.Modules { public static partial class PythonSignal { private class SimpleSignalState : PythonSignalState { + private readonly ConsoleCancelEventHandler? _consoleHandler; public SimpleSignalState(PythonContext pc) : base(pc) { Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress); + if (pc.Console is Microsoft.Scripting.Hosting.Shell.BasicConsole console) { + // in console hosting scenarios, we need to override the console handler of Ctrl+C + _consoleHandler = console.ConsoleCancelEventHandler; + console.ConsoleCancelEventHandler = null; + } } @@ -42,8 +48,8 @@ private void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e) { throw new InvalidOperationException("unreachable"); } } else if (ReferenceEquals(handler, default_int_handler) && pySignal == SIGINT) { - // Let the real interrupt handler throw a KeyboardInterrupt for SIGINT. - // It handles this far more gracefully than we can + // Forward the signal to the console handler, if any + _consoleHandler?.Invoke(sender, e); return; } else { CallPythonHandler(pySignal, handler); diff --git a/src/core/IronPython/Hosting/PythonCommandLine.cs b/src/core/IronPython/Hosting/PythonCommandLine.cs index 781836ddd..2fc86f071 100644 --- a/src/core/IronPython/Hosting/PythonCommandLine.cs +++ b/src/core/IronPython/Hosting/PythonCommandLine.cs @@ -145,6 +145,7 @@ protected override void Initialize() { Console.Output = new OutputWriter(PythonContext, false); Console.ErrorOutput = new OutputWriter(PythonContext, true); + Language.Console = Console; // TODO: must precede path initialization! (??? - test test_importpkg.py) int pathIndex = PythonContext.PythonOptions.SearchPaths.Count; diff --git a/src/core/IronPython/Runtime/PythonContext.cs b/src/core/IronPython/Runtime/PythonContext.cs index 23090b46e..27f563dfb 100644 --- a/src/core/IronPython/Runtime/PythonContext.cs +++ b/src/core/IronPython/Runtime/PythonContext.cs @@ -22,6 +22,7 @@ using Microsoft.Scripting.Actions; using Microsoft.Scripting.Debugging.CompilerServices; using Microsoft.Scripting.Generation; +using Microsoft.Scripting.Hosting.Shell; using Microsoft.Scripting.Runtime; using Microsoft.Scripting.Utils; @@ -684,6 +685,15 @@ internal static Version GetPythonVersion() internal FloatFormat DoubleFormat { get; set; } +#nullable enable + + /// + /// Not null if the Python context is running in a console host. + /// + internal IConsole? Console { get; set; } + +#nullable restore + /// /// Initializes the sys module on startup. Called both to load and reload sys ///