Skip to content

Commit 32e446e

Browse files
committed
Drop C module dependency when getting _PyObject_NextNotImplemented
1 parent 9003ea0 commit 32e446e

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

src/runtime/runtime.cs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -292,23 +292,18 @@ internal static void Initialize(bool initSigs = false)
292292

293293
Error = new IntPtr(-1);
294294

295+
_PyObject_NextNotImplemented = Get_PyObject_NextNotImplemented();
296+
{
297+
IntPtr sys = PyImport_ImportModule("sys");
298+
PyModuleType = PyObject_Type(sys);
299+
XDecref(sys);
300+
}
301+
295302
// Initialize data about the platform we're running on. We need
296303
// this for the type manager and potentially other details. Must
297304
// happen after caching the python types, above.
298305
InitializePlatformData();
299306

300-
// Since `_PyObject_NextNotImplemented` would set to a heap class
301-
// for tp_iternext which doesn't implement __next__.
302-
// Thus we need a heap class to get it, the ZipImportError is a
303-
// heap class and it's in builtins, so we can use it as a trick.
304-
var zipimport = PyImport_ImportModule("zipimport");
305-
var ZipImportError = PyObject_GetAttrString(zipimport, "ZipImportError");
306-
_PyObject_NextNotImplemented = Marshal.ReadIntPtr(ZipImportError, TypeOffset.tp_iternext);
307-
XDecref(ZipImportError);
308-
XDecref(zipimport);
309-
310-
PyModuleType = PyObject_Type(zipimport);
311-
312307
// Initialize modules that depend on the runtime class.
313308
AssemblyManager.Initialize();
314309
PyCLRMetaType = MetaType.Initialize();
@@ -325,6 +320,24 @@ internal static void Initialize(bool initSigs = false)
325320
AssemblyManager.UpdatePath();
326321
}
327322

323+
private static IntPtr Get_PyObject_NextNotImplemented()
324+
{
325+
IntPtr globals = PyDict_New();
326+
const string code = "class A(object): pass";
327+
IntPtr res = PyRun_String(code, (IntPtr)RunFlagType.File, globals, globals);
328+
if (res == IntPtr.Zero)
329+
{
330+
XDecref(globals);
331+
throw new PythonException();
332+
}
333+
XDecref(res);
334+
IntPtr A = PyDict_GetItemString(globals, "A");
335+
IntPtr iternext = Marshal.ReadIntPtr(A, TypeOffset.tp_iternext);
336+
XDecref(globals);
337+
XDecref(A);
338+
return iternext;
339+
}
340+
328341
/// <summary>
329342
/// Initializes the data about platforms.
330343
///

0 commit comments

Comments
 (0)