Skip to content

On shutdown from Python release all slot holders #1720

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
wants to merge 7 commits into from
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
6 changes: 3 additions & 3 deletions pythonnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ 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
Expand All @@ -51,7 +51,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:
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/AssemblyManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ internal class AssemblyManager
// than it can end up referring to assemblies that are already unloaded (default behavior after unload appDomain -
// unless LoaderOptimization.MultiDomain is used);
// So for multidomain support it is better to have the dict. recreated for each app-domain initialization
private static ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>> namespaces =
new ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>>();
private static readonly ConcurrentDictionary<string, ConcurrentDictionary<Assembly, string>> namespaces =
new();

#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
// domain-level handlers are initialized in Initialize
Expand All @@ -33,7 +33,7 @@ internal class AssemblyManager
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

// updated only under GIL?
private static Dictionary<string, int> probed = new Dictionary<string, int>(32);
private static readonly Dictionary<string, int> probed = new(32);

// modified from event handlers below, potentially triggered from different .NET threads
private static readonly ConcurrentQueue<Assembly> assemblies = new();
Expand Down
3 changes: 1 addition & 2 deletions src/runtime/ClassManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,9 @@ internal static void InitClassBase(Type type, ClassBase impl, ReflectedClrType p
Runtime.PyDict_SetItem(dict, PyIdentifier.__doc__, doc.Borrow());
}

