diff --git a/pythonnet.sln b/pythonnet.sln
index 3b509518f..eb97cfbd0 100644
--- a/pythonnet.sln
+++ b/pythonnet.sln
@@ -25,6 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Repo", "Repo", "{441A0123-F
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CI", "CI", "{D301657F-5EAF-4534-B280-B858D651B2E5}"
ProjectSection(SolutionItems) = preProject
+ .github\workflows\ARM.yml = .github\workflows\ARM.yml
.github\workflows\main.yml = .github\workflows\main.yml
.github\workflows\nuget-preview.yml = .github\workflows\nuget-preview.yml
EndProjectSection
diff --git a/pythonnet/__init__.py b/pythonnet/__init__.py
index 7eec90f27..10dc403e4 100644
--- a/pythonnet/__init__.py
+++ b/pythonnet/__init__.py
@@ -16,7 +16,7 @@ def set_runtime(runtime):
def set_default_runtime() -> None:
- if sys.platform == 'win32':
+ if sys.platform == "win32":
set_runtime(clr_loader.get_netfx())
else:
set_runtime(clr_loader.get_mono())
@@ -36,14 +36,15 @@ def load():
set_default_runtime()
dll_path = join(dirname(__file__), "runtime", "Python.Runtime.dll")
-
+
_LOADER_ASSEMBLY = _RUNTIME.get_assembly(dll_path)
func = _LOADER_ASSEMBLY["Python.Runtime.Loader.Initialize"]
- if func(''.encode("utf8")) != 0:
+ if func(b"") != 0:
raise RuntimeError("Failed to initialize Python.Runtime.dll")
import atexit
+
atexit.register(unload)
@@ -51,7 +52,7 @@ def unload():
global _RUNTIME
if _LOADER_ASSEMBLY is not None:
func = _LOADER_ASSEMBLY["Python.Runtime.Loader.Shutdown"]
- if func(b"") != 0:
+ if func(b"full_shutdown") != 0:
raise RuntimeError("Failed to call Python.NET shutdown")
if _RUNTIME is not None:
diff --git a/src/runtime/Runtime.cs b/src/runtime/Runtime.cs
index e33c4624c..e358c0135 100644
--- a/src/runtime/Runtime.cs
+++ b/src/runtime/Runtime.cs
@@ -54,8 +54,9 @@ private static string GetDefaultDllName(Version version)
}
private static bool _isInitialized = false;
-
internal static bool IsInitialized => _isInitialized;
+ private static bool _typesInitialized = false;
+ internal static bool TypeManagerInitialized => _typesInitialized;
internal static readonly bool Is32Bit = IntPtr.Size == 4;
// .NET core: System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
@@ -151,6 +152,7 @@ internal static void Initialize(bool initSigs = false)
ClassManager.Reset();
ClassDerivedObject.Reset();
TypeManager.Initialize();
+ _typesInitialized = true;
// Initialize modules that depend on the runtime class.
AssemblyManager.Initialize();
@@ -272,6 +274,7 @@ internal static void Shutdown()
NullGCHandles(ExtensionType.loadedExtensions);
ClassManager.RemoveClasses();
TypeManager.RemoveTypes();
+ _typesInitialized = false;
MetaType.Release();
PyCLRMetaType.Dispose();
@@ -291,9 +294,10 @@ internal static void Shutdown()
Finalizer.Shutdown();
InternString.Shutdown();
+ ResetPyMembers();
+
if (!HostedInPython)
{
- ResetPyMembers();
GC.Collect();
GC.WaitForPendingFinalizers();
PyGILState_Release(state);
@@ -310,7 +314,6 @@ internal static void Shutdown()
}
else
{
- ResetPyMembers();
PyGILState_Release(state);
}
}
diff --git a/src/runtime/TypeManager.cs b/src/runtime/TypeManager.cs
index 6057ca830..84618df64 100644
--- a/src/runtime/TypeManager.cs
+++ b/src/runtime/TypeManager.cs
@@ -51,18 +51,21 @@ internal static void Initialize()
internal static void RemoveTypes()
{
- foreach (var type in cache.Values)
+ if (Runtime.HostedInPython)
{
- if (Runtime.HostedInPython
- && _slotsHolders.TryGetValue(type, out var holder))
+ foreach (var holder in _slotsHolders)
{
// If refcount > 1, it needs to reset the managed slot,
// otherwise it can dealloc without any trick.
- if (Runtime.Refcount(type) > 1)
+ if (holder.Key.Refcount > 1)
{
- holder.ResetSlots();
+ holder.Value.ResetSlots();
}
}
+ }
+
+ foreach (var type in cache.Values)
+ {
type.Dispose();
}
cache.Clear();
@@ -507,7 +510,7 @@ internal static PyType CreateMetaType(Type impl, out SlotsHolder slotsHolder)
{
throw PythonException.ThrowLastAsClrException();
}
-
+
BorrowedReference dict = Util.ReadRef(type, TypeOffset.tp_dict);
using (var mod = Runtime.PyString_FromString("clr._internal"))
Runtime.PyDict_SetItemString(dict, "__module__", mod.Borrow());
@@ -726,6 +729,7 @@ internal static void CopySlot(BorrowedReference from, BorrowedReference to, int
internal static SlotsHolder CreateSlotsHolder(PyType type)
{
+ type = new PyType(type);
var holder = new SlotsHolder(type);
_slotsHolders.Add(type, holder);
return holder;
@@ -828,6 +832,7 @@ public void ResetSlots()
var metatype = Runtime.PyObject_TYPE(Type);
ManagedType.TryFreeGCHandle(Type, metatype);
}
+ Runtime.PyType_Modified(Type);
}
public static IntPtr GetDefaultSlot(int offset)
diff --git a/src/runtime/Types/ClassDerived.cs b/src/runtime/Types/ClassDerived.cs
index da1bf0f9a..6c2c81b13 100644
--- a/src/runtime/Types/ClassDerived.cs
+++ b/src/runtime/Types/ClassDerived.cs
@@ -59,10 +59,7 @@ protected override NewReference NewObjectToPython(object obj, BorrowedReference
// Decrement the python object's reference count.
// This doesn't actually destroy the object, it just sets the reference to this object
// to be a weak reference and it will be destroyed when the C# object is destroyed.
- if (!self.IsNull())
- {
- Runtime.XDecref(self.Steal());
- }
+ Runtime.XDecref(self.Steal());
return Converter.ToPython(obj, type.Value);
}
@@ -942,13 +939,16 @@ internal static void Finalize(IntPtr derived)
var type = Runtime.PyObject_TYPE(@ref.Borrow());
- // rare case when it's needed
- // matches correspdonging PyObject_GC_UnTrack
- // in ClassDerivedObject.tp_dealloc
- Runtime.PyObject_GC_Del(@ref.Steal());
+ if (!Runtime.HostedInPython || Runtime.TypeManagerInitialized)
+ {
+ // rare case when it's needed
+ // matches correspdonging PyObject_GC_UnTrack
+ // in ClassDerivedObject.tp_dealloc
+ Runtime.PyObject_GC_Del(@ref.Steal());
- // must decref our type
- Runtime.XDecref(StolenReference.DangerousFromPointer(type.DangerousGetAddress()));
+ // must decref our type
+ Runtime.XDecref(StolenReference.DangerousFromPointer(type.DangerousGetAddress()));
+ }
}
internal static FieldInfo? GetPyObjField(Type type) => type.GetField(PyObjName, PyObjFlags);
diff --git a/src/runtime/Types/ModuleObject.cs b/src/runtime/Types/ModuleObject.cs
index 1e86d4472..1cc9f04b2 100644
--- a/src/runtime/Types/ModuleObject.cs
+++ b/src/runtime/Types/ModuleObject.cs
@@ -542,7 +542,6 @@ public static Assembly AddReference(string name)
///
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: