Visitar URL original
Ensure that the tests work even if BinaryFormatter is not available by filmor · Pull Request #2638 · pythonnet/pythonnet · GitHub
Skip to content
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
Prev Previous commit
Move tests that require reinit and only run on .NET Framework
  • Loading branch information
filmor committed Dec 8, 2025
commit 2f24a35d9912df97a9463fdc011b6fc7d8d1d3e7
28 changes: 28 additions & 0 deletions src/embed_tests/NeedsReinit/StopAndRestartEngine.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Python.Runtime;
using NUnit.Framework;

namespace Python.EmbeddingTest.NeedsReinit;

public class StopAndRestartEngine
{
bool WasInitialized = false;

[OneTimeSetUp]
public void Setup()
{
WasInitialized = PythonEngine.IsInitialized;
if (WasInitialized)
{
PythonEngine.Shutdown();
}
}

[OneTimeTearDown]
public void Teardown()
{
if (WasInitialized && !PythonEngine.IsInitialized)
{
PythonEngine.Initialize();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
// Unfortunately this means no continuous integration testing for this case.
//
#if NETFRAMEWORK
namespace Python.EmbeddingTest
namespace Python.EmbeddingTest.NeedsReinit
{
class TestDomainReload
[Category("NeedsReinit")]
class TestDomainReload : StopAndRestartEngine
{


abstract class CrossCaller : MarshalByRefObject
{
public abstract ValueType Execute(ValueType arg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
using NUnit.Framework;
using Python.Runtime;

namespace Python.EmbeddingTest
namespace Python.EmbeddingTest.NeedsReinit
{
[Ignore("Only works if we can re-initialize the Python engine")]
public class PyInitializeTest
[Category("NeedsReinit")]
public class TestPyInitialize : StopAndRestartEngine
{
/// <summary>
/// Tests issue with multiple simple Initialize/Shutdowns.
Expand Down
133 changes: 133 additions & 0 deletions src/embed_tests/NeedsReinit/TestPythonEngineProperties.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using System;
using NUnit.Framework;
using Python.Runtime;

namespace Python.EmbeddingTest.NeedsReinit
{
[Category("NeedsReinit")]
public class TestPythonEngineProperties : StopAndRestartEngine
{
[Test]
public void SetPythonHome()
{
PythonEngine.Initialize();
var pythonHomeBackup = PythonEngine.PythonHome;
PythonEngine.Shutdown();

if (pythonHomeBackup == "")
Assert.Inconclusive("Can't reset PythonHome to empty string, skipping");

var pythonHome = "/dummypath/";

PythonEngine.PythonHome = pythonHome;
PythonEngine.Initialize();

Assert.AreEqual(pythonHome, PythonEngine.PythonHome);
PythonEngine.Shutdown();

// Restoring valid pythonhome.
PythonEngine.PythonHome = pythonHomeBackup;
}

[Test]
public void SetPythonHomeTwice()
{
PythonEngine.Initialize();
var pythonHomeBackup = PythonEngine.PythonHome;
PythonEngine.Shutdown();

if (pythonHomeBackup == "")
Assert.Inconclusive("Can't reset PythonHome to empty string, skipping");

var pythonHome = "/dummypath/";

PythonEngine.PythonHome = "/dummypath2/";
PythonEngine.PythonHome = pythonHome;
PythonEngine.Initialize();

Assert.AreEqual(pythonHome, PythonEngine.PythonHome);
PythonEngine.Shutdown();

PythonEngine.PythonHome = pythonHomeBackup;
}

[Test]
[Ignore("Currently buggy in Python")]
public void SetPythonHomeEmptyString()
{
PythonEngine.Initialize();

var backup = PythonEngine.PythonHome;
if (backup == "")
{
PythonEngine.Shutdown();
Assert.Inconclusive("Can't reset PythonHome to empty string, skipping");
}
PythonEngine.PythonHome = "";

Assert.AreEqual("", PythonEngine.PythonHome);

PythonEngine.PythonHome = backup;
PythonEngine.Shutdown();
}

[Test]
public void SetProgramName()
{
if (PythonEngine.IsInitialized)
{
PythonEngine.Shutdown();
}

var programNameBackup = PythonEngine.ProgramName;

var programName = "FooBar";

PythonEngine.ProgramName = programName;
PythonEngine.Initialize();

Assert.AreEqual(programName, PythonEngine.ProgramName);
PythonEngine.Shutdown();

PythonEngine.ProgramName = programNameBackup;
}

[Test]
public void SetPythonPath()
{
PythonEngine.Initialize();

const string moduleName = "pytest";
bool importShouldSucceed;
try
{
Py.Import(moduleName);
importShouldSucceed = true;
}
catch
{
importShouldSucceed = false;
}

string[] paths = Py.Import("sys").GetAttr("path").As<string[]>();
string path = string.Join(System.IO.Path.PathSeparator.ToString(), paths);

// path should not be set to PythonEngine.PythonPath here.
// PythonEngine.PythonPath gets the default module search path, not the full search path.
// The list sys.path is initialized with this value on interpreter startup;
// it can be (and usually is) modified later to change the search path for loading modules.
// See https://docs.python.org/3/c-api/init.html#c.Py_GetPath
// After PythonPath is set, then PythonEngine.PythonPath will correctly return the full search path.

PythonEngine.Shutdown();

PythonEngine.PythonPath = path;
PythonEngine.Initialize();

Assert.AreEqual(path, PythonEngine.PythonPath);
if (importShouldSucceed) Py.Import(moduleName);

PythonEngine.Shutdown();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,11 @@
using NUnit.Framework;
using Python.Runtime;

namespace Python.EmbeddingTest
namespace Python.EmbeddingTest.NeedsReinit
{
[Ignore("Only works if we can shutdown and re-initialize the Python runtime")]
public class TestRuntime
[Ignore("Tests for low-level Runtime functions, crashing currently")]
public class TestRuntime : StopAndRestartEngine
{
[OneTimeSetUp]
public void SetUp()
{
// We needs to ensure that no any engines are running.
if (PythonEngine.IsInitialized)
{
PythonEngine.Shutdown();
}
}

[Test]
public static void Py_IsInitializedValue()
{
Expand Down
5 changes: 5 additions & 0 deletions src/embed_tests/Python.EmbeddingTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
<None Include="fixtures/**/*.py" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

<!-- Drop Reinit test source files for net8.0 and above -->
<ItemGroup Condition="'$(TargetFramework)' != 'net472'">
<Compile Remove="NeedsReinit/*.cs" />
</ItemGroup>

<PropertyGroup>
<DefineConstants>$(DefineConstants);$(ConfiguredConstants)</DefineConstants>
</PropertyGroup>
Expand Down
127 changes: 0 additions & 127 deletions src/embed_tests/TestPythonEngineProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,132 +96,5 @@ public static void GetPythonHomeDefault()

Assert.AreEqual(envPythonHome, enginePythonHome);
}

[Ignore("Only works if we can shutdown and re-init the interpreter")]
[Test]
public void SetPythonHome()
{
PythonEngine.Initialize();
var pythonHomeBackup = PythonEngine.PythonHome;
PythonEngine.Shutdown();

if (pythonHomeBackup == "")
Assert.Inconclusive("Can't reset PythonHome to empty string, skipping");

var pythonHome = "/dummypath/";

PythonEngine.PythonHome = pythonHome;
PythonEngine.Initialize();

Assert.AreEqual(pythonHome, PythonEngine.PythonHome);
PythonEngine.Shutdown();

// Restoring valid pythonhome.
PythonEngine.PythonHome = pythonHomeBackup;
}

[Ignore("Only works if we can shutdown and re-init the interpreter")]
[Test]
public void SetPythonHomeTwice()
{
PythonEngine.Initialize();
var pythonHomeBackup = PythonEngine.PythonHome;
PythonEngine.Shutdown();

if (pythonHomeBackup == "")
Assert.Inconclusive("Can't reset PythonHome to empty string, skipping");

var pythonHome = "/dummypath/";

PythonEngine.PythonHome = "/dummypath2/";
PythonEngine.PythonHome = pythonHome;
PythonEngine.Initialize();

Assert.AreEqual(pythonHome, PythonEngine.PythonHome);
PythonEngine.Shutdown();

PythonEngine.PythonHome = pythonHomeBackup;
}

[Test]
[Ignore("Currently buggy in Python")]
public void SetPythonHomeEmptyString()
{
PythonEngine.Initialize();

var backup = PythonEngine.PythonHome;
if (backup == "")
{
PythonEngine.Shutdown();
Assert.Inconclusive("Can't reset PythonHome to empty string, skipping");
}
PythonEngine.PythonHome = "";

Assert.AreEqual("", PythonEngine.PythonHome);

PythonEngine.PythonHome = backup;
PythonEngine.Shutdown();
}

[Ignore("Only works if we can shutdown and re-init the interpreter")]
[Test]
public void SetProgramName()
{
if (PythonEngine.IsInitialized)
{
PythonEngine.Shutdown();
}

var programNameBackup = PythonEngine.ProgramName;

var programName = "FooBar";

PythonEngine.ProgramName = programName;
PythonEngine.Initialize();

Assert.AreEqual(programName, PythonEngine.ProgramName);
PythonEngine.Shutdown();

PythonEngine.ProgramName = programNameBackup;
}

[Ignore("Only works if we can shutdown and re-init the interpreter")]
[Test]
public void SetPythonPath()
{
PythonEngine.Initialize();

const string moduleName = "pytest";
bool importShouldSucceed;
try
{
Py.Import(moduleName);
importShouldSucceed = true;
}
catch
{
importShouldSucceed = false;
}

string[] paths = Py.Import("sys").GetAttr("path").As<string[]>();
string path = string.Join(System.IO.Path.PathSeparator.ToString(), paths);

// path should not be set to PythonEngine.PythonPath here.
// PythonEngine.PythonPath gets the default module search path, not the full search path.
// The list sys.path is initialized with this value on interpreter startup;
// it can be (and usually is) modified later to change the search path for loading modules.
// See https://docs.python.org/3/c-api/init.html#c.Py_GetPath
// After PythonPath is set, then PythonEngine.PythonPath will correctly return the full search path.

PythonEngine.Shutdown();

PythonEngine.PythonPath = path;
PythonEngine.Initialize();

Assert.AreEqual(path, PythonEngine.PythonPath);
if (importShouldSucceed) Py.Import(moduleName);

PythonEngine.Shutdown();
}
}
}
Loading