diff --git a/src/runtime/Util.cs b/src/runtime/Util.cs index eb21cddbb..c70f5cf51 100644 --- a/src/runtime/Util.cs +++ b/src/runtime/Util.cs @@ -7,6 +7,8 @@ internal static class Util { internal const string UnstableApiMessage = "This API is unstable, and might be changed or removed in the next minor release"; + internal const string MinimalPythonVersionRequired = + "Only Python 3.5 or newer is supported"; internal static Int64 ReadCLong(IntPtr tp, int offset) { diff --git a/src/runtime/clrobject.cs b/src/runtime/clrobject.cs index 02f7baf65..07b816e05 100644 --- a/src/runtime/clrobject.cs +++ b/src/runtime/clrobject.cs @@ -5,6 +5,7 @@ namespace Python.Runtime { [Serializable] + [DebuggerDisplay("clrO: {inst}")] internal class CLRObject : ManagedType { internal object inst; diff --git a/src/runtime/debughelper.cs b/src/runtime/debughelper.cs index 5e854bffd..25d32af5b 100644 --- a/src/runtime/debughelper.cs +++ b/src/runtime/debughelper.cs @@ -144,5 +144,13 @@ public static void AssertHasReferences(IntPtr obj) long refcount = Runtime.Refcount(obj); Debug.Assert(refcount > 0, "Object refcount is 0 or less"); } + + [Conditional("DEBUG")] + public static void EnsureGIL() + { + Debug.Assert(HaveInterpreterLock(), "GIL must be acquired"); + } + + public static bool HaveInterpreterLock() => Runtime.PyGILState_Check() == 1; } } diff --git a/src/runtime/pyobject.cs b/src/runtime/pyobject.cs index dea12ba1b..55e76019b 100644 --- a/src/runtime/pyobject.cs +++ b/src/runtime/pyobject.cs @@ -16,6 +16,7 @@ namespace Python.Runtime /// for details. /// [Serializable] + [DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")] public partial class PyObject : DynamicObject, IEnumerable, IDisposable { #if TRACE_ALLOC @@ -1069,6 +1070,10 @@ public override string ToString() return result; } + string DebuggerDisplay => DebugUtil.HaveInterpreterLock() + ? this.ToString() + : $"pyobj at 0x{this.obj:X} (get Py.GIL to see more info)"; + /// /// Equals Method diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 009412ea5..43ee08716 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -832,7 +832,7 @@ internal static unsafe long Refcount(IntPtr op) internal static IntPtr PyThreadState_Swap(IntPtr key) => Delegates.PyThreadState_Swap(key); - + internal static int PyGILState_Check() => Delegates.PyGILState_Check(); internal static IntPtr PyGILState_Ensure() => Delegates.PyGILState_Ensure(); @@ -2302,6 +2302,14 @@ static Delegates() PyThread_get_thread_ident = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyThread_get_thread_ident), GetUnmanagedDll(_PythonDll)); PyThread_set_key_value = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyThread_set_key_value), GetUnmanagedDll(_PythonDll)); PyThreadState_Swap = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyThreadState_Swap), GetUnmanagedDll(_PythonDll)); + try + { + PyGILState_Check = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_Check), GetUnmanagedDll(_PythonDll)); + } + catch (MissingMethodException e) + { + throw new NotSupportedException(Util.MinimalPythonVersionRequired, innerException: e); + } PyGILState_Ensure = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_Ensure), GetUnmanagedDll(_PythonDll)); PyGILState_Release = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_Release), GetUnmanagedDll(_PythonDll)); PyGILState_GetThisThreadState = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyGILState_GetThisThreadState), GetUnmanagedDll(_PythonDll)); @@ -2605,6 +2613,7 @@ static Delegates() internal static delegate* unmanaged[Cdecl] PyThread_get_thread_ident { get; } internal static delegate* unmanaged[Cdecl] PyThread_set_key_value { get; } internal static delegate* unmanaged[Cdecl] PyThreadState_Swap { get; } + internal static delegate* unmanaged[Cdecl] PyGILState_Check { get; } internal static delegate* unmanaged[Cdecl] PyGILState_Ensure { get; } internal static delegate* unmanaged[Cdecl] PyGILState_Release { get; } internal static delegate* unmanaged[Cdecl] PyGILState_GetThisThreadState { get; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

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:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy