| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent dfeb354 commit 53836de
30 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,10 +14,6 @@ jobs: | |||
| 14 | 14 | os: [windows, ubuntu, macos] | |
| 15 | 15 | python: ["3.6", "3.7", "3.8", "3.9", "3.10"] | |
| 16 | 16 | platform: [x64] | |
| 17 | - shutdown_mode: [Normal, Soft] | ||
| 18 | - | ||
| 19 | - env: | ||
| 20 | - PYTHONNET_SHUTDOWN_MODE: ${{ matrix.SHUTDOWN_MODE }} | ||
| 21 | 17 | ||
| 22 | 18 | steps: | |
| 23 | 19 | - name: Set Environment on macOS | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -107,6 +107,8 @@ Instead, `PyIterable` does that. | |||
| 107 | 107 | ||
| 108 | 108 | ### Removed | |
| 109 | 109 | ||
| 110 | + - `ShutdownMode` has been removed. The only shutdown mode supported now is an equivalent of `ShutdownMode.Reload`. | ||
| 111 | + There is no need to specify it. | ||
| 110 | 112 | - implicit assembly loading (you have to explicitly `clr.AddReference` before doing import) | |
| 111 | 113 | - messages in `PythonException` no longer start with exception type | |
| 112 | 114 | - `PyScopeManager`, `PyScopeException`, `PyScope` (use `PyModule` instead) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -34,7 +34,7 @@ static void TupleConversionsGeneric<T, TTuple>() | |||
| 34 | 34 | using (var scope = Py.CreateScope()) | |
| 35 | 35 | { | |
| 36 | 36 | void Accept(T value) => restored = value; | |
| 37 | - var accept = new Action<T>(Accept).ToPython(); | ||
| 37 | + using var accept = new Action<T>(Accept).ToPython(); | ||
| 38 | 38 | scope.Set(nameof(tuple), tuple); | |
| 39 | 39 | scope.Set(nameof(accept), accept); | |
| 40 | 40 | scope.Exec($"{nameof(accept)}({nameof(tuple)})"); | |
@@ -55,7 +55,7 @@ static void TupleConversionsObject<T, TTuple>() | |||
| 55 | 55 | using (var scope = Py.CreateScope()) | |
| 56 | 56 | { | |
| 57 | 57 | void Accept(object value) => restored = (T)value; | |
| 58 | - var accept = new Action<object>(Accept).ToPython(); | ||
| 58 | + using var accept = new Action<object>(Accept).ToPython(); | ||
| 59 | 59 | scope.Set(nameof(tuple), tuple); | |
| 60 | 60 | scope.Set(nameof(accept), accept); | |
| 61 | 61 | scope.Exec($"{nameof(accept)}({nameof(tuple)})"); | |
@@ -71,7 +71,7 @@ public void TupleRoundtripObject() | |||
| 71 | 71 | static void TupleRoundtripObject<T, TTuple>() | |
| 72 | 72 | { | |
| 73 | 73 | var tuple = Activator.CreateInstance(typeof(T), 42.0, "42", new object()); | |
| 74 | - var pyTuple = TupleCodec<TTuple>.Instance.TryEncode(tuple); | ||
| 74 | + using var pyTuple = TupleCodec<TTuple>.Instance.TryEncode(tuple); | ||
| 75 | 75 | Assert.IsTrue(TupleCodec<TTuple>.Instance.TryDecode(pyTuple, out object restored)); | |
| 76 | 76 | Assert.AreEqual(expected: tuple, actual: restored); | |
| 77 | 77 | } | |
@@ -85,7 +85,7 @@ public void TupleRoundtripGeneric() | |||
| 85 | 85 | static void TupleRoundtripGeneric<T, TTuple>() | |
| 86 | 86 | { | |
| 87 | 87 | var tuple = Activator.CreateInstance(typeof(T), 42, "42", new object()); | |
| 88 | - var pyTuple = TupleCodec<TTuple>.Instance.TryEncode(tuple); | ||
| 88 | + using var pyTuple = TupleCodec<TTuple>.Instance.TryEncode(tuple); | ||
| 89 | 89 | Assert.IsTrue(TupleCodec<TTuple>.Instance.TryDecode(pyTuple, out T restored)); | |
| 90 | 90 | Assert.AreEqual(expected: tuple, actual: restored); | |
| 91 | 91 | } | |
@@ -98,9 +98,9 @@ public void ListDecoderTest() | |||
| 98 | 98 | var codec = ListDecoder.Instance; | |
| 99 | 99 | var items = new List<PyObject>() { new PyInt(1), new PyInt(2), new PyInt(3) }; | |
| 100 | 100 | ||
| 101 | - var pyList = new PyList(items.ToArray()); | ||
| 101 | + using var pyList = new PyList(items.ToArray()); | ||
| 102 | 102 | ||
| 103 | - var pyListType = pyList.GetPythonType(); | ||
| 103 | + using var pyListType = pyList.GetPythonType(); | ||
| 104 | 104 | Assert.IsTrue(codec.CanDecode(pyListType, typeof(IList<bool>))); | |
| 105 | 105 | Assert.IsTrue(codec.CanDecode(pyListType, typeof(IList<int>))); | |
| 106 | 106 | Assert.IsFalse(codec.CanDecode(pyListType, typeof(System.Collections.IEnumerable))); | |
@@ -128,8 +128,8 @@ public void ListDecoderTest() | |||
| 128 | 128 | Assert.Throws(typeof(InvalidCastException), () => { var x = stringList[0]; }); | |
| 129 | 129 | ||
| 130 | 130 | //can't convert python iterable to list (this will require a copy which isn't lossless) | |
| 131 | - var foo = GetPythonIterable(); | ||
| 132 | - var fooType = foo.GetPythonType(); | ||
| 131 | + using var foo = GetPythonIterable(); | ||
| 132 | + using var fooType = foo.GetPythonType(); | ||
| 133 | 133 | Assert.IsFalse(codec.CanDecode(fooType, typeof(IList<int>))); | |
| 134 | 134 | } | |
| 135 | 135 | ||
@@ -140,8 +140,8 @@ public void SequenceDecoderTest() | |||
| 140 | 140 | var items = new List<PyObject>() { new PyInt(1), new PyInt(2), new PyInt(3) }; | |
| 141 | 141 | ||
| 142 | 142 | //SequenceConverter can only convert to any ICollection | |
| 143 | - var pyList = new PyList(items.ToArray()); | ||
| 144 | - var listType = pyList.GetPythonType(); | ||
| 143 | + using var pyList = new PyList(items.ToArray()); | ||
| 144 | + using var listType = pyList.GetPythonType(); | ||
| 145 | 145 | //it can convert a PyList, since PyList satisfies the python sequence protocol | |
| 146 | 146 | ||
| 147 | 147 | Assert.IsFalse(codec.CanDecode(listType, typeof(bool))); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,8 +4,6 @@ | |||
| 4 | 4 | using Python.Runtime; | |
| 5 | 5 | ||
| 6 | 6 | namespace Python.EmbeddingTest { | |
| 7 | - using Runtime = Python.Runtime.Runtime; | ||
| 8 | - | ||
| 9 | 7 | public class TestCallbacks { | |
| 10 | 8 | [OneTimeSetUp] | |
| 11 | 9 | public void SetUp() { | |
@@ -22,11 +20,13 @@ public void TestNoOverloadException() { | |||
| 22 | 20 | int passed = 0; | |
| 23 | 21 | var aFunctionThatCallsIntoPython = new Action<int>(value => passed = value); | |
| 24 | 22 | using (Py.GIL()) { | |
| 25 | - dynamic callWith42 = PythonEngine.Eval("lambda f: f([42])"); | ||
| 26 | - var error = Assert.Throws<PythonException>(() => callWith42(aFunctionThatCallsIntoPython.ToPython())); | ||
| 23 | + using dynamic callWith42 = PythonEngine.Eval("lambda f: f([42])"); | ||
| 24 | + using var pyFunc = aFunctionThatCallsIntoPython.ToPython(); | ||
| 25 | + var error = Assert.Throws<PythonException>(() => callWith42(pyFunc)); | ||
| 27 | 26 | Assert.AreEqual("TypeError", error.Type.Name); | |
| 28 | 27 | string expectedArgTypes = "(<class 'list'>)"; | |
| 29 | 28 | StringAssert.EndsWith(expectedArgTypes, error.Message); | |
| 29 | + error.Traceback.Dispose(); | ||
| 30 | 30 | } | |
| 31 | 31 | } | |
| 32 | 32 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -67,14 +67,6 @@ public static void DomainReloadAndGC() | |||
| 67 | 67 | RunAssemblyAndUnload("test2"); | |
| 68 | 68 | Assert.That(PyRuntime.Py_IsInitialized() != 0, | |
| 69 | 69 | "On soft-shutdown mode, Python runtime should still running"); | |
| 70 | - | ||
| 71 | - if (PythonEngine.DefaultShutdownMode == ShutdownMode.Normal) | ||
| 72 | - { | ||
| 73 | - // The default mode is a normal mode, | ||
| 74 | - // it should shutdown the Python VM avoiding influence other tests. | ||
| 75 | - PyRuntime.PyGILState_Ensure(); | ||
| 76 | - PyRuntime.Py_Finalize(); | ||
| 77 | - } | ||
| 78 | 70 | } | |
| 79 | 71 | ||
| 80 | 72 | #region CrossDomainObject | |
@@ -222,7 +214,7 @@ static void RunAssemblyAndUnload(string domainName) | |||
| 222 | 214 | // assembly (and Python .NET) to reside | |
| 223 | 215 | var theProxy = CreateInstanceInstanceAndUnwrap<Proxy>(domain); | |
| 224 | 216 | ||
| 225 | - theProxy.Call(nameof(PythonRunner.InitPython), ShutdownMode.Soft, PyRuntime.PythonDLL); | ||
| 217 | + theProxy.Call(nameof(PythonRunner.InitPython), PyRuntime.PythonDLL); | ||
| 226 | 218 | // From now on use the Proxy to call into the new assembly | |
| 227 | 219 | theProxy.RunPython(); | |
| 228 | 220 | ||
@@ -290,7 +282,7 @@ static void RunDomainReloadSteps<T1, T2>() where T1 : CrossCaller where T2 : Cro | |||
| 290 | 282 | try | |
| 291 | 283 | { | |
| 292 | 284 | var theProxy = CreateInstanceInstanceAndUnwrap<Proxy>(domain); | |
| 293 | - theProxy.Call(nameof(PythonRunner.InitPython), ShutdownMode.Reload, PyRuntime.PythonDLL); | ||
| 285 | + theProxy.Call(nameof(PythonRunner.InitPython), PyRuntime.PythonDLL); | ||
| 294 | 286 | ||
| 295 | 287 | var caller = CreateInstanceInstanceAndUnwrap<T1>(domain); | |
| 296 | 288 | arg = caller.Execute(arg); | |
@@ -308,7 +300,7 @@ static void RunDomainReloadSteps<T1, T2>() where T1 : CrossCaller where T2 : Cro | |||
| 308 | 300 | try | |
| 309 | 301 | { | |
| 310 | 302 | var theProxy = CreateInstanceInstanceAndUnwrap<Proxy>(domain); | |
| 311 | - theProxy.Call(nameof(PythonRunner.InitPython), ShutdownMode.Reload, PyRuntime.PythonDLL); | ||
| 303 | + theProxy.Call(nameof(PythonRunner.InitPython), PyRuntime.PythonDLL); | ||
| 312 | 304 | ||
| 313 | 305 | var caller = CreateInstanceInstanceAndUnwrap<T2>(domain); | |
| 314 | 306 | caller.Execute(arg); | |
@@ -319,10 +311,8 @@ static void RunDomainReloadSteps<T1, T2>() where T1 : CrossCaller where T2 : Cro | |||
| 319 | 311 | AppDomain.Unload(domain); | |
| 320 | 312 | } | |
| 321 | 313 | } | |
| 322 | - if (PythonEngine.DefaultShutdownMode == ShutdownMode.Normal) | ||
| 323 | - { | ||
| 324 | - Assert.IsTrue(PyRuntime.Py_IsInitialized() == 0); | ||
| 325 | - } | ||
| 314 | + | ||
| 315 | + Assert.IsTrue(PyRuntime.Py_IsInitialized() != 0); | ||
| 326 | 316 | } | |
| 327 | 317 | } | |
| 328 | 318 | ||
@@ -368,10 +358,10 @@ public static void RunPython() | |||
| 368 | 358 | ||
| 369 | 359 | private static IntPtr _state; | |
| 370 | 360 | ||
| 371 | - public static void InitPython(ShutdownMode mode, string dllName) | ||
| 361 | + public static void InitPython(string dllName) | ||
| 372 | 362 | { | |
| 373 | 363 | PyRuntime.PythonDLL = dllName; | |
| 374 | - PythonEngine.Initialize(mode: mode); | ||
| 364 | + PythonEngine.Initialize(); | ||
| 375 | 365 | _state = PythonEngine.BeginAllowThreads(); | |
| 376 | 366 | } | |
| 377 | 367 | ||
@@ -384,15 +374,7 @@ public static void ShutdownPython() | |||
| 384 | 374 | public static void ShutdownPythonCompletely() | |
| 385 | 375 | { | |
| 386 | 376 | PythonEngine.EndAllowThreads(_state); | |
| 387 | - // XXX: Reload mode will reserve clr objects after `Runtime.Shutdown`, | ||
| 388 | - // if it used a another mode(the default mode) in other tests, | ||
| 389 | - // when other tests trying to access these reserved objects, it may cause Domain exception, | ||
| 390 | - // thus it needs to reduct to Soft mode to make sure all clr objects remove from Python. | ||
| 391 | - var defaultMode = PythonEngine.DefaultShutdownMode; | ||
| 392 | - if (defaultMode != ShutdownMode.Reload) | ||
| 393 | - { | ||
| 394 | - PythonEngine.ShutdownMode = defaultMode; | ||
| 395 | - } | ||
| 377 | + | ||
| 396 | 378 | PythonEngine.Shutdown(); | |
| 397 | 379 | } | |
| 398 | 380 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -151,51 +151,6 @@ public void ShutdownHandlers() | |||
| 151 | 151 | // Wrong: (4 * 2) + 1 + 1 + 1 = 11 | |
| 152 | 152 | Assert.That(shutdown_count, Is.EqualTo(12)); | |
| 153 | 153 | } | |
| 154 | - | ||
| 155 | - [Test] | ||
| 156 | - public static void TestRunExitFuncs() | ||
| 157 | - { | ||
| 158 | - if (Runtime.Runtime.GetDefaultShutdownMode() == ShutdownMode.Normal) | ||
| 159 | - { | ||
| 160 | - // If the runtime using the normal mode, | ||
| 161 | - // callback registered by atexit will be called after we release the clr information, | ||
| 162 | - // thus there's no chance we can check it here. | ||
| 163 | - Assert.Ignore("Skip on normal mode"); | ||
| 164 | - } | ||
| 165 | - Runtime.Runtime.Initialize(); | ||
| 166 | - PyObject atexit; | ||
| 167 | - try | ||
| 168 | - { | ||
| 169 | - atexit = Py.Import("atexit"); | ||
| 170 | - } | ||
| 171 | - catch (PythonException e) | ||
| 172 | - { | ||
| 173 | - string msg = e.ToString(); | ||
| 174 | - bool isImportError = e.Is(Exceptions.ImportError); | ||
| 175 | - Runtime.Runtime.Shutdown(); | ||
| 176 | - | ||
| 177 | - if (isImportError) | ||
| 178 | - { | ||
| 179 | - Assert.Ignore("no atexit module"); | ||
| 180 | - } | ||
| 181 | - else | ||
| 182 | - { | ||
| 183 | - Assert.Fail(msg); | ||
| 184 | - } | ||
| 185 | - PythonEngine.InteropConfiguration = InteropConfiguration.MakeDefault(); | ||
| 186 | - return; | ||
| 187 | - } | ||
| 188 | - bool called = false; | ||
| 189 | - Action callback = () => | ||
| 190 | - { | ||
| 191 | - called = true; | ||
| 192 | - }; | ||
| 193 | - atexit.InvokeMethod("register", callback.ToPython()).Dispose(); | ||
| 194 | - atexit.Dispose(); | ||
| 195 | - Runtime.Runtime.Shutdown(); | ||
| 196 | - Assert.True(called); | ||
| 197 | - PythonEngine.InteropConfiguration = InteropConfiguration.MakeDefault(); | ||
| 198 | - } | ||
| 199 | 154 | } | |
| 200 | 155 | ||
| 201 | 156 | public class ImportClassShutdownRefcountClass { } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,4 +1,5 @@ | |||
| 1 | 1 | using System; | |
| 2 | + using System.Collections.Generic; | ||
| 2 | 3 | using System.Diagnostics; | |
| 3 | 4 | using System.Runtime.Serialization; | |
| 4 | 5 | ||
@@ -49,9 +50,9 @@ public static ReflectedClrType GetOrCreate(Type type) | |||
| 49 | 50 | return pyType; | |
| 50 | 51 | } | |
| 51 | 52 | ||
| 52 | - internal void Restore(InterDomainContext context) | ||
| 53 | + internal void Restore(Dictionary<string, object?> context) | ||
| 53 | 54 | { | |
| 54 | - var cb = context.Storage.GetValue<ClassBase>("impl"); | ||
| 55 | + var cb = (ClassBase)context["impl"]!; | ||
| 55 | 56 | ||
| 56 | 57 | Debug.Assert(cb is not null); | |
| 57 | 58 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,6 @@ namespace Python.Runtime.StateSerialization; | |||
| 10 | 10 | [Serializable] | |
| 11 | 11 | internal class ClassManagerState | |
| 12 | 12 | { | |
| 13 | - public Dictionary<ReflectedClrType, InterDomainContext> Contexts { get; set; } | ||
| 13 | + public Dictionary<ReflectedClrType, Dictionary<string, object?>> Contexts { get; set; } | ||
| 14 | 14 | public Dictionary<MaybeType, ReflectedClrType> Cache { get; set; } | |
| 15 | 15 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,6 +4,6 @@ namespace Python.Runtime; | |||
| 4 | 4 | ||
| 5 | 5 | public interface ICLRObjectStorer | |
| 6 | 6 | { | |
| 7 | - ICollection<CLRMappedItem> Store(CLRWrapperCollection wrappers, RuntimeDataStorage storage); | ||
| 8 | - CLRWrapperCollection Restore(RuntimeDataStorage storage); | ||
| 7 | + ICollection<CLRMappedItem> Store(CLRWrapperCollection wrappers, Dictionary<string, object?> storage); | ||
| 8 | + CLRWrapperCollection Restore(Dictionary<string, object?> storage); | ||
| 9 | 9 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,6 @@ internal class SharedObjectsState | |||
| 12 | 12 | { | |
| 13 | 13 | public Dictionary<PyObject, CLRObject> InternalStores { get; init; } | |
| 14 | 14 | public Dictionary<PyObject, ExtensionType> Extensions { get; init; } | |
| 15 | - public RuntimeDataStorage Wrappers { get; init; } | ||
| 16 | - public Dictionary<PyObject, InterDomainContext> Contexts { get; init; } | ||
| 15 | + public Dictionary<string, object?> Wrappers { get; init; } | ||
| 16 | + public Dictionary<PyObject, Dictionary<string, object?>> Contexts { get; init; } | ||
| 17 | 17 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments