|
1 |
| -using System; |
| 1 | +using System; |
2 | 2 | using System.Runtime.InteropServices;
|
3 | 3 | using System.Security;
|
4 | 4 | using System.Text;
|
@@ -274,19 +274,17 @@ internal static void Initialize()
|
274 | 274 |
|
275 | 275 | Error = new IntPtr(-1);
|
276 | 276 |
|
277 |
| -#if PYTHON3 |
278 | 277 | IntPtr dllLocal = IntPtr.Zero;
|
279 | 278 | if (PythonDll != "__Internal")
|
280 | 279 | {
|
281 |
| - NativeMethods.LoadLibrary(PythonDll); |
| 280 | + dllLocal = NativeMethods.LoadLibrary(PythonDll); |
282 | 281 | }
|
283 | 282 | _PyObject_NextNotImplemented = NativeMethods.GetProcAddress(dllLocal, "_PyObject_NextNotImplemented");
|
284 | 283 | #if !(MONO_LINUX || MONO_OSX)
|
285 | 284 | if (dllLocal != IntPtr.Zero)
|
286 | 285 | {
|
287 | 286 | NativeMethods.FreeLibrary(dllLocal);
|
288 | 287 | }
|
289 |
| -#endif |
290 | 288 | #endif
|
291 | 289 |
|
292 | 290 | // Initialize modules that depend on the runtime class.
|
@@ -349,8 +347,8 @@ internal static int AtExit()
|
349 | 347 |
|
350 | 348 | #if PYTHON3
|
351 | 349 | internal static IntPtr PyBytesType;
|
352 |
| - internal static IntPtr _PyObject_NextNotImplemented; |
353 | 350 | #endif
|
| 351 | + internal static IntPtr _PyObject_NextNotImplemented; |
354 | 352 |
|
355 | 353 | internal static IntPtr PyNotImplemented;
|
356 | 354 | internal const int Py_LT = 0;
|
@@ -780,6 +778,21 @@ internal static string PyObject_GetTypeName(IntPtr op)
|
780 | 778 | return Marshal.PtrToStringAnsi(ppName);
|
781 | 779 | }
|
782 | 780 |
|
| 781 | + /// <summary> |
| 782 | + /// Test whether the Python object is an iterable. |
| 783 | + /// </summary> |
| 784 | + internal static bool PyObject_IsIterable(IntPtr pointer) |
| 785 | + { |
| 786 | + var ob_type = Marshal.ReadIntPtr(pointer, ObjectOffset.ob_type); |
| 787 | +#if PYTHON2 |
| 788 | + long tp_flags = Marshal.ReadInt64(ob_type, TypeOffset.tp_flags); |
| 789 | + if ((tp_flags & TypeFlags.HaveIter) == 0) |
| 790 | + return false; |
| 791 | +#endif |
| 792 | + IntPtr tp_iter = Marshal.ReadIntPtr(ob_type, TypeOffset.tp_iter); |
| 793 | + return tp_iter != IntPtr.Zero; |
| 794 | + } |
| 795 | + |
783 | 796 | [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
|
784 | 797 | internal static extern int PyObject_HasAttrString(IntPtr pointer, string name);
|
785 | 798 |
|
@@ -1425,17 +1438,17 @@ internal static bool PyTuple_Check(IntPtr ob)
|
1425 | 1438 | // Python iterator API
|
1426 | 1439 | //====================================================================
|
1427 | 1440 |
|
1428 |
| -#if PYTHON2 |
1429 |
| - [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)] |
1430 |
| - internal static extern bool PyIter_Check(IntPtr pointer); |
1431 |
| -#elif PYTHON3 |
1432 | 1441 | internal static bool PyIter_Check(IntPtr pointer)
|
1433 | 1442 | {
|
1434 |
| - var ob_type = (IntPtr)Marshal.PtrToStructure(pointer + ObjectOffset.ob_type, typeof(IntPtr)); |
1435 |
| - IntPtr tp_iternext = ob_type + TypeOffset.tp_iternext; |
1436 |
| - return tp_iternext != null && tp_iternext != _PyObject_NextNotImplemented; |
1437 |
| - } |
| 1443 | + var ob_type = Marshal.ReadIntPtr(pointer, ObjectOffset.ob_type); |
| 1444 | +#if PYTHON2 |
| 1445 | + long tp_flags = Marshal.ReadInt64(ob_type, TypeOffset.tp_flags); |
| 1446 | + if ((tp_flags & TypeFlags.HaveIter) == 0) |
| 1447 | + return false; |
1438 | 1448 | #endif
|
| 1449 | + IntPtr tp_iternext = Marshal.ReadIntPtr(ob_type, TypeOffset.tp_iternext); |
| 1450 | + return tp_iternext != IntPtr.Zero && tp_iternext != _PyObject_NextNotImplemented; |
| 1451 | + } |
1439 | 1452 |
|
1440 | 1453 | [DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
|
1441 | 1454 | internal static extern IntPtr PyIter_Next(IntPtr pointer);
|
|
0 commit comments