Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 904d9ed

Browse files
committed
add a Variables method
1 parent e117d60 commit 904d9ed

File tree

2 files changed

+80
-20
lines changed

2 files changed

+80
-20
lines changed

src/embed_tests/TestPyScope.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,37 @@ public void TestScopeFunction()
125125
}
126126
}
127127

128+
/// <summary>
129+
/// Create a class in the scope, the class can read variables in the scope.
130+
/// Its methods can write the variables with the help of 'global' keyword.
131+
/// </summary>
132+
[Test]
133+
public void TestScopeClass()
134+
{
135+
using (Py.GIL())
136+
{
137+
dynamic _ps = ps;
138+
_ps.bb = 100;
139+
ps.Exec(
140+
"class class1():\n" +
141+
" def __init__(self, value):\n" +
142+
" self.value = value\n" +
143+
" def call(self, arg):\n" +
144+
" return self.value + bb + arg\n" + //use scope variables
145+
" def update(self, arg):\n" +
146+
" global bb\n" +
147+
" bb = self.value + arg\n" //update scope variable
148+
);
149+
dynamic obj1 = _ps.class1(20);
150+
var result = obj1.call(10).AsManagedObject(typeof(int));
151+
Assert.AreEqual(130, result);
152+
153+
obj1.update(10);
154+
result = ps.GetVariable<int>("bb");
155+
Assert.AreEqual(30, result);
156+
}
157+
}
158+
128159
/// <summary>
129160
/// Import a python module into the session.
130161
/// Equivalent to the Python "import" statement.

src/runtime/pyscope.cs

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ public PyScopeException(string message)
1212
}
1313
}
1414

15+
/// <summary>
16+
/// Classes implement this interface must be used with GIL obtained.
17+
/// </summary>
1518
public interface IPyObject : IDisposable
1619
{
1720
}
@@ -38,6 +41,8 @@ internal PyScope(string name)
3841
variables, "__builtins__",
3942
Runtime.PyEval_GetBuiltins()
4043
);
44+
SetVariable("locals", (Func<PyDict>)Variables);
45+
SetVariable("globals", (Func<PyDict>)Variables);
4146
}
4247

4348
/// <summary>
@@ -47,6 +52,11 @@ internal PyScope(string name)
4752

4853
public event Action<PyScope> OnDispose;
4954

55+
public PyDict Variables()
56+
{
57+
return new PyDict(variables);
58+
}
59+
5060
public PyScope CreateScope()
5161
{
5262
var scope = new PyScope(null);
@@ -276,17 +286,26 @@ private PyObject _GetVariable(string name)
276286
public PyObject GetVariable(string name)
277287
{
278288
Check();
279-
var variable = _GetVariable(name);
280-
if (variable == null)
281-
{
282-
throw new PyScopeException(String.Format("'ScopeStorage' object has no attribute '{0}'", name));
283-
}
284-
if (variable.Handle == Runtime.PyNone)
289+
using (var pyKey = new PyString(name))
285290
{
286-
variable.Dispose();
287-
return null;
291+
if (Runtime.PyMapping_HasKey(variables, pyKey.obj) != 0)
292+
{
293+
IntPtr op = Runtime.PyObject_GetItem(variables, pyKey.obj);
294+
if (op == IntPtr.Zero)
295+
{
296+
throw new PythonException();
297+
}
298+
if (op == Runtime.PyNone)
299+
{
300+
return null;
301+
}
302+
return new PyObject(op);
303+
}
304+
else
305+
{
306+
throw new PyScopeException(String.Format("'ScopeStorage' object has no attribute '{0}'", name));
307+
}
288308
}
289-
return variable;
290309
}
291310

292311
/// <summary>
@@ -299,19 +318,29 @@ public PyObject GetVariable(string name)
299318
public bool TryGetVariable(string name, out PyObject value)
300319
{
301320
Check();
302-
var variable = _GetVariable(name);
303-
if (variable == null)
304-
{
305-
value = null;
306-
return false;
307-
}
308-
if (variable.Handle == Runtime.PyNone)
321+
using (var pyKey = new PyString(name))
309322
{
310-
value = null;
311-
return true;
323+
if (Runtime.PyMapping_HasKey(variables, pyKey.obj) != 0)
324+
{
325+
IntPtr op = Runtime.PyObject_GetItem(variables, pyKey.obj);
326+
if (op == IntPtr.Zero)
327+
{
328+
throw new PythonException();
329+
}
330+
if (op == Runtime.PyNone)
331+
{
332+
value = null;
333+
return true;
334+
}
335+
value = new PyObject(op);
336+
return true;
337+
}
338+
else
339+
{
340+
value = null;
341+
return false;
342+
}
312343
}
313-
value = variable;
314-
return true;
315344
}
316345

317346
public T GetVariable<T>(string name)

0 commit comments

Comments
 (0)