Skip to content

Override console Ctrl+C event handler with handler in module signal #1951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 26, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/core/IronPython.Modules/signal.SimpleSignalState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}


Expand All @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/core/IronPython/Hosting/PythonCommandLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions src/core/IronPython/Runtime/PythonContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -684,6 +685,11 @@ internal static Version GetPythonVersion()

internal FloatFormat DoubleFormat { get; set; }

/// <summary>
/// Not null if the Python context is running in a console host.
/// </summary>
internal IConsole/*?*/ Console { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could do a #nullable enable / #nullable restore?


/// <summary>
/// Initializes the sys module on startup. Called both to load and reload sys
/// </summary>
Expand Down