[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/pythonindy/pythonnet/master/pythonnet/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 bool initialized;

	#region Properties

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

	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) {
		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('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