PyImport_GetModuleDict() private method

private PyImport_GetModuleDict ( ) : IntPtr
return IntPtr
Esempio n. 1
0
        /// <summary>
        /// Initialization performed on startup of the Python runtime.
        /// </summary>
        internal static void Initialize()
        {
            InitImport();

            // Initialize the clr module and tell Python about it.
            root = new CLRModule();

#if PYTHON3
            // create a python module with the same methods as the clr module-like object
            InitializeModuleDef();
            py_clr_module = Runtime.PyModule_Create2(module_def, 3);

            // both dicts are borrowed references
            IntPtr mod_dict = Runtime.PyModule_GetDict(py_clr_module);
            IntPtr clr_dict = Runtime._PyObject_GetDictPtr(root.pyHandle); // PyObject**
            clr_dict = (IntPtr)Marshal.PtrToStructure(clr_dict, typeof(IntPtr));

            Runtime.PyDict_Update(mod_dict, clr_dict);
#elif PYTHON2
            Runtime.XIncref(root.pyHandle); // we are using the module two times
            py_clr_module = root.pyHandle;  // Alias handle for PY2/PY3
#endif
            IntPtr dict = Runtime.PyImport_GetModuleDict();
            Runtime.PyDict_SetItemString(dict, "CLR", py_clr_module);
            Runtime.PyDict_SetItemString(dict, "clr", py_clr_module);
        }
Esempio n. 2
0
        internal static void RestoreRuntimeData(RuntimeDataStorage storage)
        {
            storage.GetValue("py_clr_module", out py_clr_module);
            var rootHandle = storage.GetValue <IntPtr>("root");

            root = (CLRModule)ManagedType.GetManagedObject(rootHandle);
            BorrowedReference dict = Runtime.PyImport_GetModuleDict();

            Runtime.PyDict_SetItemString(dict, "clr", ClrModuleReference);
            SetupNamespaceTracking();
        }
Esempio n. 3
0
        /// <summary>
        /// Initialization performed on startup of the Python runtime.
        /// </summary>
        internal static void Initialize()
        {
            // Initialize the Python <--> CLR module hook. We replace the
            // built-in Python __import__ with our own. This isn't ideal,
            // but it provides the most "Pythonic" way of dealing with CLR
            // modules (Python doesn't provide a way to emulate packages).
            IntPtr dict = Runtime.PyImport_GetModuleDict();

            IntPtr mod = Runtime.IsPython3
                ? Runtime.PyImport_ImportModule("builtins")
                : Runtime.PyDict_GetItemString(dict, "__builtin__");

            if (mod == IntPtr.Zero)
            {
                throw new PythonException();
            }

            py_import = Runtime.PyObject_GetAttrString(mod, "__import__");
            if (py_import == IntPtr.Zero)
            {
                throw new PythonException();
            }

            hook = new MethodWrapper(typeof(ImportHook), "__import__", "TernaryFunc");
            Runtime.PyObject_SetAttrString(mod, "__import__", hook.ptr);

            if (Runtime.IsPython3)
            {
                // On Python3, PyImport_ImportModule got a new reference, so we need to decrease it.
                Runtime.Py_DecRef(mod);
            }

            root = new CLRModule();

#if PYTHON3
            // create a python module with the same methods as the clr module-like object
            InitializeModuleDef();
            py_clr_module = Runtime.PyModule_Create2(module_def, 3);

            // both dicts are borrowed references
            IntPtr mod_dict = Runtime.PyModule_GetDict(py_clr_module);
            IntPtr clr_dict = Runtime._PyObject_GetDictPtr(root.pyHandle); // PyObject**
            clr_dict = (IntPtr)Marshal.PtrToStructure(clr_dict, typeof(IntPtr));

            Runtime.PyDict_Update(mod_dict, clr_dict);
#elif PYTHON2
            Runtime.XIncref(root.pyHandle); // we are using the module two times
            py_clr_module = root.pyHandle;  // Alias handle for PY2/PY3
#endif
            Runtime.PyDict_SetItemString(dict, "CLR", py_clr_module);
            Runtime.PyDict_SetItemString(dict, "clr", py_clr_module);
        }
