8000 * Load PyModuleType without LibraryLoader · pythonnet/pythonnet@b3e889b · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit b3e889b

Browse files
committed
* Load PyModuleType without LibraryLoader
* Drop C module dependency when getting _PyObject_NextNotImplemented * Exception details for SetNoSiteFlag
1 parent 653a263 commit b3e889b

File tree

1 file changed

+38
-24
lines changed

1 file changed

+38
-24
lines changed

src/runtime/runtime.cs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -292,26 +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-
IntPtr dllLocal = IntPtr.Zero;
301-
var loader = LibraryLoader.Get(OperatingSystem);
302-
303-
// Since `_PyObject_NextNotImplemented` would set to a heap class
304-
// for tp_iternext which doesn't implement __next__.
305-
// Thus we need a heap class to get it, the ZipImportError is a
306-
// heap class and it's in builtins, so we can use it as a trick.
307-
var zipimport = PyImport_ImportModule("zipimport");
308-
var ZipImportError = PyObject_GetAttrString(zipimport, "ZipImportError");
309-
_PyObject_NextNotImplemented = Marshal.ReadIntPtr(ZipImportError, TypeOffset.tp_iternext);
310-
XDecref(ZipImportError);
311-
XDecref(zipimport);
312-
PyModuleType = loader.GetFunction(dllLocal, "PyModule_Type");
313-
314-
315307
// Initialize modules that depend on the runtime class.
316308
AssemblyManager.Initialize();
317309
PyCLRMetaType = MetaType.Initialize();
@@ -328,6 +320,29 @@ internal static void Initialize(bool initSigs = false)
328320
AssemblyManager.UpdatePath();
329321
}
330322

323+
private static IntPtr Get_PyObject_NextNotImplemented()
324+
{
325+
IntPtr globals = PyDict_New();
326+
if (PyDict_SetItemString(globals, "__builtins__", PyEval_GetBuiltins()) != 0)
327+
{
328+
XDecref(globals);
329+
throw new PythonException();
330+
}
331+
const string code = "class A(object): pass";
332+
IntPtr res = PyRun_String(code, (IntPtr)RunFlagType.File, globals, globals);
333+
if (res == IntPtr.Zero)
334+
{
335+
XDecref(globals);
336+
throw new PythonException();
337+
}
338+
XDecref(res);
339+
IntPtr A = PyDict_GetItemString(globals, "A");
340+
IntPtr iternext = Marshal.ReadIntPtr(A, TypeOffset.tp_iternext);
341+
XDecref(globals);
342+
XDecref(A);
343+
return iternext;
344+
}
345+
331346
/// <summary>
332347
/// Initializes the data about platforms.
333348
///
@@ -1893,25 +1908,24 @@ internal static IntPtr PyMem_Realloc(IntPtr ptr, long size)
18931908

18941909
internal static void SetNoSiteFlag()
18951910
{
1911+
if (_PythonDll == "__Internal")
1912+
{
1913+
throw new NotSupportedException("SetNoSiteFlag didn't support on static compile");
1914+
}
18961915
var loader = LibraryLoader.Get(OperatingSystem);
1897-
1898-
IntPtr dllLocal;
1899-
if (_PythonDll != "__Internal")
1916+
IntPtr dllLocal = loader.Load(_PythonDll);
1917+
if (dllLocal == IntPtr.Zero)
19001918
{
1901-
dllLocal = loader.Load(_PythonDll);
1919+
throw new Exception($"Cannot load {_PythonDll}");
19021920
}
1903-
19041921
try
19051922
{
19061923
Py_NoSiteFlag = loader.GetFunction(dllLocal, "Py_NoSiteFlag");
19071924
Marshal.WriteInt32(Py_NoSiteFlag, 1);
19081925
}
19091926
finally
19101927
{
1911-
if (dllLocal != IntPtr.Zero)
1912-
{
1913-
loader.Free(dllLocal);
1914-
}
1928+
loader.Free(dllLocal);
19151929
}
19161930
}
19171931
}

0 commit comments

Comments
 (0)
0