X Tutup
using System; using NUnit.Framework; using Python.Runtime; namespace Python.EmbeddingTest { public class PyInitializeTest { /// /// Tests issue with multiple simple Initialize/Shutdowns. /// Fixed by #343 /// [Test] public static void StartAndStopTwice() { PythonEngine.Initialize(); PythonEngine.Shutdown(); PythonEngine.Initialize(); PythonEngine.Shutdown(); } [Test] public static void LoadDefaultArgs() { using (new PythonEngine()) { using(var argv = new PyList(Runtime.Runtime.PySys_GetObject("argv"))) { Assert.AreNotEqual(0, argv.Length()); } } } [Test] public static void LoadSpecificArgs() { var args = new[] { "test1", "test2" }; using (new PythonEngine(args)) { using (var argv = new PyList(Runtime.Runtime.PySys_GetObject("argv"))) { using var v0 = argv[0]; using var v1 = argv[1]; Assert.AreEqual(args[0], v0.ToString()); Assert.AreEqual(args[1], v1.ToString()); } } } // regression test for https://github.com/pythonnet/pythonnet/issues/1561 [Test] public void ImportClassShutdownRefcount() { PythonEngine.Initialize(); PyObject ns = Py.Import(typeof(ImportClassShutdownRefcountClass).Namespace); PyObject cls = ns.GetAttr(nameof(ImportClassShutdownRefcountClass)); BorrowedReference clsRef = cls.Reference; #pragma warning disable CS0618 // Type or member is obsolete cls.Leak(); #pragma warning restore CS0618 // Type or member is obsolete ns.Dispose(); Assert.Less(Runtime.Runtime.Refcount32(clsRef), 256); PythonEngine.Shutdown(); Assert.Greater(Runtime.Runtime.Refcount32(clsRef), 0); } /// /// Failing test demonstrating current issue with OverflowException (#376) /// and ArgumentException issue after that one is fixed. /// More complex version of StartAndStopTwice test /// [Test] [Ignore("GH#376: System.OverflowException : Arithmetic operation resulted in an overflow")] //[Ignore("System.ArgumentException : Cannot pass a GCHandle across AppDomains")] public void ReInitialize() { var code = "from System import Int32\n"; PythonEngine.Initialize(); using (Py.GIL()) { // Import any class or struct from .NET PythonEngine.RunSimpleString(code); } PythonEngine.Shutdown(); PythonEngine.Initialize(); using (Py.GIL()) { // Import a class/struct from .NET // This class/struct must be imported during the first initialization. PythonEngine.RunSimpleString(code); // Create an instance of the class/struct // System.OverflowException Exception will be raised here. // If replacing int with Int64, OverflowException will be replaced with AppDomain exception. PythonEngine.RunSimpleString("Int32(1)"); } PythonEngine.Shutdown(); } /// /// Helper for testing the shutdown handlers. /// int shutdown_count = 0; void OnShutdownIncrement() { shutdown_count++; } void OnShutdownDouble() { shutdown_count *= 2; } /// /// Test the shutdown handlers. /// [Test] public void ShutdownHandlers() { // Test we can run one shutdown handler. shutdown_count = 0; PythonEngine.Initialize(); PythonEngine.AddShutdownHandler(OnShutdownIncrement); PythonEngine.Shutdown(); Assert.That(shutdown_count, Is.EqualTo(1)); // Test we can run multiple shutdown handlers in the right order. shutdown_count = 4; PythonEngine.Initialize(); PythonEngine.AddShutdownHandler(OnShutdownIncrement); PythonEngine.AddShutdownHandler(OnShutdownDouble); PythonEngine.Shutdown(); // Correct: 4 * 2 + 1 = 9 // Wrong: (4 + 1) * 2 = 10 Assert.That(shutdown_count, Is.EqualTo(9)); // Test we can remove shutdown handlers, handling duplicates. shutdown_count = 4; PythonEngine.Initialize(); PythonEngine.AddShutdownHandler(OnShutdownIncrement); PythonEngine.AddShutdownHandler(OnShutdownIncrement); PythonEngine.AddShutdownHandler(OnShutdownDouble); PythonEngine.AddShutdownHandler(OnShutdownIncrement); PythonEngine.AddShutdownHandler(OnShutdownDouble); PythonEngine.RemoveShutdownHandler(OnShutdownDouble); PythonEngine.Shutdown(); // Correct: (4 + 1) * 2 + 1 + 1 = 12 // Wrong: (4 * 2) + 1 + 1 + 1 = 11 Assert.That(shutdown_count, Is.EqualTo(12)); } } public class ImportClassShutdownRefcountClass { } }
X Tutup