8000 add a scope class to manage the context of interaction with Python an… by yagweb · Pull Request #381 · pythonnet/pythonnet · GitHub
[go: up one dir, main page]

Skip to content

add a scope class to manage the context of interaction with Python an… #381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jun 9, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rename several methods and add three methods
Referring to IronPython, change the name of the methods Get, Exists, SetLocal, DelLocal to GetVariable, ContainsVariable, SetVariable, RemoveVariable.
Hidden the methods SetGlobalVariable, RemoveGlobalVariable.
Add a new method 'Compile' to compile string into ast, the ast can be seen as the ScriptSource of IronPython.
Add two new methods 'Execute' and 'Execute<T>' to execute an ast and
obtain the result, corresponding to the 'Execute' method of IronPython.
  • Loading branch information
yagweb committed Apr 7, 2017
commit efd3798d5900ffe2e8681c937e99be320f7e8090
56 changes: 43 additions & 13 deletions src/embed_tests/pyscope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void TearDown()
[Test]
public void TestEval()
{
ps.SetLocal("a", 1);
ps.SetVariable("a", 1);
int result = ps.Eval<int>("a+2");
Assert.AreEqual(result, 3);
}
Expand All @@ -37,10 +37,40 @@ public void TestEval()
[Test]
public void TestExec()
{
ps.SetGlobal("bb", 100); //declare a global variable
ps.SetLocal("cc", 10); //declare a local variable
ps.SetVariable("bb", 100); //declare a global variable
ps.SetVariable("cc", 10); //declare a local variable
ps.Exec("aa=bb+cc+3");
int result = ps.Get<System.Int32>("aa");
int result = ps.GetVariable<System.Int32>("aa");
Assert.AreEqual(result, 113);
}

/// <summary>
/// Compile an expression into an ast object;
/// Execute the ast and obtain its return value.
/// </summary>
[Test]
public void TestCompileExpression()
{
ps.SetVariable("bb", 100); //declare a global variable
ps.SetVariable("cc", 10); //declare a local variable
var script = ps.Compile("bb+cc+3", "", CompileMode.Eval);
var result = ps.Execute<int>(script);
Assert.AreEqual(result, 113);
}

/// <summary>
/// Compile Python statements into an ast object;
/// Execute the ast;
/// Obtain the local variables created.
/// </summary>
[Test]
public void TestCompileStatements()
{
ps.SetVariable("bb", 100); //declare a global variable
ps.SetVariable("cc", 10); //declare a local variable
var script = ps.Compile("aa=bb+cc+3", "", CompileMode.File);
ps.Execute(script);
int result = ps.GetVariable<int>("aa");
Assert.AreEqual(result, 113);
}

Expand All @@ -50,16 +80,16 @@ public void TestExec()
[Test]
public void TestSubScope()
{
ps.SetGlobal("bb", 100); //declare a global variable
ps.SetLocal("cc", 10); //declare a local variable
ps.SetVariable("bb", 100); //declare a global variable
ps.SetVariable("cc", 10); //declare a local variable

PyScope scope = ps.SubScope();
scope.Exec("aa=bb+cc+3");
int result = scope.Get<System.Int32>("aa");
int result = scope.GetVariable<System.Int32>("aa");
Assert.AreEqual(result, 113); //
scope.Dispose();

Assert.IsFalse(ps.Exists("aa"));
Assert.IsFalse(ps.ContainsVariable("aa"));
}

/// <summary>
Expand All @@ -70,7 +100,7 @@ public void TestSubScope()
public void TestImport()
{
dynamic sys = ps.Import("sys");
Assert.IsTrue(ps.Exists("sys"));
Assert.IsTrue(ps.ContainsVariable("sys"));

ps.Exec("sys.attr1 = 2");
int value1 = ps.Eval<int>("sys.attr1");
Expand All @@ -87,7 +117,7 @@ public void TestImport()
public void TestImportAs()
{
ps.ImportAs("sys", "sys1");
Assert.IsTrue(ps.Exists("sys1"));
Assert.IsTrue(ps.ContainsVariable("sys1"));
}

/// <summary>
Expand All @@ -96,8 +126,8 @@ public void TestImportAs()
[Test]
public void TestSuspend()
{
ps.SetGlobal("bb", 100);
ps.SetLocal("cc", 10);
ps.SetVariable("bb", 100);
ps.SetVariable("cc", 10);
ps.Suspend();

using (Py.GIL())
Expand All @@ -106,7 +136,7 @@ public void TestSuspend()
}

ps.Exec("aa=bb+cc+3");
int result = ps.Get<System.Int32>("aa");
int result = ps.GetVariable<System.Int32>("aa");
Assert.AreEqual(result, 113);
}
}
Expand Down
68 changes: 56 additions & 12 deletions src/runtime/pythonengine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,13 @@ public class PySessionDisposedException: Exception

}

public enum CompileMode
{
Single = 256,
File = 257,
Eval = 258
}

public class PyScope : IDisposable
{
public class GILState : IDisposable
Expand Down Expand Up @@ -691,10 +698,47 @@ public PyObject ImportAs(string name, string asname)
{
asname = name;
}
SetLocal(asname, module);
SetVariable(asname, module);
return module;
}

public PyObject Execute(PyObject script)
{
IntPtr ptr = Runtime.PyEval_EvalCode(script.Handle, globals, locals);
Py.Throw();
if(ptr == Runtime.PyNone)
{
Runtime.XDecref(ptr);
return null;
}
return new PyObject(ptr);
}

public T Execute<T>(PyObject script)
{
var pyObj = this.Execute(script);
if(pyObj == null)
{
return default(T);
}
T obj = (T)pyObj.AsManagedObject(typeof(T));
return obj;
}

/// <summary>
/// Compile Method
/// </summary>
/// <remarks>
/// Compile Python expression/statements into ast.
/// </remarks>
public PyObject Compile(string code, string filename = "", CompileMode mode = CompileMode.File)
{
IntPtr flag = (IntPtr)mode;
IntPtr ptr = Runtime.Py_CompileString(code, filename, flag);
Py.Throw();
return new PyObject(ptr);
}

/// <summary>
/// Evaluate a Python expression
/// </summary>
Expand Down Expand Up @@ -751,15 +795,15 @@ private void Exec(string code, IntPtr _globals, IntPtr _locals)
}
Runtime.XDecref(ptr);
}

/// <summary>
/// SetGlobal Method
/// SetGlobalVariable Method
/// </summary>
/// <remarks>
/// Add a new variable to global variable dict if it not exists
/// or set the value of the global variable if it exists.
/// </remarks>
public void SetGlobal(string name, object value)
internal void SetGlobalVariable(string name, object value)
{
this.AcquireLock();
using (var pyKey = new PyString(name))
Expand All @@ -775,12 +819,12 @@ public void SetGlobal(string name, object value)
}

/// <summary>
/// DelGlobal Method
/// RemoveGlobalVariable Method
/// </summary>
/// <remarks>
/// Remove a variable from the global variable dict.
/// </remarks>
public void DelGlobal(string name)
internal void RemoveGlobalVariable(string name)
{
this.AcquireLock();
using (var pyKey = new PyString(name))
Expand All @@ -800,7 +844,7 @@ public void DelGlobal(string name)
/// Add a new variable to local variable dict if it not exists
/// or set the value of the local variable if it exists.
/// </remarks>
public void SetLocal(string name, object value)
public void SetVariable(string name, object value)
{
this.AcquireLock();
using (var pyKey = new PyString(name))
Expand All @@ -821,7 +865,7 @@ public void SetLocal(string name, object value)
/// <remarks>
/// Remove a variable from the local variable dict.
/// </remarks>
public void DelLocal(string name)
public void RemoveVariable(string name)
{
this.AcquireLock();
using (var pyKey = new PyString(name))
Expand All @@ -840,7 +884,7 @@ public void DelLocal(string name)
/// <remarks>
/// Returns true if the variable appears in the local variable dict or the global variable dict.
/// </remarks>
public bool Exists(string name)
public bool ContainsVariable(string name)
{
this.AcquireLock();
using (var pyKey = new PyString(name))
Expand All @@ -860,7 +904,7 @@ public bool Exists(string name)
/// Returns the value of the variable, local variable first.
/// If the variable is not exists, return null.
/// </remarks>
public PyObject Get(string name)
public PyObject GetVariable(string name)
{
this.AcquireLock();
using (var pyKey = new PyString(name))
Expand All @@ -886,9 +930,9 @@ public PyObject Get(string name)
}
}

public T Get<T>(string name)
public T GetVariable<T>(string name)
{
PyObject obj = this.Get(name);
PyObject obj = this.GetVariable(name);
return (T)obj.AsManagedObject(typeof(T));
}

Expand Down
7 changes: 6 additions & 1 deletion src/runtime/runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,12 @@ public static extern int Py_Main(
[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr PyRun_String(string code, IntPtr st, IntPtr globals, IntPtr locals);

[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl,
ExactSpelling = true, CharSet = CharSet.Ansi)]
internal unsafe static extern IntPtr
PyEval_EvalCode(IntPtr co, IntPtr globals, IntPtr locals);

[DllImport(PythonDll)]
internal static extern IntPtr Py_CompileString(string code, string file, IntPtr tok);

[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
Expand Down
0