var co = impl as ClassObject;
// If this is a ClassObject AND it has constructors, generate a __doc__ attribute.
// required that the ClassObject.ctors be changed to internal
if (co != null)
if (impl is ClassObject co)
{
if (co.NumCtors > 0 && !co.HasCustomNew())
{
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/Codecs/DecoderGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Python.Runtime.Codecs
/// </summary>
public sealed class DecoderGroup: IPyObjectDecoder, IEnumerable<IPyObjectDecoder>, IDisposable
{
readonly List<IPyObjectDecoder> decoders = new List<IPyObjectDecoder>();
readonly List<IPyObjectDecoder> decoders = new();

/// <summary>
/// Add specified decoder to the group
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/Codecs/EncoderGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Python.Runtime.Codecs
/// </summary>
public sealed class EncoderGroup: IPyObjectEncoder, IEnumerable<IPyObjectEncoder>, IDisposable
{
readonly List<IPyObjectEncoder> encoders = new List<IPyObjectEncoder>();
readonly List<IPyObjectEncoder> encoders = new();

/// <summary>
/// Add specified encoder to the group
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/Codecs/PyObjectConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ namespace Python.Runtime
/// </summary>
public static class PyObjectConversions
{
static readonly DecoderGroup decoders = new DecoderGroup();
static readonly EncoderGroup encoders = new EncoderGroup();
static readonly DecoderGroup decoders = new();
static readonly EncoderGroup encoders = new();

/// <summary>
/// Registers specified encoder (marshaller)
Expand Down Expand Up @@ -62,7 +62,7 @@ public static void RegisterDecoder(IPyObjectDecoder decoder)
}

static readonly ConcurrentDictionary<Type, IPyObjectEncoder[]>
clrToPython = new ConcurrentDictionary<Type, IPyObjectEncoder[]>();
clrToPython = new();
static IPyObjectEncoder[] GetEncoders(Type type)
{
lock (encoders)
Expand Down
23 changes: 11 additions & 12 deletions src/runtime/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ private Converter()
{
}

private static Type objectType;
private static Type stringType;
private static Type singleType;
private static Type doubleType;
private static Type int16Type;
private static Type int32Type;
private static Type int64Type;
private static Type boolType;
private static Type typeType;
private static readonly Type objectType;
private static readonly Type stringType;
private static readonly Type singleType;
private static readonly Type doubleType;
private static readonly Type int16Type;
private static readonly Type int32Type;
private static readonly Type int64Type;
private static readonly Type boolType;
private static readonly Type typeType;

static Converter()
{
Expand Down Expand Up @@ -151,8 +151,7 @@ internal static NewReference ToPython(object? value, Type type)

// it the type is a python subclass of a managed type then return the
// underlying python object rather than construct a new wrapper object.
var pyderived = value as IPythonDerivedType;
if (null != pyderived)
if (value is IPythonDerivedType pyderived)
{
if (!IsTransparentProxy(pyderived))
return ClassDerivedObject.ToPython(pyderived);
Expand All @@ -161,7 +160,7 @@ internal static NewReference ToPython(object? value, Type type)
// ModuleObjects are created in a way that their wrapping them as
// a CLRObject fails, the ClassObject has no tpHandle. Return the
// pyHandle as is, do not convert.
if (value is ModuleObject modobj)
if (value is ModuleObject)
{
throw new NotImplementedException();
}
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/DelegateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ namespace Python.Runtime
/// </summary>
internal class DelegateManager
{
private readonly Dictionary<Type,Type> cache = new Dictionary<Type, Type>();
private readonly Dictionary<Type,Type> cache = new();
private readonly Type basetype = typeof(Dispatcher);
private readonly Type arrayType = typeof(object[]);
private readonly Type voidtype = typeof(void);
private readonly Type typetype = typeof(Type);
private readonly Type pyobjType = typeof(PyObject);
private readonly CodeGenerator codeGenerator = new CodeGenerator();
private readonly CodeGenerator codeGenerator = new();
private readonly ConstructorInfo arrayCtor;
private readonly MethodInfo dispatch;

Expand Down Expand Up @@ -309,7 +309,7 @@ protected Dispatcher(PyObject target, Type dtype)
{
tpName += $" of size {Runtime.PyTuple_Size(op)}";
}
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
if (!isVoid) sb.Append(rtype.FullName);
for (int i = 0; i < pi.Length; i++)
{
Expand Down
3 changes: 1 addition & 2 deletions src/runtime/Exceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ public static bool SetError(Exception e)
// might get a managed exception raised that is a wrapper for a
// Python exception. In that case we'd rather have the real thing.

var pe = e as PythonException;
if (pe != null)
if (e is PythonException pe)
{
pe.Restore();
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/Finalizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public ErrorArgs(Exception error)
[DefaultValue(true)]
public bool Enable { get; set; } = true;

private ConcurrentQueue<PendingFinalization> _objQueue = new();
private readonly ConcurrentQueue<PendingFinalization> _objQueue = new();
private readonly ConcurrentQueue<PendingFinalization> _derivedQueue = new();
private readonly ConcurrentQueue<Py_buffer> _bufferQueue = new();
private int _throttled;
Expand Down
3 changes: 1 addition & 2 deletions src/runtime/InternString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ public static void Shutdown()

public static string? GetManagedString(BorrowedReference op)
{
string s;
if (TryGetInterned(op, out s))
if (TryGetInterned(op, out string s))
{
return s;
}
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/Interop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ internal static Type GetPrototype(MethodInfo method)
}


internal static Dictionary<IntPtr, Delegate> allocatedThunks = new Dictionary<IntPtr, Delegate>();
internal static Dictionary<IntPtr, Delegate> allocatedThunks = new();

internal static ThunkInfo GetThunk(MethodInfo method)
{
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/InteropConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Python.Runtime
public sealed class InteropConfiguration: IDisposable
{
internal readonly PythonBaseTypeProviderGroup pythonBaseTypeProviders
= new PythonBaseTypeProviderGroup();
= new();

/// <summary>Enables replacing base types of CLR types as seen from Python</summary>
public IList<IPythonBaseTypeProvider> PythonBaseTypeProviders => this.pythonBaseTypeProviders;
Expand Down
25 changes: 4 additions & 21 deletions src/runtime/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,8 @@ public unsafe static int Initialize(IntPtr data, int size)
PythonDLL = null;
}

var gs = PyGILState_Ensure();

try
{
// Console.WriteLine("Startup thread");
PythonEngine.InitExt();
// Console.WriteLine("Startup finished");
}
finally
{
PyGILState_Release(gs);
}
using var _ = Py.GIL();
PythonEngine.InitExt();
}
catch (Exception exc)
{
Expand All @@ -55,15 +45,8 @@ public unsafe static int Shutdown(IntPtr data, int size)

if (command == "full_shutdown")
{
var gs = PyGILState_Ensure();
try
{
PythonEngine.Shutdown();
}
finally
{
PyGILState_Release(gs);
}
using var _ = Py.GIL();
PythonEngine.Shutdown();
}
}
catch (Exception exc)
Expand Down
Loading