Esempio n. 4
0
            public override ValueType Execute(ValueType arg)
            {
                const string code = @"
from Python.EmbeddingTest.Domain import MyClass

def test_obj_call():
    obj = MyClass()
    obj.Method()
    obj.StaticMethod()
    obj.Property = 1
    obj.Field = 10

test_obj_call()
";
                const string name = "test_domain_reload_mod";

                using (Py.GIL())
                {
                    // Create a new module
                    IntPtr module = PyRuntime.PyModule_New(name);
                    Assert.That(module != IntPtr.Zero);
                    IntPtr globals = PyRuntime.PyObject_GetAttrString(module, "__dict__");
                    Assert.That(globals != IntPtr.Zero);
                    try
                    {
                        // import builtins
                        // module.__dict__[__builtins__] = builtins
                        int res = PyRuntime.PyDict_SetItemString(globals, "__builtins__",
                                                                 PyRuntime.PyEval_GetBuiltins());
                        PythonException.ThrowIfIsNotZero(res);

                        // Execute the code in the module's scope
                        PythonEngine.Exec(code, globals);
                        // import sys
                        // modules = sys.modules
                        IntPtr modules = PyRuntime.PyImport_GetModuleDict();
                        // modules[name] = module
                        res = PyRuntime.PyDict_SetItemString(modules, name, module);
                        PythonException.ThrowIfIsNotZero(res);
                    }
                    catch
                    {
                        PyRuntime.XDecref(module);
                        throw;
                    }
                    finally
                    {
                        PyRuntime.XDecref(globals);
                    }
                    return(module);
                }
            }
Esempio n. 5
0
        internal static void RestoreRuntimeData(ImportHookState storage)
        {
            py_clr_module = storage.PyCLRModule;
            var rootHandle = storage.Root;

            root      = new PyObject(rootHandle);
            clrModule = (CLRModule)ManagedType.GetManagedObject(rootHandle) !;
            BorrowedReference dict = Runtime.PyImport_GetModuleDict();

            Runtime.PyDict_SetItemString(dict, "clr", ClrModuleReference);
            SetupNamespaceTracking();

            RestoreDotNetModules(storage.Modules);
        }
Esempio n. 6
0
        private static void RestoreDotNetModules(Dictionary <PyString, PyObject> modules)
        {
            var pyMoudles = Runtime.PyImport_GetModuleDict();

            foreach (var item in modules)
            {
                var moduleName = item.Key;
                var module     = item.Value;
                int res        = Runtime.PyDict_SetItem(pyMoudles, moduleName, module);
                PythonException.ThrowIfIsNotZero(res);
                item.Key.Dispose();
                item.Value.Dispose();
            }
            modules.Clear();
        }
