Skip to content

Commit 604d5f1

Browse files
authored
Override console Ctrl+C event handler with handler in module signal (#1951)
* Override console Ctrl+C event handler with handler in module `signal` * Use nullable annotation
1 parent 71a8f5c commit 604d5f1

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

src/core/IronPython.Modules/signal.SimpleSignalState.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,15 @@
1414
namespace IronPython.Modules {
1515
public static partial class PythonSignal {
1616
private class SimpleSignalState : PythonSignalState {
17+
private readonly ConsoleCancelEventHandler? _consoleHandler;
1718

1819
public SimpleSignalState(PythonContext pc) : base(pc) {
1920
Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);
21+
if (pc.Console is Microsoft.Scripting.Hosting.Shell.BasicConsole console) {
22+
// in console hosting scenarios, we need to override the console handler of Ctrl+C
23+
_consoleHandler = console.ConsoleCancelEventHandler;
24+
console.ConsoleCancelEventHandler = null;
25+
}
2026
}
2127

2228

@@ -42,8 +48,8 @@ private void Console_CancelKeyPress(object? sender, ConsoleCancelEventArgs e) {
4248
throw new InvalidOperationException("unreachable");
4349
}
4450
} else if (ReferenceEquals(handler, default_int_handler) && pySignal == SIGINT) {
45-
// Let the real interrupt handler throw a KeyboardInterrupt for SIGINT.
46-
// It handles this far more gracefully than we can
51+
// Forward the signal to the console handler, if any
52+
_consoleHandler?.Invoke(sender, e);
4753
return;
4854
} else {
4955
CallPythonHandler(pySignal, handler);

src/core/IronPython/Hosting/PythonCommandLine.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ protected override void Initialize() {
145145

146146
Console.Output = new OutputWriter(PythonContext, false);
147147
Console.ErrorOutput = new OutputWriter(PythonContext, true);
148+
Language.Console = Console;
148149

149150
// TODO: must precede path initialization! (??? - test test_importpkg.py)
150151
int pathIndex = PythonContext.PythonOptions.SearchPaths.Count;

src/core/IronPython/Runtime/PythonContext.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using Microsoft.Scripting.Actions;
2323
using Microsoft.Scripting.Debugging.CompilerServices;
2424
using Microsoft.Scripting.Generation;
25+
using Microsoft.Scripting.Hosting.Shell;
2526
using Microsoft.Scripting.Runtime;
2627
using Microsoft.Scripting.Utils;
2728

@@ -684,6 +685,15 @@ internal static Version GetPythonVersion()
684685

685686
internal FloatFormat DoubleFormat { get; set; }
686687

688+
#nullable enable
689+
690+
/// <summary>
691+
/// Not null if the Python context is running in a console host.
692+
/// </summary>
693+
internal IConsole? Console { get; set; }
694+
695+
#nullable restore
696+
687697
/// <summary>
688698
/// Initializes the sys module on startup. Called both to load and reload sys
689699
/// </summary>

0 commit comments

Comments
 (0)