Skip to content

Commit 5ded48d

Browse files
committed
dispose all temporary objects in PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test
1 parent 33d771c commit 5ded48d

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

src/embed_tests/TestRuntime.cs

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,27 +92,29 @@ public static void PyCheck_Iter_PyObject_IsIterable_ThreadingLock_Test()
9292
{
9393
Runtime.Runtime.Py_Initialize();
9494

95-
// Create an instance of threading.Lock, which is one of the very few types that does not have the
96-
// TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check.
97-
var threading = Runtime.Runtime.PyImport_ImportModule("threading");
98-
Exceptions.ErrorCheck(threading);
99-
var threadingDict = Runtime.Runtime.PyModule_GetDict(threading);
100-
Exceptions.ErrorCheck(threadingDict);
101-
var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock");
102-
if (lockType.IsNull)
103-
throw new KeyNotFoundException("class 'Lock' was not found in 'threading'");
104-
105-
var args = Runtime.Runtime.PyTuple_New(0);
106-
var lockInstance = Runtime.Runtime.PyObject_CallObject(lockType.DangerousGetAddress(), args);
107-
Runtime.Runtime.XDecref(args);
108-
Exceptions.ErrorCheck(lockInstance);
109-
110-
Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance));
111-
Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance));
112-
113-
threading.Dispose();
114-
115-
Runtime.Runtime.Py_Finalize();
95+
try
96+
{
97+
// Create an instance of threading.Lock, which is one of the very few types that does not have the
98+
// TypeFlags.HaveIter set in Python 2. This tests a different code path in PyObject_IsIterable and PyIter_Check.
99+
using var threading = Runtime.Runtime.PyImport_ImportModule("threading");
100+
Exceptions.ErrorCheck(threading);
101+
var threadingDict = Runtime.Runtime.PyModule_GetDict(threading);
102+
Exceptions.ErrorCheck(threadingDict);
103+
var lockType = Runtime.Runtime.PyDict_GetItemString(threadingDict, "Lock");
104+
if (lockType.IsNull)
105+
throw new PythonException();
106+
107+
using var args = NewReference.DangerousFromPointer(Runtime.Runtime.PyTuple_New(0));
108+
using var lockInstance = Runtime.Runtime.PyObject_CallObject(lockType, args);
109+
Exceptions.ErrorCheck(lockInstance);
110+
111+
Assert.IsFalse(Runtime.Runtime.PyObject_IsIterable(lockInstance));
112+
Assert.IsFalse(Runtime.Runtime.PyIter_Check(lockInstance));
113+
}
114+
finally
115+
{
116+
Runtime.Runtime.Py_Finalize();
117+
}
116118
}
117119
}
118120
}

src/runtime/runtime.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,11 @@ internal static string PyObject_GetTypeName(IntPtr op)
10091009
return Marshal.PtrToStringAnsi(ppName);
10101010
}
10111011

1012+
/// <summary>
1013+
/// Test whether the Python object is an iterable.
1014+
/// </summary>
1015+
internal static bool PyObject_IsIterable(BorrowedReference ob)
1016+
=> PyObject_IsIterable(ob.DangerousGetAddress());
10121017
/// <summary>
10131018
/// Test whether the Python object is an iterable.
10141019
/// </summary>
@@ -1078,7 +1083,10 @@ internal static IntPtr PyObject_GetAttr(IntPtr pointer, IntPtr name)
10781083
internal static IntPtr PyObject_Call(IntPtr pointer, IntPtr args, IntPtr kw) => Delegates.PyObject_Call(pointer, args, kw);
10791084

10801085

1081-
internal static IntPtr PyObject_CallObject(IntPtr pointer, IntPtr args) => Delegates.PyObject_CallObject(pointer, args);
1086+
internal static NewReference PyObject_CallObject(BorrowedReference callable, BorrowedReference args) => Delegates.PyObject_CallObject(callable, args);
1087+
internal static IntPtr PyObject_CallObject(IntPtr pointer, IntPtr args)
1088+
=> Delegates.PyObject_CallObject(new BorrowedReference(pointer), new BorrowedReference(args))
1089+
.DangerousMoveToPointerOrNull();
10821090

10831091

10841092
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)
18801888
//====================================================================
18811889
// Python iterator API
18821890
//====================================================================
1891+
internal static bool PyIter_Check(BorrowedReference ob) => PyIter_Check(ob.DangerousGetAddress());
18831892

18841893
internal static bool PyIter_Check(IntPtr pointer)
18851894
{
@@ -2317,7 +2326,7 @@ static Delegates()
23172326
PyObject_DelItem = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int>)GetFunctionByName(nameof(PyObject_DelItem), GetUnmanagedDll(_PythonDll));
23182327
PyObject_GetIter = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr>)GetFunctionByName(nameof(PyObject_GetIter), GetUnmanagedDll(_PythonDll));
23192328
PyObject_Call = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, IntPtr>)GetFunctionByName(nameof(PyObject_Call), GetUnmanagedDll(_PythonDll));
2320-
PyObject_CallObject = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr>)GetFunctionByName(nameof(PyObject_CallObject), GetUnmanagedDll(_PythonDll));
2329+
PyObject_CallObject = (delegate* unmanaged[Cdecl]<BorrowedReference, BorrowedReference, NewReference>)GetFunctionByName(nameof(PyObject_CallObject), GetUnmanagedDll(_PythonDll));
23212330
PyObject_RichCompareBool = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int, int>)GetFunctionByName(nameof(PyObject_RichCompareBool), GetUnmanagedDll(_PythonDll));
23222331
PyObject_IsInstance = (delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int>)GetFunctionByName(nameof(PyObject_IsInstance), GetUnmanagedDll(_PythonDll));
23232332
PyObject_IsSubclass = (delegate* unmanaged[Cdecl]<BorrowedReference, BorrowedReference, int>)GetFunctionByName(nameof(PyObject_IsSubclass), GetUnmanagedDll(_PythonDll));
@@ -2616,7 +2625,7 @@ static Delegates()
26162625
internal static delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int> PyObject_DelItem { get; }
26172626
internal static delegate* unmanaged[Cdecl]<IntPtr, IntPtr> PyObject_GetIter { get; }
26182627
internal static delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr, IntPtr> PyObject_Call { get; }
2619-
internal static delegate* unmanaged[Cdecl]<IntPtr, IntPtr, IntPtr> PyObject_CallObject { get; }
2628+
internal static delegate* unmanaged[Cdecl]<BorrowedReference, BorrowedReference, NewReference> PyObject_CallObject { get; }
26202629
internal static delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int, int> PyObject_RichCompareBool { get; }
26212630
internal static delegate* unmanaged[Cdecl]<IntPtr, IntPtr, int> PyObject_IsInstance { get; }
26222631
internal static delegate* unmanaged[Cdecl]<BorrowedReference, BorrowedReference, int> PyObject_IsSubclass { get; }

0 commit comments

Comments
 (0)