Esempio n. 7
0
        /// <summary>
        /// Cleanup resources upon shutdown of the Python runtime.
        /// </summary>
        internal static void Shutdown()
        {
            if (Runtime.Py_IsInitialized() != 0)
            {
                Runtime.XDecref(py_clr_module);
                Runtime.XDecref(root.pyHandle);

                // Re-install the original import function
                IntPtr dict = Runtime.PyImport_GetModuleDict();
                IntPtr mod  = Runtime.IsPython3
                    ? Runtime.PyImport_ImportModule("builtins")
                    : Runtime.PyDict_GetItemString(dict, "__builtin__");
                Runtime.PyObject_SetAttrString(mod, "__import__", py_import);
                Runtime.XDecref(py_import);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Get a <i>New reference</i> to the builtins module.
        /// </summary>
        static IntPtr GetNewRefToBuiltins()
        {
            if (Runtime.IsPython3)
            {
                return(Runtime.PyImport_ImportModule("builtins"));
            }
            else
            {
                // dict is a borrowed ref, no need to decref
                IntPtr dict = Runtime.PyImport_GetModuleDict();

                // GetItemString is a borrowed ref; incref to get a new ref
                IntPtr builtins = Runtime.PyDict_GetItemString(dict, "__builtin__");
                Runtime.XIncref(builtins);
                return(builtins);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Initialization performed on startup of the Python runtime.
        /// </summary>
        internal static unsafe void Initialize()
        {
            InitImport();

            // Initialize the clr module and tell Python about it.
            root = new CLRModule();

            // create a python module with the same methods as the clr module-like object
            InitializeModuleDef();
            py_clr_module = Runtime.PyModule_Create2(module_def, 3);

            // both dicts are borrowed references
            BorrowedReference mod_dict = Runtime.PyModule_GetDict(ClrModuleReference);
            BorrowedReference clr_dict = *Runtime._PyObject_GetDictPtr(root.ObjectReference);

            Runtime.PyDict_Update(mod_dict, clr_dict);
            BorrowedReference dict = Runtime.PyImport_GetModuleDict();

            Runtime.PyDict_SetItemString(dict, "CLR", ClrModuleReference);
            Runtime.PyDict_SetItemString(dict, "clr", ClrModuleReference);
        }
Esempio n. 10
0
        //===================================================================
        // Initialization performed on startup of the Python runtime.
        //===================================================================

        internal static void Initialize()
        {
            // Initialize the Python <--> CLR module hook. We replace the
            // built-in Python __import__ with our own. This isn't ideal,
            // but it provides the most "Pythonic" way of dealing with CLR
            // modules (Python doesn't provide a way to emulate packages).

            IntPtr dict = Runtime.PyImport_GetModuleDict();
            IntPtr mod  = Runtime.PyDict_GetItemString(dict, "__builtin__");

            py_import = Runtime.PyObject_GetAttrString(mod, "__import__");

            hook = new MethodWrapper(typeof(ImportHook), "__import__");
            Runtime.PyObject_SetAttrString(mod, "__import__", hook.ptr);
            Runtime.Decref(hook.ptr);

            root = new CLRModule();
            Runtime.Incref(root.pyHandle); // we are using the module two times
            Runtime.PyDict_SetItemString(dict, "CLR", root.pyHandle);
            Runtime.PyDict_SetItemString(dict, "clr", root.pyHandle);
        }
Esempio n. 11
0
        /// <summary>
        /// Initialization performed on startup of the Python runtime.
        /// </summary>
        internal static unsafe void Initialize()
        {
            // Initialize the clr module and tell Python about it.
            root = new CLRModule();

            // create a python module with the same methods as the clr module-like object
            py_clr_module = Runtime.PyModule_New("clr").DangerousMoveToPointer();

            // both dicts are borrowed references
            BorrowedReference mod_dict = Runtime.PyModule_GetDict(ClrModuleReference);

            using var clr_dict = Runtime.PyObject_GenericGetDict(root.ObjectReference);

            Runtime.PyDict_Update(mod_dict, clr_dict);
            BorrowedReference dict = Runtime.PyImport_GetModuleDict();

            Runtime.PyDict_SetItemString(dict, "CLR", ClrModuleReference);
            Runtime.PyDict_SetItemString(dict, "clr", ClrModuleReference);
            SetupNamespaceTracking();
            SetupImportHook();
        }
Esempio n. 12
0
        //===================================================================
        // Initialization performed on startup of the Python runtime.
        //===================================================================

        internal static void Initialize()
        {
            // Initialize the Python <--> CLR module hook. We replace the
            // built-in Python __import__ with our own. This isn't ideal,
            // but it provides the most "Pythonic" way of dealing with CLR
            // modules (Python doesn't provide a way to emulate packages).
            IntPtr dict = Runtime.PyImport_GetModuleDict();

#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
            IntPtr mod = Runtime.PyImport_ImportModule("builtins");
            py_import = Runtime.PyObject_GetAttrString(mod, "__import__");
#else
            IntPtr mod = Runtime.PyDict_GetItemString(dict, "__builtin__");
            py_import = Runtime.PyObject_GetAttrString(mod, "__import__");
#endif
            hook = new MethodWrapper(typeof(ImportHook), "__import__", "TernaryFunc");
            Runtime.PyObject_SetAttrString(mod, "__import__", hook.ptr);
            Runtime.Decref(hook.ptr);

            root = new CLRModule();

#if (PYTHON32 || PYTHON33 || PYTHON34 || PYTHON35)
            // create a python module with the same methods as the clr module-like object
            module_def    = ModuleDefOffset.AllocModuleDef("clr");
            py_clr_module = Runtime.PyModule_Create2(module_def, 3);

            // both dicts are borrowed references
            IntPtr mod_dict = Runtime.PyModule_GetDict(py_clr_module);
            IntPtr clr_dict = Runtime._PyObject_GetDictPtr(root.pyHandle); // PyObject**
            clr_dict = (IntPtr)Marshal.PtrToStructure(clr_dict, typeof(IntPtr));

            Runtime.PyDict_Update(mod_dict, clr_dict);
            Runtime.PyDict_SetItemString(dict, "CLR", py_clr_module);
            Runtime.PyDict_SetItemString(dict, "clr", py_clr_module);
#else
            Runtime.Incref(root.pyHandle); // we are using the module two times
            Runtime.PyDict_SetItemString(dict, "CLR", root.pyHandle);
            Runtime.PyDict_SetItemString(dict, "clr", root.pyHandle);
#endif
        }
Esempio n. 13
0
        private static Dictionary <PyString, PyObject> GetDotNetModules()
        {
            BorrowedReference pyModules = Runtime.PyImport_GetModuleDict();

            using var items = Runtime.PyDict_Items(pyModules);
            nint length = Runtime.PyList_Size(items.BorrowOrThrow());

            Debug.Assert(length >= 0);
            var modules = new Dictionary <PyString, PyObject>();

            for (nint i = 0; i < length; i++)
            {
                BorrowedReference item   = Runtime.PyList_GetItem(items.Borrow(), i);
                BorrowedReference name   = Runtime.PyTuple_GetItem(item, 0);
                BorrowedReference module = Runtime.PyTuple_GetItem(item, 1);
                if (ManagedType.IsInstanceOfManagedType(module))
                {
                    modules.Add(new PyString(name), new PyObject(module));
                }
            }
            return(modules);
        }
Esempio n. 14
0
        /// <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);
            }
        }
Esempio n. 15
0
        //===================================================================
        // The actual import hook that ties Python to the managed world.
        //===================================================================

        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);

            // 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")
            {
                root.InitializePreload();
                Runtime.Incref(root.pyHandle);
                return(root.pyHandle);
            }
            if (mod_name == "CLR")
            {
                Exceptions.deprecation("The CLR module is deprecated. " +
                                       "Please use 'clr'.");
                root.InitializePreload();
                Runtime.Incref(root.pyHandle);
                return(root.pyHandle);
            }
            string realname = mod_name;

            if (mod_name.StartsWith("CLR."))
            {
                realname = mod_name.Substring(4);
                string msg = String.Format("Importing from the CLR.* namespace " +
                                           "is deprecated. Please import '{0}' directly.", realname);
                Exceptions.deprecation(msg);
            }
            else
            {
                // 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, kw);
                if (res != IntPtr.Zero)
                {
                    // There was no error.
                    return(res);
                }
                // There was an error
                if (!Exceptions.ExceptionMatches(Exceptions.ImportError))
                {
                    // and it was NOT an ImportError; bail out here.
                    return(IntPtr.Zero);
                }
                // Otherwise,  just clear the it.
                Exceptions.Clear();
            }

            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();
            if (!AssemblyManager.IsValidNamespace(realname))
            {
                bool fromFile = false;
                if (AssemblyManager.LoadImplicit(realname, out fromFile))
                {
                    if (true == fromFile)
                    {
                        string deprWarning = String.Format("\nThe module was found, but not in a referenced namespace.\n" +
                                                           "Implicit loading is deprecated. Please use clr.AddReference(\"{0}\").", realname);
                        Exceptions.deprecation(deprWarning);
                    }
                }
                else
                {
                    // May be called when a module being imported imports a module.
                    // In particular, I've seen decimal import copy import org.python.core
                    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.
            // 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();

            for (int i = 0; i < names.Length; i++)
            {
                string      name = names[i];
                ManagedType mt   = tail.GetAttribute(name, true);
                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 (CLRModule.preload)
                {
                    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 ((!CLRModule.preload) && Runtime.GetManagedString(fp) == "*")
                {
                    mod.LoadNames();
                }
                Runtime.Decref(fp);
            }

            Runtime.Incref(mod.pyHandle);
            return(mod.pyHandle);
        }
Esempio n. 16
0
        //===================================================================
        // The actual import hook that ties Python to the managed world.
        //===================================================================

        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")
            {
                Exceptions.deprecation("The CLR module is deprecated. " +
                                       "Please use 'clr'.");
                root.InitializePreload();
                Runtime.Incref(root.pyHandle);
                return(root.pyHandle);
            }

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

            string realname = mod_name;

            if (mod_name.StartsWith("CLR."))
            {
                realname = mod_name.Substring(4);
                string msg = String.Format("Importing from the CLR.* namespace " +
                                           "is deprecated. Please import '{0}' directly.", realname);
                Exceptions.deprecation(msg);
            }

            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.
            // 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();

            for (int i = 0; i < names.Length; i++)
            {
                string      name = names[i];
                ManagedType mt   = tail.GetAttribute(name, true);
                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 (CLRModule.preload)
                {
                    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 ((!CLRModule.preload) && Runtime.GetManagedString(fp) == "*")
                {
                    mod.LoadNames();
                }
                Runtime.Decref(fp);
            }

            Runtime.Incref(mod.pyHandle);
            return(mod.pyHandle);
        }
Esempio n. 17
0
        /// <summary>
        /// The actual import hook that ties Python to the managed world.
        /// </summary>
        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.

            var 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;
            var    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);

            // 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" || mod_name == "CLR")
            {
                if (mod_name == "CLR")
                {
                    Exceptions.deprecation("The CLR module is deprecated. Please use 'clr'.");
                }
                IntPtr clr_module = GetCLRModule(fromList);
                if (clr_module != IntPtr.Zero)
                {
                    IntPtr sys_modules = Runtime.PyImport_GetModuleDict();
                    if (sys_modules != IntPtr.Zero)
                    {
                        Runtime.PyDict_SetItemString(sys_modules, "clr", clr_module);
                    }
                }
                return(clr_module);
            }

            string realname   = mod_name;
            string clr_prefix = null;

            if (mod_name.StartsWith("CLR."))
            {
                clr_prefix = "CLR."; // prepend when adding the module to sys.modules
                realname   = mod_name.Substring(4);
                string msg = $"Importing from the CLR.* namespace is deprecated. Please import '{realname}' directly.";
                Exceptions.deprecation(msg);
            }
            else
            {
                // 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, 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);
                }
                // Otherwise,  just clear the it.
                Exceptions.Clear();
            }

            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();
            if (!AssemblyManager.IsValidNamespace(realname))
            {
                var loadExceptions = new List <Exception>();
                if (!AssemblyManager.LoadImplicit(realname, assemblyLoadErrorHandler: loadExceptions.Add))
                {
                    // May be called when a module being imported imports a module.
                    // In particular, I've seen decimal import copy import org.python.core
                    IntPtr importResult = Runtime.PyObject_Call(py_import, args, kw);
                    // TODO: use ModuleNotFoundError in Python 3.6+
                    if (importResult == IntPtr.Zero && loadExceptions.Count > 0 &&
                        Exceptions.ExceptionMatches(Exceptions.ImportError))
                    {
                        loadExceptions.Add(new PythonException());
                        var importError = new PyObject(new BorrowedReference(Exceptions.ImportError));
                        importError.SetAttr("__cause__", new AggregateException(loadExceptions).ToPython());
                        Runtime.PyErr_SetObject(new BorrowedReference(Exceptions.ImportError), importError.Reference);
                    }
                    return(importResult);
                }
            }

            // See if sys.modules for this interpreter already has the
            // requested module. If so, just return the existing module.
            IntPtr modules = Runtime.PyImport_GetModuleDict();
            IntPtr module  = Runtime.PyDict_GetItem(modules, py_mod_name);

            if (module != IntPtr.Zero)
            {
                if (fromlist)
                {
                    if (IsLoadAll(fromList))
                    {
                        var mod = ManagedType.GetManagedObject(module) as ModuleObject;
                        mod?.LoadNames();
                    }
                    Runtime.XIncref(module);
                    return(module);
                }
                if (clr_prefix != null)
                {
                    return(GetCLRModule(fromList));
                }
                module = Runtime.PyDict_GetItemString(modules, names[0]);
                Runtime.XIncref(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.
            // 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))
                {
                    Exceptions.SetError(Exceptions.ImportError, $"No module named {name}");
                    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.pyHandle);

                // If imported from CLR add CLR.<modulename> to sys.modules as well
                if (clr_prefix != null)
                {
                    Runtime.PyDict_SetItemString(modules, clr_prefix + tail.moduleName, tail.pyHandle);
                }
            }

            {
                var mod = fromlist ? tail : head;

                if (fromlist && IsLoadAll(fromList))
                {
                    mod.LoadNames();
                }

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