diff --git a/src/embed_tests/TestRuntime.cs b/src/embed_tests/TestRuntime.cs index 32369190c..4e05850c1 100644 --- a/src/embed_tests/TestRuntime.cs +++ b/src/embed_tests/TestRuntime.cs @@ -92,27 +92,29 @@ public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test() { Runtime.Runtime.Py_Initialize(); - // Create an instance of threading.Lock, which is one of the very few types that does not have the - // TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check. - var threading = Runtime.Runtime.PyImport_ImportModule("threading"); - Exceptions.ErrorCheck(threading); - var threadingDict = Runtime.Runtime.PyModule_GetDict(threading); - Exceptions.ErrorCheck(threadingDict); - var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock"); - if (lockType.IsNull) - throw new KeyNotFoundException("class 'Lock' was not found in 'threading'"); - - var args = Runtime.Runtime.PyTuple_New(0); - var lockInstance = Runtime.Runtime.PyObject_CallObject(lockType.DangerousGetAddress(), args); - Runtime.Runtime.XDecref(args); - Exceptions.ErrorCheck(lockInstance); - - Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance)); - Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance)); - - threading.Dispose(); - - Runtime.Runtime.Py_Finalize(); + try + { + // Create an instance of threading.Lock, which is one of the very few types that does not have the + // TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check. + using var threading = Runtime.Runtime.PyImport_ImportModule("threading"); + Exceptions.ErrorCheck(threading); + var threadingDict = Runtime.Runtime.PyModule_GetDict(threading); + Exceptions.ErrorCheck(threadingDict); + var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock"); + if (lockType.IsNull) + throw new PythonException(); + + using var args = NewReference.DangerousFromPointer(Runtime.Runtime.PyTuple_New(0)); + using var lockInstance = Runtime.Runtime.PyObject_CallObject(lockType, args); + Exceptions.ErrorCheck(lockInstance); + + Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance)); + Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance)); + } + finally + { + Runtime.Runtime.Py_Finalize(); + } } } } diff --git a/src/runtime/runtime.cs b/src/runtime/runtime.cs index 6ebf885a0..232dd8708 100644 --- a/src/runtime/runtime.cs +++ b/src/runtime/runtime.cs @@ -1009,6 +1009,11 @@ internal static string PyObject_GetTypeName(IntPtr op) return Marshal.PtrToStringAnsi(ppName); } + /// + /// Test whether the Python object is an iterable. + /// + internal static bool PyObject_IsIterable(BorrowedReference ob) + => PyObject_IsIterable(ob.DangerousGetAddress()); /// /// Test whether the Python object is an iterable. /// @@ -1078,7 +1083,10 @@ internal static IntPtr PyObject_GetAttr(IntPtr pointer, IntPtr name) internal static IntPtr PyObject_Call(IntPtr pointer, IntPtr args, IntPtr kw) => Delegates.PyObject_Call(pointer, args, kw); - internal static IntPtr PyObject_CallObject(IntPtr pointer, IntPtr args) => Delegates.PyObject_CallObject(pointer, args); + internal static NewReference PyObject_CallObject(BorrowedReference callable, BorrowedReference args) => Delegates.PyObject_CallObject(callable, args); + internal static IntPtr PyObject_CallObject(IntPtr pointer, IntPtr args) + => Delegates.PyObject_CallObject(new BorrowedReference(pointer), new BorrowedReference(args)) + .DangerousMoveToPointerOrNull(); internal static int PyObject_RichCompareBool(IntPtr value1, IntPtr value2, int opid) => Delegates.PyObject_RichCompareBool(value1, value2, opid); @@ -1880,6 +1888,7 @@ internal static IntPtr PyTuple_GetSlice(IntPtr pointer, long start, long end) //==================================================================== // Python iterator API //==================================================================== + internal static bool PyIter_Check(BorrowedReference ob) => PyIter_Check(ob.DangerousGetAddress()); internal static bool PyIter_Check(IntPtr pointer) { @@ -2317,7 +2326,7 @@ static Delegates() PyObject_DelItem = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_DelItem), GetUnmanagedDll(_PythonDll)); PyObject_GetIter = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_GetIter), GetUnmanagedDll(_PythonDll)); PyObject_Call = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_Call), GetUnmanagedDll(_PythonDll)); - PyObject_CallObject = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_CallObject), GetUnmanagedDll(_PythonDll)); + PyObject_CallObject = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_CallObject), GetUnmanagedDll(_PythonDll)); PyObject_RichCompareBool = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_RichCompareBool), GetUnmanagedDll(_PythonDll)); PyObject_IsInstance = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_IsInstance), GetUnmanagedDll(_PythonDll)); PyObject_IsSubclass = (delegate* unmanaged[Cdecl])GetFunctionByName(nameof(PyObject_IsSubclass), GetUnmanagedDll(_PythonDll)); @@ -2616,7 +2625,7 @@ static Delegates() internal static delegate* unmanaged[Cdecl] PyObject_DelItem { get; } internal static delegate* unmanaged[Cdecl] PyObject_GetIter { get; } internal static delegate* unmanaged[Cdecl] PyObject_Call { get; } - internal static delegate* unmanaged[Cdecl] PyObject_CallObject { get; } + internal static delegate* unmanaged[Cdecl] PyObject_CallObject { get; } internal static delegate* unmanaged[Cdecl] PyObject_RichCompareBool { get; } internal static delegate* unmanaged[Cdecl] PyObject_IsInstance { get; } internal static delegate* unmanaged[Cdecl] PyObject_IsSubclass { 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