-
Notifications
You must be signed in to change notification settings - Fork 762
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
Changes from 1 commit
8e0b1a2
72003aa
efd3798
9f50e25
add5ba8
c15555c
b0d57e9
ceaaef0
dec39c7
e117d60
904d9ed
5484451
2e063c2
dd492f4
df6a49a
f35d75b
497d7aa
60ce28b
ebf5a2b
2c3db3d
30543eb
b9dcdac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -125,6 +125,37 @@ public void TestScopeFunction() | |
} | ||
} | ||
|
||
/// <summary> | ||
/// Create a class in the scope, the class can read variables in the scope. | ||
/// Its methods can write the variables with the help of 'global' keyword. | ||
/// </summary> | ||
[Test] | ||
public void TestScopeClass() | ||
{ | ||
using (Py.GIL()) | ||
{ | ||
dynamic _ps = ps; | ||
_ps.bb = 100; | ||
ps.Exec( | ||
"class class1():\n" + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should read There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Revised. |
||
" def __init__(self, value):\n" + | ||
" self.value = value\n" + | ||
" def call(self, arg):\n" + | ||
" return self.value + bb + arg\n" + //use scope variables | ||
" def update(self, arg):\n" + | ||
" global bb\n" + | ||
" bb = self.value + arg\n" //update scope variable | ||
); | ||
dynamic obj1 = _ps.class1(20); | ||
var result = obj1.call(10).AsManagedObject(typeof(int)); | ||
Assert.AreEqual(130, result); | ||
|
||
obj1.update(10); | ||
result = ps.GetVariable<int>("bb"); | ||
Assert.AreEqual(30, result); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Import a python module into the session. | ||
/// Equivalent to the Python "import" statement. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,9 @@ public PyScopeException(string message) | |
} | ||
} | ||
|
||
/// <summary> | ||
/// Classes implement this interface must be used with GIL obtained. | ||
/// </summary> | ||
public interface IPyObject : IDisposable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very weird naming for what you are trying to mark here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace this interface with Attritue or just remove it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Attribute would make more sense, yes. Could allow us to test this at least at runtime. |
||
{ | ||
} | ||
|
@@ -38,6 +41,8 @@ internal PyScope(string name) | |
variables, "__builtins__", | ||
Runtime.PyEval_GetBuiltins() | ||
); | ||
SetVariable("locals", (Func<PyDict>)Variables); | ||
SetVariable("globals", (Func<PyDict>)Variables); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As said before, I'm strongly against this. I don't see any advantage in this over separating There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the responses below. |
||
} | ||
|
||
/// <summary> | ||
|
@@ -47,6 +52,11 @@ internal PyScope(string name) | |
|
||
public event Action<PyScope> OnDispose; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the use-case for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PyScopes are managed by Py class, when it was disposed, Py class can do some cleaning work through registering this event. In the future, methods in Py class maybe put in an independent ScopeManager class, see the responses below. |
||
|
||
public PyDict Variables() | ||
{ | ||
return new PyDict(variables); | ||
} | ||
|
||
public PyScope CreateScope() | ||
{ | ||
var scope = new PyScope(null); | ||
|
@@ -276,17 +286,26 @@ private PyObject _GetVariable(string name) | |
public PyObject GetVariable(string name) | ||
{ | ||
Check(); | ||
var variable = _GetVariable(name); | ||
if (variable == null) | ||
{ | ||
throw new PyScopeException(String.Format("'ScopeStorage' object has no attribute '{0}'", name)); | ||
} | ||
if (variable.Handle == Runtime.PyNone) | ||
using (var pyKey = new PyString(name)) | ||
{ | ||
variable.Dispose(); | ||
return null; | ||
if (Runtime.PyMapping_HasKey(variables, pyKey.obj) != 0) | ||
{ | ||
IntPtr op = Runtime.PyObject_GetItem(variables, pyKey.obj); | ||
if (op == IntPtr.Zero) | ||
{ | ||
throw new PythonException(); | ||
} | ||
if (op == Runtime.PyNone) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaks a reference. Also, I'm not sure whether this is the right place for this conversion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed. |
||
{ | ||
return null; | ||
} | ||
return new PyObject(op); | ||
} | ||
else | ||
{ | ||
throw new PyScopeException(String.Format("'ScopeStorage' object has no attribute '{0}'", name)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a weird error message. Also, why is this not implemented in terms of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be compatible with IronPython, see the responses below. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have no compatibility with IronPython here anyhow. |
||
} | ||
} | ||
return variable; | ||
} | ||
|
||
/// <summary> | ||
|
@@ -299,19 +318,29 @@ public PyObject GetVariable(string name) | |
public bool TryGetVariable(string name, out PyObject value) | ||
{ | ||
Check(); | ||
var variable = _GetVariable(name); | ||
if (variable == null) | ||
{ | ||
value = null; | ||
return false; | ||
} | ||
if (variable.Handle == Runtime.PyNone) | ||
using (var pyKey = new PyString(name)) | ||
{ | ||
value = null; | ||
return true; | ||
if (Runtime.PyMapping_HasKey(variables, pyKey.obj) != 0) | ||
{ | ||
IntPtr op = Runtime.PyObject_GetItem(variables, pyKey.obj); | ||
if (op == IntPtr.Zero) | ||
{ | ||
throw new PythonException(); | ||
} | ||
if (op == Runtime.PyNone) | ||
{ | ||
value = null; | ||
return true; | ||
} | ||
value = new PyObject(op); | ||
return true; | ||
} | ||
else | ||
{ | ||
value = null; | ||
return false; | ||
} | ||
} | ||
value = variable; | ||
return true; | ||
} | ||
|
||
public T GetVariable<T>(string name) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this dynamic scope necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, I see below, you dynamically accessed the class