PySys_GetObject() private method

private PySys_GetObject ( string name ) : IntPtr
name string
return IntPtr
Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        /// <summary>
        /// We __really__ want to avoid using Python objects or APIs when
        /// probing for assemblies to load, since our ResolveHandler may be
        /// called in contexts where we don't have the Python GIL and can't
        /// even safely try to get it without risking a deadlock ;(
        /// To work around that, we update a managed copy of sys.path (which
        /// is the main thing we care about) when UpdatePath is called. The
        /// import hook calls this whenever it knows its about to use the
        /// assembly manager, which lets us keep up with changes to sys.path
        /// in a relatively lightweight and low-overhead way.
        /// </summary>
        internal static void UpdatePath()
        {
            BorrowedReference list = Runtime.PySys_GetObject("path");
            var count = Runtime.PyList_Size(list);
            var sep   = Path.DirectorySeparatorChar;

            if (count != pypath.Count)
            {
                pypath.Clear();
                probed.Clear();

                for (var i = 0; i < count; i++)
                {
                    BorrowedReference item = Runtime.PyList_GetItem(list, i);
                    string            path = Runtime.GetManagedString(item);
                    if (path != null)
                    {
                        pypath.Add(path == string.Empty ? path : path + sep);
                    }
                }

                // for performance we will search for all files in each directory in the path once
                Parallel.ForEach(pypath.Where(s =>
                {
                    try
                    {
                        lock (filesInPath)
                        {
                            // only search in directory if it exists and we haven't already analyzed it
                            return(Directory.Exists(s) && !filesInPath.ContainsKey(s));
                        }
                    }
                    catch
                    {
                        // just in case, file operations can throw
                    }
                    return(false);
                }), path =>
                {
                    var container = new HashSet <string>();
                    try
                    {
                        foreach (var file in Directory.EnumerateFiles(path)
                                 .Where(file => file.EndsWith(".dll") || file.EndsWith(".exe")))
                        {
                            container.Add(Path.GetFileName(file));
                        }
                    }
                    catch
                    {
                        // just in case, file operations can throw
                    }

                    lock (filesInPath)
                    {
                        filesInPath[path] = container;
                    }
                });
            }
        }
Esempio n. 3
0
        static void SetupImportHook()
        {
            // Create the import hook module
            using var import_hook_module = Runtime.PyModule_New("clr.loader");
            BorrowedReference mod_dict = Runtime.PyModule_GetDict(import_hook_module.BorrowOrThrow());

            Debug.Assert(mod_dict != null);

            // 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 = Runtime.PyTuple_New(2);
            PythonException.ThrowIfIsNull(args);
            using var codeStr = Runtime.PyString_FromString(LoaderCode);
            Runtime.PyTuple_SetItem(args.Borrow(), 0, codeStr.StealOrThrow());

            // reference not stolen due to overload incref'ing for us.
            Runtime.PyTuple_SetItem(args.Borrow(), 1, mod_dict);
            Runtime.PyObject_Call(exec, args.Borrow(), default).Dispose();
            // Set as a sub-module of clr.
            if (Runtime.PyModule_AddObject(ClrModuleReference, "loader", import_hook_module.Steal()) != 0)
            {
                throw PythonException.ThrowLastAsClrException();
            }

            // Finally, add the hook to the meta path
            var findercls = Runtime.PyDict_GetItemString(mod_dict, "DotNetFinder");

            using var finderCtorArgs = Runtime.PyTuple_New(0);
            using var finder_inst    = Runtime.PyObject_CallObject(findercls, finderCtorArgs.Borrow());
            var metapath = Runtime.PySys_GetObject("meta_path");

            PythonException.ThrowIfIsNotZero(Runtime.PyList_Append(metapath, finder_inst.BorrowOrThrow()));
        }
Esempio n. 4
0
 /// <summary>
 /// The initializing of the preload hook has to happen as late as
 /// possible since sys.ps1 is created after the CLR module is
 /// created.
 /// </summary>
 internal void InitializePreload()
 {
     if (interactive_preload)
     {
         interactive_preload = false;
         if (Runtime.PySys_GetObject("ps1") != IntPtr.Zero)
         {
             preload = true;
         }
         else
         {
             Exceptions.Clear();
             preload = false;
         }
     }
 }
