public ExtensionType() { // Create a new PyObject whose type is a generated type that is // implemented by the particular concrete ExtensionType subclass. // The Python instance object is related to an instance of a // particular concrete subclass with a hidden CLR gchandle. BorrowedReference tp = TypeManager.GetTypeReference(GetType()); //int rc = (int)Marshal.ReadIntPtr(tp, TypeOffset.ob_refcnt); //if (rc > 1050) //{ // DebugUtil.Print("tp is: ", tp); // DebugUtil.DumpType(tp); //} NewReference py = Runtime.PyType_GenericAlloc(tp, 0); // Borrowed reference. Valid as long as pyHandle is valid. tpHandle = tp.DangerousGetAddress(); pyHandle = py.DangerousMoveToPointer(); #if DEBUG GetGCHandle(ObjectReference, TypeReference, out var existing); System.Diagnostics.Debug.Assert(existing == IntPtr.Zero); #endif SetupGc(); }
/// <summary> /// Set the 'args' slot on a python exception object that wraps /// a CLR exception. This is needed for pickling CLR exceptions as /// BaseException_reduce will only check the slots, bypassing the /// __getattr__ implementation, and thus dereferencing a NULL /// pointer. /// </summary> internal static void SetArgsAndCause(BorrowedReference ob, Exception e) { IntPtr args; if (!string.IsNullOrEmpty(e.Message)) { args = Runtime.PyTuple_New(1); IntPtr msg = Runtime.PyString_FromString(e.Message); Runtime.PyTuple_SetItem(args, 0, msg); } else { args = Runtime.PyTuple_New(0); } using var argsTuple = NewReference.DangerousFromPointer(args); if (Runtime.PyObject_SetAttrString(ob, "args", argsTuple) != 0) { throw PythonException.ThrowLastAsClrException(); } if (e.InnerException != null) { // Note: For an AggregateException, InnerException is only the first of the InnerExceptions. using var cause = CLRObject.GetReference(e.InnerException); Runtime.PyException_SetCause(ob, cause.Steal()); } }
static void SetupImportHook() { // Create the import hook module var import_hook_module = Runtime.PyModule_New("clr.loader"); // Run the python code to create the module's classes. var builtins = Runtime.PyEval_GetBuiltins(); var exec = Runtime.PyDict_GetItemString(builtins, "exec"); using var args = NewReference.DangerousFromPointer(Runtime.PyTuple_New(2)); var codeStr = NewReference.DangerousFromPointer(Runtime.PyString_FromString(LoaderCode)); Runtime.PyTuple_SetItem(args, 0, codeStr); var mod_dict = Runtime.PyModule_GetDict(import_hook_module); // reference not stolen due to overload incref'ing for us. Runtime.PyTuple_SetItem(args, 1, mod_dict); Runtime.PyObject_Call(exec, args, default).Dispose(); // Set as a sub-module of clr. if (Runtime.PyModule_AddObject(ClrModuleReference, "loader", import_hook_module.DangerousGetAddress()) != 0) { Runtime.XDecref(import_hook_module.DangerousGetAddress()); throw PythonException.ThrowLastAsClrException(); } // Finally, add the hook to the meta path var findercls = Runtime.PyDict_GetItemString(mod_dict, "DotNetFinder"); var finderCtorArgs = NewReference.DangerousFromPointer(Runtime.PyTuple_New(0)); var finder_inst = Runtime.PyObject_CallObject(findercls, finderCtorArgs); var metapath = Runtime.PySys_GetObject("meta_path"); Runtime.PyList_Append(metapath, finder_inst); }
/// <summary> /// Given a module or package name, import the /// module and return the resulting module object as a <see cref="PyModule"/>. /// </summary> /// <param name="name">Fully-qualified module or package name</param> public static PyModule Import(string name) { NewReference op = Runtime.PyImport_ImportModule(name); PythonException.ThrowIfIsNull(op); return(new PyModule(ref op)); }
/// <summary> /// Reloads the module, and returns the updated object /// </summary> public PyModule Reload() { NewReference op = Runtime.PyImport_ReloadModule(this.Reference); PythonException.ThrowIfIsNull(op); return(new PyModule(ref op)); }
public virtual NewReference Alloc() { // Create a new PyObject whose type is a generated type that is // implemented by the particular concrete ExtensionType subclass. // The Python instance object is related to an instance of a // particular concrete subclass with a hidden CLR gchandle. BorrowedReference tp = TypeManager.GetTypeReference(GetType()); //int rc = (int)Util.ReadIntPtr(tp, TypeOffset.ob_refcnt); //if (rc > 1050) //{ // DebugUtil.Print("tp is: ", tp); // DebugUtil.DumpType(tp); //} NewReference py = Runtime.PyType_GenericAlloc(tp, 0); #if DEBUG GetGCHandle(py.BorrowOrThrow(), tp, out var existing); System.Diagnostics.Debug.Assert(existing == IntPtr.Zero); #endif SetupGc(py.Borrow(), tp); return(py); }
private void Exec(string code, BorrowedReference _globals, BorrowedReference _locals) { using NewReference reference = Runtime.PyRun_String( code, RunFlagType.File, _globals, _locals ); PythonException.ThrowIfIsNull(reference); }
private static IntPtr FromString(string value) { using (var s = new PyString(value)) { NewReference val = Runtime.PyFloat_FromString(s.Reference); PythonException.ThrowIfIsNull(val); return(val.DangerousMoveToPointerOrNull()); } }
public static PyModule FromString(string name, string code) { using NewReference c = Runtime.Py_CompileString(code, "none", (int)RunFlagType.File); PythonException.ThrowIfIsNull(c); NewReference m = Runtime.PyImport_ExecCodeModule(name, c); PythonException.ThrowIfIsNull(m); return(new PyModule(ref m)); }
private void Exec(string code, IntPtr _globals, IntPtr _locals) { NewReference reference = Runtime.PyRun_String( code, RunFlagType.File, _globals, _locals ); PythonException.ThrowIfIsNull(reference); reference.Dispose(); }
/// <summary> /// Creates <see cref="CLRObject"/> proxy for the given object, /// and returns a <see cref="NewReference"/> to it. /// </summary> internal static NewReference MakeNewReference(object obj) { if (obj is null) { throw new ArgumentNullException(nameof(obj)); } // TODO: CLRObject currently does not have Dispose or finalizer which might change in the future return(NewReference.DangerousFromPointer(GetInstHandle(obj))); }
private void Exec(string code, IntPtr _globals, IntPtr _locals) { var flag = (IntPtr)Runtime.Py_file_input; NewReference reference = Runtime.PyRun_String( code, flag, _globals, _locals ); PythonException.ThrowIfIsNull(reference); reference.Dispose(); }
public static void Save() { if (!PySys_GetObject("dummy_gc").IsNull) { throw new Exception("Runtime State set already"); } NewReference objs = default; if (ShouldRestoreObjects) { objs = PySet_New(default);
/// <summary> /// Eval method /// </summary> /// <remarks> /// Evaluate a Python expression and return the result as a PyObject /// or null if an exception is raised. /// </remarks> public PyObject Eval(string code, PyDict locals = null) { Check(); IntPtr _locals = locals == null ? variables : locals.obj; NewReference reference = Runtime.PyRun_String( code, RunFlagType.Eval, variables, _locals ); PythonException.ThrowIfIsNull(reference); return(reference.MoveToPyObject()); }
/// <summary> /// Eval method /// </summary> /// <remarks> /// Evaluate a Python expression and return the result as a PyObject /// or null if an exception is raised. /// </remarks> public PyObject Eval(string code, PyDict locals = null) { Check(); BorrowedReference _locals = locals == null ? VarsRef : locals.Reference; NewReference reference = Runtime.PyRun_String( code, RunFlagType.Eval, VarsRef, _locals ); PythonException.ThrowIfIsNull(reference); return(reference.MoveToPyObject()); }
/// <summary> /// Return the clr python module (new reference) /// </summary> public static unsafe NewReference GetCLRModule(BorrowedReference fromList = default) { root.InitializePreload(); // update the module dictionary with the contents of the root dictionary root.LoadNames(); BorrowedReference py_mod_dict = Runtime.PyModule_GetDict(ClrModuleReference); using (var clr_dict = Runtime.PyObject_GenericGetDict(root.ObjectReference)) { Runtime.PyDict_Update(py_mod_dict, clr_dict); } // find any items from the from list and get them from the root if they're not // already in the module dictionary if (fromList != null) { if (Runtime.PyTuple_Check(fromList)) { using var mod_dict = new PyDict(py_mod_dict); using var from = new PyTuple(fromList); foreach (PyObject item in from) { if (mod_dict.HasKey(item)) { continue; } var s = item.AsManagedObject(typeof(string)) as string; if (s == null) { continue; } ManagedType attr = root.GetAttribute(s, true); if (attr == null) { continue; } Runtime.XIncref(attr.pyHandle); using (var obj = new PyObject(attr.pyHandle)) { mod_dict.SetItem(s, obj); } } } } Runtime.XIncref(py_clr_module); return(NewReference.DangerousFromPointer(py_clr_module)); }
internal static Exception?FetchCurrentOrNull(out ExceptionDispatchInfo?dispatchInfo) { dispatchInfo = null; // prevent potential interop errors in this method // from crashing process with undebuggable StackOverflowException RuntimeHelpers.EnsureSufficientExecutionStack(); using var _ = new Py.GILState(); Runtime.PyErr_Fetch(out var type, out var value, out var traceback); if (type.IsNull()) { Debug.Assert(value.IsNull()); Debug.Assert(traceback.IsNull()); return(null); } try { if (TryDecodePyErr(type.Borrow(), value.BorrowNullable(), traceback.BorrowNullable()) is { } pyErr) { type.Dispose(); value.Dispose(); traceback.Dispose(); return(pyErr); } } catch { type.Dispose(); value.Dispose(); traceback.Dispose(); throw; } var normalizedValue = new NewReference(value.Borrow()); Runtime.PyErr_NormalizeException(type: ref type, val: ref normalizedValue, tb: ref traceback); try { return(FromPyErr(typeRef: type.Borrow(), valRef: value.Borrow(), nValRef: normalizedValue.Borrow(), tbRef: traceback.BorrowNullable(), out dispatchInfo)); } finally { type.Dispose(); value.Dispose(); traceback.Dispose(); } }
/// <summary> /// Helper to get docstring from reflected constructor info. /// </summary> internal NewReference GetDocString() { MethodBase[] methods = binder.GetMethods(); var str = ""; foreach (MethodBase t in methods) { if (str.Length > 0) { str += Environment.NewLine; } str += t.ToString(); } return(NewReference.DangerousFromPointer(Runtime.PyString_FromString(str))); }
/// <summary> /// Internal RunString Method. /// </summary> /// <remarks> /// Run a string containing Python code. Returns the result of /// executing the code string as a PyObject instance, or null if /// an exception was raised. /// </remarks> internal static PyObject RunString(string code, IntPtr?globals, IntPtr?locals, RunFlagType flag) { var borrowedGlobals = true; if (globals == null) { globals = Runtime.PyEval_GetGlobals(); if (globals == IntPtr.Zero) { globals = Runtime.PyDict_New(); Runtime.PyDict_SetItemString( globals.Value, "__builtins__", Runtime.PyEval_GetBuiltins() ); borrowedGlobals = false; } } if (locals == null) { locals = globals; } try { NewReference result = Runtime.PyRun_String( code, (IntPtr)flag, globals.Value, locals.Value ); try { Runtime.CheckExceptionOccurred(); return(result.MoveToPyObject()); } finally { result.Dispose(); } } finally { if (!borrowedGlobals) { Runtime.XDecref(globals.Value); } } }
/// <summary> /// The following CreateType implementations do the necessary work to /// create Python types to represent managed extension types, reflected /// types, subclasses of reflected types and the managed metatype. The /// dance is slightly different for each kind of type due to different /// behavior needed and the desire to have the existing Python runtime /// do as much of the allocation and initialization work as possible. /// </summary> internal static unsafe IntPtr CreateType(Type impl) { IntPtr type = AllocateTypeObject(impl.Name, metatype: Runtime.PyCLRMetaType); IntPtr base_ = impl == typeof(CLRModule) ? Runtime.PyModuleType : Runtime.PyBaseObjectType; int newFieldOffset = InheritOrAllocateStandardFields(type, base_); int tp_clr_inst_offset = newFieldOffset; newFieldOffset += IntPtr.Size; int ob_size = newFieldOffset; // Set tp_basicsize to the size of our managed instance objects. Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size); Marshal.WriteInt32(type, ManagedType.Offsets.tp_clr_inst_offset, tp_clr_inst_offset); Marshal.WriteIntPtr(type, TypeOffset.tp_new, (IntPtr)Runtime.Delegates.PyType_GenericNew); SlotsHolder slotsHolder = CreateSolotsHolder(type); InitializeSlots(type, impl, slotsHolder); var flags = TypeFlags.Default | TypeFlags.HasClrInstance | TypeFlags.HeapType | TypeFlags.HaveGC; Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags); if (Runtime.PyType_Ready(type) != 0) { throw new PythonException(); } var dict = new BorrowedReference(Marshal.ReadIntPtr(type, TypeOffset.tp_dict)); var mod = NewReference.DangerousFromPointer(Runtime.PyString_FromString("CLR")); Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod); mod.Dispose(); InitMethods(type, impl); // The type has been modified after PyType_Ready has been called // Refresh the type Runtime.PyType_Modified(type); return(type); }
public bool MoveNext() { NewReference next = Runtime.PyIter_Next(Reference); if (next.IsNull()) { if (Exceptions.ErrorOccurred()) { throw new PythonException(); } // stop holding the previous object, if there was one _current = null; return(false); } _current = next.MoveToPyObject(); return(true); }
/// <summary> /// Eval method /// </summary> /// <remarks> /// Evaluate a Python expression and return the result as a PyObject /// or null if an exception is raised. /// </remarks> public PyObject Eval(string code, PyDict locals = null) { Check(); IntPtr _locals = locals == null ? variables : locals.obj; var flag = (IntPtr)Runtime.Py_eval_input; NewReference reference = Runtime.PyRun_String( code, flag, variables, _locals ); try { Runtime.CheckExceptionOccurred(); return(reference.MoveToPyObject()); } finally { reference.Dispose(); } }
private void Exec(string code, IntPtr _globals, IntPtr _locals) { var flag = (IntPtr)Runtime.Py_file_input; NewReference reference = Runtime.PyRun_String( code, flag, _globals, _locals ); try { Runtime.CheckExceptionOccurred(); if (!reference.IsNone()) { throw new PythonException(); } } finally { reference.Dispose(); } }
public new static void tp_dealloc(NewReference ob) { var self = (CLRObject?)GetManagedObject(ob.Borrow()); // don't let the python GC destroy this object Runtime.PyObject_GC_UnTrack(ob.Borrow()); // self may be null after Shutdown begun if (self is not null) { // The python should now have a ref count of 0, but we don't actually want to // deallocate the object until the C# object that references it is destroyed. // So we don't call PyObject_GC_Del here and instead we set the python // reference to a weak reference so that the C# object can be collected. GCHandle oldHandle = GetGCHandle(ob.Borrow()); GCHandle gc = GCHandle.Alloc(self, GCHandleType.Weak); SetGCHandle(ob.Borrow(), gc); oldHandle.Free(); } }
/// <summary> /// Constructor /// </summary> /// <remarks> /// Create a scope based on a Python Module. /// </remarks> internal PyScope(ref NewReference ptr, PyScopeManager manager) { if (!Runtime.PyType_IsSubtype(Runtime.PyObject_TYPE(ptr), Runtime.PyModuleType)) { throw new PyScopeException("object is not a module"); } Manager = manager ?? PyScopeManager.Global; obj = ptr.MoveToPyObject(); //Refcount of the variables not increase variables = Runtime.PyModule_GetDict(Reference).DangerousGetAddress(); PythonException.ThrowIfIsNull(variables); int res = Runtime.PyDict_SetItem( VarsRef, PyIdentifier.__builtins__, Runtime.PyEval_GetBuiltins() ); PythonException.ThrowIfIsNotZero(res); this.Name = this.Get <string>("__name__"); }
public ModuleObject(string name) { if (name == string.Empty) { throw new ArgumentException("Name must not be empty!"); } moduleName = name; cache = new Dictionary <string, ManagedType>(); _namespace = name; // Use the filename from any of the assemblies just so there's something for // anything that expects __file__ to be set. var filename = "unknown"; var docstring = "Namespace containing types from the following assemblies:\n\n"; foreach (Assembly a in AssemblyManager.GetAssemblies(name)) { if (!a.IsDynamic && a.Location != null) { filename = a.Location; } docstring += "- " + a.FullName + "\n"; } var dictRef = Runtime.PyObject_GenericGetDict(ObjectReference); PythonException.ThrowIfIsNull(dictRef); dict = dictRef.DangerousMoveToPointer(); using var pyname = NewReference.DangerousFromPointer(Runtime.PyString_FromString(moduleName)); using var pyfilename = NewReference.DangerousFromPointer(Runtime.PyString_FromString(filename)); using var pydocstring = NewReference.DangerousFromPointer(Runtime.PyString_FromString(docstring)); BorrowedReference pycls = TypeManager.GetTypeReference(GetType()); Runtime.PyDict_SetItem(DictRef, PyIdentifier.__name__, pyname); Runtime.PyDict_SetItem(DictRef, PyIdentifier.__file__, pyfilename); Runtime.PyDict_SetItem(DictRef, PyIdentifier.__doc__, pydocstring); Runtime.PyDict_SetItem(DictRef, PyIdentifier.__class__, pycls); InitializeModuleMembers(); }
private static PyModule Create(string name, string filename = null) { if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentNullException(nameof(name)); } NewReference op = Runtime.PyModule_New(name); PythonException.ThrowIfIsNull(op); if (filename != null) { BorrowedReference globals = Runtime.PyModule_GetDict(op); PythonException.ThrowIfIsNull(globals); int rc = Runtime.PyDict_SetItemString(globals, "__file__", filename.ToPython().Reference); PythonException.ThrowIfIsNotZero(rc); } return(new PyModule(ref op)); }
/// <summary> /// The following CreateType implementations do the necessary work to /// create Python types to represent managed extension types, reflected /// types, subclasses of reflected types and the managed metatype. The /// dance is slightly different for each kind of type due to different /// behavior needed and the desire to have the existing Python runtime /// do as much of the allocation and initialization work as possible. /// </summary> internal static IntPtr CreateType(Type impl) { IntPtr type = AllocateTypeObject(impl.Name, metatype: Runtime.PyTypeType); int ob_size = ObjectOffset.Size(type); // Set tp_basicsize to the size of our managed instance objects. Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)ob_size); var offset = (IntPtr)ObjectOffset.TypeDictOffset(type); Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset); SlotsHolder slotsHolder = CreateSolotsHolder(type); InitializeSlots(type, impl, slotsHolder); var flags = TypeFlags.Default | TypeFlags.Managed | TypeFlags.HeapType | TypeFlags.HaveGC; Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags); if (Runtime.PyType_Ready(type) != 0) { throw new PythonException(); } var dict = new BorrowedReference(Marshal.ReadIntPtr(type, TypeOffset.tp_dict)); var mod = NewReference.DangerousFromPointer(Runtime.PyString_FromString("CLR")); Runtime.PyDict_SetItem(dict, PyIdentifier.__module__, mod); mod.Dispose(); InitMethods(type, impl); // The type has been modified after PyType_Ready has been called // Refresh the type Runtime.PyType_Modified(type); return(type); }
public static IntPtr CreateObjectType() { using var globals = NewReference.DangerousFromPointer(Runtime.PyDict_New()); if (Runtime.PyDict_SetItemString(globals, "__builtins__", Runtime.PyEval_GetBuiltins()) != 0) { globals.Dispose(); throw new PythonException(); } const string code = "class A(object): pass"; using var resRef = Runtime.PyRun_String(code, RunFlagType.File, globals, globals); if (resRef.IsNull()) { globals.Dispose(); throw new PythonException(); } resRef.Dispose(); BorrowedReference A = Runtime.PyDict_GetItemString(globals, "A"); Debug.Assert(!A.IsNull); return(new NewReference(A).DangerousMoveToPointer()); }
/// <summary> /// The actual import hook that ties Python to the managed world. /// </summary> public static IntPtr __import__(IntPtr self, IntPtr argsRaw, IntPtr kw) { var args = new BorrowedReference(argsRaw); // Replacement for the builtin __import__. The original import // hook is saved as this.py_import. This version handles CLR // import and defers to the normal builtin for everything else. var num_args = Runtime.PyTuple_Size(args); if (num_args < 1) { return(Exceptions.RaiseTypeError("__import__() takes at least 1 argument (0 given)")); } BorrowedReference py_mod_name = Runtime.PyTuple_GetItem(args, 0); if (py_mod_name.IsNull || !Runtime.IsStringType(py_mod_name)) { return(Exceptions.RaiseTypeError("string expected")); } // Check whether the import is of the form 'from x import y'. // This determines whether we return the head or tail module. BorrowedReference fromList = default; var fromlist = false; if (num_args >= 4) { fromList = Runtime.PyTuple_GetItem(args, 3); if (fromList != null && Runtime.PyObject_IsTrue(fromList) == 1) { fromlist = true; } } string mod_name = Runtime.GetManagedString(py_mod_name); // Check these BEFORE the built-in import runs; may as well // do the Incref()ed return here, since we've already found // the module. if (mod_name == "clr") { NewReference clr_module = GetCLRModule(fromList); if (!clr_module.IsNull()) { BorrowedReference sys_modules = Runtime.PyImport_GetModuleDict(); if (!sys_modules.IsNull) { Runtime.PyDict_SetItemString(sys_modules, "clr", clr_module); } } return(clr_module.DangerousMoveToPointerOrNull()); } string realname = mod_name; // 2010-08-15: Always seemed smart to let python try first... // This shaves off a few tenths of a second on test_module.py // and works around a quirk where 'sys' is found by the // LoadImplicit() deprecation logic. // Turns out that the AssemblyManager.ResolveHandler() checks to see if any // Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very // little sense to me. IntPtr res = Runtime.PyObject_Call(py_import, args.DangerousGetAddress(), kw); if (res != IntPtr.Zero) { // There was no error. if (fromlist && IsLoadAll(fromList)) { var mod = ManagedType.GetManagedObject(res) as ModuleObject; mod?.LoadNames(); } return(res); } // There was an error if (!Exceptions.ExceptionMatches(Exceptions.ImportError)) { // and it was NOT an ImportError; bail out here. return(IntPtr.Zero); } if (mod_name == string.Empty) { // Most likely a missing relative import. // For example site-packages\bs4\builder\__init__.py uses it to check if a package exists: // from . import _html5lib // We don't support them anyway return(IntPtr.Zero); } // Save the exception var originalException = new PythonException(); // Otherwise, just clear the it. Exceptions.Clear(); string[] names = realname.Split('.'); // See if sys.modules for this interpreter already has the // requested module. If so, just return the existing module. BorrowedReference modules = Runtime.PyImport_GetModuleDict(); BorrowedReference module = Runtime.PyDict_GetItem(modules, py_mod_name); if (module != null) { if (fromlist) { if (IsLoadAll(fromList)) { var mod = ManagedType.GetManagedObject(module) as ModuleObject; mod?.LoadNames(); } return(new NewReference(module).DangerousMoveToPointer()); } module = Runtime.PyDict_GetItemString(modules, names[0]); return(new NewReference(module, canBeNull: true).DangerousMoveToPointer()); } Exceptions.Clear(); // Traverse the qualified module name to get the named module // and place references in sys.modules as we go. Note that if // we are running in interactive mode we pre-load the names in // each module, which is often useful for introspection. If we // are not interactive, we stick to just-in-time creation of // objects at lookup time, which is much more efficient. // NEW: The clr got a new module variable preload. You can // enable preloading in a non-interactive python processing by // setting clr.preload = True ModuleObject head = mod_name == realname ? null : root; ModuleObject tail = root; root.InitializePreload(); foreach (string name in names) { ManagedType mt = tail.GetAttribute(name, true); if (!(mt is ModuleObject)) { originalException.Restore(); return(IntPtr.Zero); } if (head == null) { head = (ModuleObject)mt; } tail = (ModuleObject)mt; if (CLRModule.preload) { tail.LoadNames(); } // Add the module to sys.modules Runtime.PyDict_SetItemString(modules, tail.moduleName, tail.ObjectReference); } { var mod = fromlist ? tail : head; if (fromlist && IsLoadAll(fromList)) { mod.LoadNames(); } Runtime.XIncref(mod.pyHandle); return(mod.pyHandle); } }