diff --git a/src/embed_tests/Python.EmbeddingTest.csproj b/src/embed_tests/Python.EmbeddingTest.csproj index 1b015136d..f943ca787 100644 --- a/src/embed_tests/Python.EmbeddingTest.csproj +++ b/src/embed_tests/Python.EmbeddingTest.csproj @@ -86,6 +86,7 @@ + diff --git a/src/embed_tests/pyrunstring.cs b/src/embed_tests/pyrunstring.cs new file mode 100644 index 000000000..b17bb87f8 --- /dev/null +++ b/src/embed_tests/pyrunstring.cs @@ -0,0 +1,61 @@ +using System; +using NUnit.Framework; +using Python.Runtime; + +namespace Python.EmbeddingTest +{ + public class RunStringTest + { + private Py.GILState gil; + + [SetUp] + public void SetUp() + { + gil = Py.GIL(); + } + + [TearDown] + public void Dispose() + { + gil.Dispose(); + } + + [Test] + public void TestRunSimpleString() + { + int aa = PythonEngine.RunSimpleString("import sys"); + Assert.AreEqual(0, aa); + + int bb = PythonEngine.RunSimpleString("import 1234"); + Assert.AreEqual(-1, bb); + } + + [Test] + public void TestEval() + { + dynamic sys = Py.Import("sys"); + sys.attr1 = 100; + var locals = new PyDict(); + locals.SetItem("sys", sys); + locals.SetItem("a", new PyInt(10)); + + object b = PythonEngine.Eval("sys.attr1 + a + 1", null, locals.Handle) + .AsManagedObject(typeof(int)); + Assert.AreEqual(111, b); + } + + [Test] + public void TestExec() + { + dynamic sys = Py.Import("sys"); + sys.attr1 = 100; + var locals = new PyDict(); + locals.SetItem("sys", sys); + locals.SetItem("a", new PyInt(10)); + + PythonEngine.Exec("c = sys.attr1 + a + 1", null, locals.Handle); + object c = locals.GetItem("c").AsManagedObject(typeof(int)); + Assert.AreEqual(111, c); + } + } +} diff --git a/src/runtime/pythonengine.cs b/src/runtime/pythonengine.cs index e9fa888a9..accd349c5 100644 --- a/src/runtime/pythonengine.cs +++ b/src/runtime/pythonengine.cs @@ -156,11 +156,7 @@ public static void Initialize(IEnumerable args) string code = "import atexit, clr\n" + "atexit.register(clr._AtExit)\n"; - PyObject r = PythonEngine.RunString(code); - if (r != null) - { - r.Dispose(); - } + PythonEngine.Exec(code); // Load the clr.py resource into the clr module IntPtr clr = Python.Runtime.ImportHook.GetCLRModule(); @@ -180,12 +176,7 @@ public static void Initialize(IEnumerable args) { // add the contents of clr.py to the module string clr_py = reader.ReadToEnd(); - PyObject result = RunString(clr_py, module_globals, locals.Handle); - if (null == result) - { - throw new PythonException(); - } - result.Dispose(); + Exec(clr_py, module_globals, locals.Handle); } // add the imported module to the clr module, and copy the API functions @@ -253,11 +244,7 @@ public static void InitExt() " exec(line)\n" + " break\n"; - PyObject r = PythonEngine.RunString(code); - if (r != null) - { - r.Dispose(); - } + PythonEngine.Exec(code); } catch (PythonException e) { @@ -405,6 +392,38 @@ public static PyObject ModuleFromString(string name, string code) } + /// + /// Eval Method + /// + /// + /// Evaluate a Python expression and returns the result. + /// It's a subset of Python eval function. + /// + public static PyObject Eval(string code, IntPtr? globals = null, IntPtr? locals = null) + { + PyObject result = RunString(code, globals, locals, RunFlagType.Eval); + return result; + } + + + /// + /// Exec Method + /// + /// + /// Run a string containing Python code. + /// It's a subset of Python exec function. + /// + public static void Exec(string code, IntPtr? globals = null, IntPtr? locals = null) + { + PyObject result = RunString(code, globals, locals, RunFlagType.File); + if (result.obj != Runtime.PyNone) + { + throw new PythonException(); + } + result.Dispose(); + } + + /// /// RunString Method /// @@ -414,7 +433,7 @@ public static PyObject ModuleFromString(string name, string code) /// an exception was raised. /// public static PyObject RunString( - string code, IntPtr? globals = null, IntPtr? locals = null + string code, IntPtr? globals = null, IntPtr? locals = null, RunFlagType _flag = RunFlagType.File ) { var borrowedGlobals = true; @@ -439,7 +458,7 @@ public static PyObject RunString( borrowedLocals = false; } - var flag = (IntPtr)257; /* Py_file_input */ + var flag = (IntPtr)_flag; try { @@ -465,6 +484,13 @@ public static PyObject RunString( } } + public enum RunFlagType + { + Single = 256, + File = 257, /* Py_file_input */ + Eval = 258 + } + public static class Py { public static GILState GIL()