Esempio n. 5
0
        //===================================================================
        // We __really__ want to avoid using Python objects or APIs when
        // probing for assemblies to load, since our ResolveHandler may be
        // called in contexts where we don't have the Python GIL and can't
        // even safely try to get it without risking a deadlock ;(
        //
        // To work around that, we update a managed copy of sys.path (which
        // is the main thing we care about) when UpdatePath is called. The
        // import hook calls this whenever it knows its about to use the
        // assembly manager, which lets us keep up with changes to sys.path
        // in a relatively lightweight and low-overhead way.
        //===================================================================

        internal static void UpdatePath()
        {
            IntPtr list  = Runtime.PySys_GetObject("path");
            int    count = Runtime.PyList_Size(list);

            if (count != pypath.Count)
            {
                pypath.Clear();
                probed.Clear();
                for (int i = 0; i < count; i++)
                {
                    IntPtr item = Runtime.PyList_GetItem(list, i);
                    string path = Runtime.GetManagedString(item);
                    if (path != null)
                    {
                        pypath.Add(path);
                    }
                }
            }
        }
Esempio n. 6
0
        public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
        {
            // 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.

            int num_args = Runtime.PyTuple_Size(args);

            if (num_args < 1)
            {
                return(Exceptions.RaiseTypeError(
                           "__import__() takes at least 1 argument (0 given)"
                           ));
            }

            // borrowed reference
            IntPtr py_mod_name = Runtime.PyTuple_GetItem(args, 0);

            if ((py_mod_name == IntPtr.Zero) ||
                (!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.

            IntPtr fromList = IntPtr.Zero;
            bool   fromlist = false;

            if (num_args >= 4)
            {
                fromList = Runtime.PyTuple_GetItem(args, 3);
                if ((fromList != IntPtr.Zero) &&
                    (Runtime.PyObject_IsTrue(fromList) == 1))
                {
                    fromlist = true;
                }
            }

            string mod_name = Runtime.GetManagedString(py_mod_name);

            if (mod_name == "CLR" || mod_name == "clr")
            {
                Runtime.Incref(root.pyHandle);
                return(root.pyHandle);
            }

            string realname = mod_name;

            if (mod_name.StartsWith("CLR."))
            {
                realname = mod_name.Substring(4);
            }

            string[] names = realname.Split('.');

            // Now we need to decide if the name refers to a CLR module,
            // and may have to do an implicit load (for b/w compatibility)
            // using the AssemblyManager. The assembly manager tries
            // really hard not to use Python objects or APIs, because
            // parts of it can run recursively and on strange threads.
            //
            // It does need an opportunity from time to time to check to
            // see if sys.path has changed, in a context that is safe. Here
            // we know we have the GIL, so we'll let it update if needed.

            AssemblyManager.UpdatePath();
            AssemblyManager.LoadImplicit(realname);
            if (!AssemblyManager.IsValidNamespace(realname))
            {
                return(Runtime.PyObject_Call(py_import, args, kw));
            }

            // See if sys.modules for this interpreter already has the
            // requested module. If so, just return the exising module.

            IntPtr modules = Runtime.PyImport_GetModuleDict();
            IntPtr module  = Runtime.PyDict_GetItem(modules, py_mod_name);

            if (module != IntPtr.Zero)
            {
                if (fromlist)
                {
                    Runtime.Incref(module);
                    return(module);
                }
                module = Runtime.PyDict_GetItemString(modules, names[0]);
                Runtime.Incref(module);
                return(module);
            }
            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.

            if (preload < 0)
            {
                if (Runtime.PySys_GetObject("ps1") != IntPtr.Zero)
                {
                    preload = 1;
                }
                else
                {
                    Exceptions.Clear();
                    preload = 0;
                }
            }

            ModuleObject head = (mod_name == realname) ? null : root;
            ModuleObject tail = root;

            for (int i = 0; i < names.Length; i++)
            {
                string      name = names[i];
                ManagedType mt   = tail.GetAttribute(name);
                if (!(mt is ModuleObject))
                {
                    string error = String.Format("No module named {0}", name);
                    Exceptions.SetError(Exceptions.ImportError, error);
                    return(IntPtr.Zero);
                }
                if (head == null)
                {
                    head = (ModuleObject)mt;
                }
                tail = (ModuleObject)mt;
                if (preload == 1)
                {
                    tail.LoadNames();
                }
                Runtime.PyDict_SetItemString(modules, tail.moduleName,
                                             tail.pyHandle
                                             );
            }

            ModuleObject mod = fromlist ? tail : head;

            if (fromlist && Runtime.PySequence_Size(fromList) == 1)
            {
                IntPtr fp = Runtime.PySequence_GetItem(fromList, 0);
                if ((preload < 1) && Runtime.GetManagedString(fp) == "*")
                {
                    mod.LoadNames();
                }
                Runtime.Decref(fp);
            }

            Runtime.Incref(mod.pyHandle);
            return(mod.pyHandle);
        }