[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/achernet/pythonnet/develop/src/runtime/pythonengine.cs [Back]  [Original]

// ==========================================================================
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.
// ==========================================================================

using System;
using System.Threading;

namespace Python.Runtime {

    /// 
    /// This class provides the public interface of the Python runtime.
    /// 

    public class PythonEngine {

        private static DelegateManager delegateManager;
        private static bool initialized;

        #region Properties

        public static bool IsInitialized {
            get {
                return initialized;
            }
        }

        internal static DelegateManager DelegateManager {
            get {
                if (delegateManager == null) {
                    throw new InvalidOperationException("DelegateManager has not yet been initialized using Python.Runtime.PythonEngine.Initialize().");
                }
                return delegateManager;
            }
        }

        public static string ProgramName {
            get {
                string result = Runtime.Py_GetProgramName();
                if (result == null) {
                    return "";
                }
                return result;
            }
            set {
                Runtime.Py_SetProgramName(value);
            }
        }

        public static string PythonHome {
            get {
                string result = Runtime.Py_GetPythonHome();
                if (result == null) {
                    return "";
                }
                return result;
            }
            set {
                Runtime.Py_SetPythonHome(value);
            }
        }

        public static string Version {
            get { 
                return Runtime.Py_GetVersion(); 
            }
        }

        public static string BuildInfo {
            get { 
                return Runtime.Py_GetBuildInfo(); 
            }
        }

        public static string Platform {
            get { 
                return Runtime.Py_GetPlatform(); 
            }
        }

        public static string Copyright {
            get { 
                return Runtime.Py_GetCopyright(); 
            }
        }

        public static int RunSimpleString(string code) {
            return Runtime.PyRun_SimpleString(code);
        }

        #endregion


        /// 
        /// Initialize Method
        /// 
        ///
        /// 
        /// Initialize the Python runtime. It is safe to call this method 
        /// more than once, though initialization will only happen on the 
        /// first call. It is *not* necessary to hold the Python global
        /// interpreter lock (GIL) to call this method.
        /// 

        public static void Initialize() {
            if (!initialized) {
                // Creating the delegateManager MUST happen before Runtime.Initialize
                // is called. If it happens afterwards, DelegateManager's CodeGenerator
                // throws an exception in its ctor.  This exception is eaten somehow
                // during an initial "import clr", and the world ends shortly thereafter.
                // This is probably masking some bad mojo happening somewhere in Runtime.Initialize().
                delegateManager = new DelegateManager();
                Runtime.Initialize();
                initialized = true;
                Exceptions.Clear();
            }
        }


        //====================================================================
        // A helper to perform initialization from the context of an active
        // CPython interpreter process - this bootstraps the managed runtime
        // when it is imported by the CLR extension module.
        //====================================================================

        public static void InitExt() {
            Initialize();

            // Trickery - when the import hook is installed into an already
            // running Python, the standard import machinery is still in 
            // control for the duration of the import that caused bootstrap.
            // 
            // That is problematic because the std machinery tries to get
            // sub-names directly from the module __dict__ rather than going
            // through our module object's getattr hook. This workaround is
            // evil ;) We essentially climb up the stack looking for the
            // import that caused the bootstrap to happen, then re-execute
            // the import explicitly after our hook has been installed. By
            // doing this, the original outer import should work correctly.
            //
            // Note that this is only needed during the execution of the
            // first import that installs the CLR import hook. This hack
            // still doesn't work if you use the interactive interpreter,
            // since there is no line info to get the import line ;(

            string code = 

            "import traceback\n" + 
            "for item in traceback.extract_stack():\n" + 
            "    line = item[3]\n" + 
            "    if line is not None:\n" +
            "        if line.startswith('import CLR') or \\\n" +
            "           line.startswith('import clr') or \\\n" +
            "           line.startswith('from clr') or \\\n" + 
            "           line.startswith('from CLR'):\n" + 
            "            exec line\n" + 
            "            break\n";            

            PyObject r = PythonEngine.RunString(code);
            if (r != null) {
                r.Dispose();
            }
        }


        /// 
        /// Shutdown Method
        /// 
        ///
        /// 
        /// Shutdown and release resources held by the Python runtime. The
        /// Python runtime can no longer be used in the current process
        /// after calling the Shutdown method.
        /// 

        public static void Shutdown() {
            if (initialized) {
                Runtime.Shutdown();
                initialized = false;
            }
        }


        /// 
        /// AcquireLock Method
        /// 
        ///
        /// 
        /// Acquire the Python global interpreter lock (GIL). Managed code
        /// *must* call this method before using any objects or calling any
        /// methods on objects in the Python.Runtime namespace. The only 
        /// exception is PythonEngine.Initialize, which may be called without
        /// first calling AcquireLock.
        ///
        /// Each call to AcquireLock must be matched by a corresponding call
        /// to ReleaseLock, passing the token obtained from AcquireLock.
        /// 
        /// For more information, see the "Extending and Embedding" section
        /// of the Python documentation on www.python.org.
        /// 

        public static IntPtr AcquireLock() {
            return Runtime.PyGILState_Ensure();
        }


        /// 
        /// ReleaseLock Method
        /// 
        ///
        /// 
        /// Release the Python global interpreter lock using a token obtained
        /// from a previous call to AcquireLock.
        /// 
        /// For more information, see the "Extending and Embedding" section
        /// of the Python documentation on www.python.org.
        /// 
        
        public static void ReleaseLock(IntPtr gs) {
            Runtime.PyGILState_Release(gs);
        }


        /// 
        /// BeginAllowThreads Method
        /// 
        ///
        /// 
        /// Release the Python global interpreter lock to allow other threads
        /// to run. This is equivalent to the Py_BEGIN_ALLOW_THREADS macro
        /// provided by the C Python API.
        /// 
        /// For more information, see the "Extending and Embedding" section
        /// of the Python documentation on www.python.org.
        /// 
        
        public static IntPtr BeginAllowThreads() {
            return Runtime.PyEval_SaveThread();
        }


        /// 
        /// EndAllowThreads Method
        /// 
        ///
        /// 
        /// Re-aquire the Python global interpreter lock for the current
        /// thread. This is equivalent to the Py_END_ALLOW_THREADS macro
        /// provided by the C Python API.
        /// 
        /// For more information, see the "Extending and Embedding" section
        /// of the Python documentation on www.python.org.
        /// 
        
        public static void EndAllowThreads(IntPtr ts) {
            Runtime.PyEval_RestoreThread(ts);
        }


        /// 
        /// ImportModule Method
        /// 
        ///
        /// 
        /// Given a fully-qualified module or package name, import the
        /// module and return the resulting module object as a PyObject 
        /// or null if an exception is raised.
        /// 

        public static PyObject ImportModule(string name) {
            IntPtr op = Runtime.PyImport_ImportModule(name);
            if (op == IntPtr.Zero) {
                return null;
            }
            return new PyObject(op);
        }


        /// 
        /// ReloadModule Method
        /// 
        ///
        /// 
        /// Given a PyObject representing a previously loaded module, reload
        /// the module.
        /// 

        public static PyObject ReloadModule(PyObject module) {
            IntPtr op = Runtime.PyImport_ReloadModule(module.Handle);
            if (op == IntPtr.Zero) {
                throw new PythonException();
            }
            return new PyObject(op);
        }


        /// 
        /// ModuleFromString Method
        /// 
        ///
        /// 
        /// Given a string module name and a string containing Python code,
        /// execute the code in and return a module of the given name.
        /// 

        public static PyObject ModuleFromString(string name, string code) {
            IntPtr c = Runtime.Py_CompileString(code, "none", (IntPtr)257);
            if (c == IntPtr.Zero) {
                throw new PythonException();
            }
            IntPtr m = Runtime.PyImport_ExecCodeModule(name, c);
            if (m == IntPtr.Zero) {
                throw new PythonException();
            }
            return new PyObject(m);
        }


        /// 
        /// RunString Method
        /// 
        ///
        /// 
        /// 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.
        /// 

        public static PyObject RunString(string code) {
            IntPtr globals = Runtime.PyEval_GetGlobals();
            IntPtr locals = Runtime.PyDict_New();

            IntPtr builtins = Runtime.PyEval_GetBuiltins();
            Runtime.PyDict_SetItemString(locals, "__builtins__", builtins);

            IntPtr flag = (IntPtr)257; /* Py_file_input */
            IntPtr result = Runtime.PyRun_String(code, flag, globals, locals);
            Runtime.Decref(locals);
            if (result == IntPtr.Zero) {
                return null;
            }
            return new PyObject(result);
        }


    }


}

Web Proxy Viewer  |  New URL  |  Original Page