Skip to content

Rebased PR 450 (Py_Initialize without overriding signals) #724

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ on_finish:

artifacts:
- path: dist\*
- path: TestResult.xml
name: TestResult
type: xml

notifications:
- provider: Slack
Expand Down
71 changes: 34 additions & 37 deletions pythonnet.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2046
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Python.Runtime", "src\runtime\Python.Runtime.csproj", "{097B4AC0-74E9-4C58-BCF8-C69746EC8271}"
EndProject
Expand Down Expand Up @@ -32,38 +32,38 @@ Global
ReleaseWinPY3|x86 = ReleaseWinPY3|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x64.ActiveCfg = DebugMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x64.Build.0 = DebugMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x86.ActiveCfg = DebugMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x86.Build.0 = DebugMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x64.ActiveCfg = DebugMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x64.Build.0 = DebugMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x86.ActiveCfg = DebugMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x86.Build.0 = DebugMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x64.ActiveCfg = DebugWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x64.Build.0 = DebugWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x86.ActiveCfg = DebugWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x86.Build.0 = DebugWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x64.ActiveCfg = DebugWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x64.Build.0 = DebugWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x86.ActiveCfg = DebugWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x86.Build.0 = DebugWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x64.ActiveCfg = ReleaseMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x64.Build.0 = ReleaseMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x86.ActiveCfg = ReleaseMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x86.Build.0 = ReleaseMono|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x64.ActiveCfg = ReleaseMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x64.Build.0 = ReleaseMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x86.ActiveCfg = ReleaseMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x86.Build.0 = ReleaseMonoPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x64.ActiveCfg = ReleaseWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x64.Build.0 = ReleaseWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x86.ActiveCfg = ReleaseWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x86.Build.0 = ReleaseWin|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x64.ActiveCfg = ReleaseWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x64.Build.0 = ReleaseWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x86.ActiveCfg = ReleaseWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x86.Build.0 = ReleaseWinPY3|Any CPU
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x64.ActiveCfg = DebugMono|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x64.Build.0 = DebugMono|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x86.ActiveCfg = DebugMono|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMono|x86.Build.0 = DebugMono|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x64.ActiveCfg = DebugMonoPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x64.Build.0 = DebugMonoPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x86.ActiveCfg = DebugMonoPY3|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugMonoPY3|x86.Build.0 = DebugMonoPY3|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x64.ActiveCfg = DebugWin|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x64.Build.0 = DebugWin|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x86.ActiveCfg = DebugWin|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWin|x86.Build.0 = DebugWin|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x64.ActiveCfg = DebugWinPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x64.Build.0 = DebugWinPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x86.ActiveCfg = DebugWinPY3|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.DebugWinPY3|x86.Build.0 = DebugWinPY3|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x64.ActiveCfg = ReleaseMono|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x64.Build.0 = ReleaseMono|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x86.ActiveCfg = ReleaseMono|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMono|x86.Build.0 = ReleaseMono|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x64.ActiveCfg = ReleaseMonoPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x64.Build.0 = ReleaseMonoPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x86.ActiveCfg = ReleaseMonoPY3|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseMonoPY3|x86.Build.0 = ReleaseMonoPY3|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x64.ActiveCfg = ReleaseWin|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x64.Build.0 = ReleaseWin|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x86.ActiveCfg = ReleaseWin|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWin|x86.Build.0 = ReleaseWin|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x64.ActiveCfg = ReleaseWinPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x64.Build.0 = ReleaseWinPY3|x64
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x86.ActiveCfg = ReleaseWinPY3|x86
{097B4AC0-74E9-4C58-BCF8-C69746EC8271}.ReleaseWinPY3|x86.Build.0 = ReleaseWinPY3|x86
{6F401A34-273B-450F-9A4C-13550BE0767B}.DebugMono|x64.ActiveCfg = DebugMono|x64
{6F401A34-273B-450F-9A4C-13550BE0767B}.DebugMono|x64.Build.0 = DebugMono|x64
{6F401A34-273B-450F-9A4C-13550BE0767B}.DebugMono|x86.ActiveCfg = DebugMono|x86
Expand Down Expand Up @@ -188,9 +188,6 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {10AE1870-1175-445A-B23A-C83497EAAE4B}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = src\console\Console.csproj
Policies = $0
Expand Down
6 changes: 5 additions & 1 deletion src/embed_tests/Python.EmbeddingTest.15.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project>
<Project>
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />

<PropertyGroup>
Expand Down Expand Up @@ -82,8 +82,12 @@
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
<PackageReference Include="NUnitLite" Version="3.7.2" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="System.CodeDom">
<Version>4.5.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\runtime\Python.Runtime.15.csproj" />
Expand Down
1 change: 1 addition & 0 deletions src/embed_tests/Python.EmbeddingTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="TestConsoleInterrupt.cs" />
<Compile Include="dynamic.cs" />
<Compile Include="pyimport.cs" />
<Compile Include="pyinitialize.cs" />
Expand Down
127 changes: 127 additions & 0 deletions src/embed_tests/TestConsoleInterrupt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using Microsoft.CSharp;
using NUnit.Framework;
using Python.Runtime;
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;

namespace Python.EmbeddingTest
{
/// <summary>
/// This class tests that a console application with PythonEngine Initialize can be interrupted by CTRL+C.
/// </summary>
public class TestConsoleInterrupt
{
static readonly string program = @"
using System;
using Python.Runtime;
using System.Text;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
PythonEngine.Initialize(); // Comment this out to support CTRL+C again.
Console.WriteLine(""Waiting 5s.. Try CTRL+C."");
System.Threading.Thread.Sleep(5000);
Console.WriteLine(""Timeout"");
}
}
";

static string BuildAssembly(string code)
{
var provider = new CSharpCodeProvider();
var compilerparams = new CompilerParameters();
compilerparams.GenerateExecutable = true;
compilerparams.GenerateInMemory = false;
if (IntPtr.Size == 8)
{
compilerparams.CompilerOptions = "/platform:x64";
}
else
{
compilerparams.CompilerOptions = "/platform:x86";
}

var dir = TestContext.CurrentContext.TestDirectory;

compilerparams.OutputAssembly = System.IO.Path.Combine(dir, "testctrl.exe");
compilerparams.ReferencedAssemblies.Add(typeof(PythonEngine).Assembly.Location);
CompilerResults results = provider.CompileAssemblyFromSource(compilerparams, code);
if (results.Errors.HasErrors)
{
StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
foreach (CompilerError error in results.Errors)
{
errors.AppendFormat("Line {0},{1}\t: {2}\n", error.Line, error.Column, error.ErrorText);
}
throw new Exception(errors.ToString());
}
else
{
return results.PathToAssembly;
}
}

#if MONO_LINUX || MONO_OSX
[DllImport("libc")]
static extern bool kill(int pid, int signal);

static void invokeSigInt(Process proc)
{
int SIGINT = 2;
kill(proc.Id, SIGINT);
}

#else

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool GenerateConsoleCtrlEvent(int sigevent, int dwProcessGroupId);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();

[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(int handler, bool add);

static void invokeSigInt(Process proc)
{
FreeConsole();
AttachConsole((uint)proc.Id);
SetConsoleCtrlHandler(0, true);
System.Threading.Thread.Sleep(50);
GenerateConsoleCtrlEvent(0, 0);
System.Threading.Thread.Sleep(50);
FreeConsole();
SetConsoleCtrlHandler(0, false);
}

#endif

[Test]
public static void ConsoleInterrupt()
{
var path = BuildAssembly(program);
using (var process = Process.Start(new ProcessStartInfo(path, "") { UseShellExecute = false, RedirectStandardOutput = true }))
{

System.Threading.Thread.Sleep(100);
invokeSigInt(process);
if (!process.WaitForExit(500))
{
process.Kill();
Assert.Fail();
}
var str = process.StandardOutput.ReadToEnd();
Assert.IsTrue(str.Contains("Waiting")); // Program starts with "Waiting".
Assert.IsTrue(str.Contains("Timeout") == false); // program ends with "Timeout" but we should never get there.
}
}
}
}