8000 fixup! add a scope class to manage the context of interaction with Py… · pythonnet/pythonnet@69598cf · GitHub
[go: up one dir, main page]

Skip to content

Commit 69598cf

Browse files
committed
fixup! add a scope class to manage the context of interaction with Python and simplify the variable exchanging
1 parent c65d1d0 commit 69598cf

File tree

2 files changed

+70
-70
lines changed

2 files changed

+70
-70
lines changed

src/embed_tests/pyscope.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public PyScopeTest()
1717
[SetUp]
1818
public void SetUp()
1919
{
20-
ps = session.Scope();
20+
ps = session.SubScope();
2121
}
2222

2323
[TearDown]
@@ -48,23 +48,25 @@ public void TestExec()
4848
}
4949

5050
[Test]
51-
public void TestExecIn()
51+
public void TestSubScope()
5252
{
5353
ps.SetGlobal("bb", 100); //declare a global variable
5454
ps.SetLocal("cc", 10); //declare a local variable
55-
ps.ExecIn("aa=bb+cc+3");
56-
PyInt result = PyInt.AsInt(ps.Get("aa") as PyObject);
57-
Assert.AreEqual(result.ToInt32(), 113);
55+
56+
PyScope scope = ps.SubScope();
57+
scope.Exec("aa=bb+cc+3");
58+
int result = scope.Get<System.Int32>("aa");
59+
Assert.AreEqual(result, 113); //
60+
scope.Dispose();
61+
62+
Assert.IsFalse(ps.Exists("aa"));
5863
}
5964

6065
[Test]
6166
public void TestImport()
6267
{
63-
ps.SetGlobal("bb", 100); //declare a global variable
64-
ps.SetLocal("cc", 10); //declare a local variable
65-
ps.ExecIn("aa=bb+cc+3");
66-
PyInt result = PyInt.AsInt(ps.Get("aa") as PyObject);
67-
Assert.AreEqual(result.ToInt32(), 113);
68+
ps.Import("sys", "sys1");
69+
Assert.IsTrue(ps.Exists("sys1"));
6870
}
6971

7072
[Test]
@@ -78,7 +80,7 @@ public void TestSuspend()
7880
{
7981
PythonEngine.RunSimpleString("import sys;");
8082
}
81-
ps.ExecIn("aa=bb+cc+3");
83+
ps.Exec("aa=bb+cc+3");
8284
int result = ps.Get<System.Int32>("aa");
8385
Assert.AreEqual(result, 113);
8486
}

src/runtime/pythonengine.cs

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -511,16 +511,6 @@ public void Dispose()
511511

512512
private GILState state;
513513

514-
/// <summary>
515-
/// the dict for global variables
516-
/// </summary>
517-
private IntPtr globals;
518-
519-
/// <summary>
520-
/// the dict for local variables
521-
/// </summary>
522-
private IntPtr locals;
523-
524514
internal PyScope()
525515
: this(null, new GILState())
526516
{
@@ -536,18 +526,52 @@ internal PyScope(PyScope parent, GILState state)
536526
{
537527
throw new PythonException();
538528
}
539-
Runtime.PyDict_SetItemString(
540-
globals, "__builtins__",
541-
Runtime.PyEval_GetBuiltins()
542-
);
543529
locals = Runtime.PyDict_New();
544530
if (locals == IntPtr.Zero)
545531
{
546532
throw new PythonException();
547533
}
534+
if(parent == null)
535+
{
536+
Runtime.PyDict_SetItemString(
537+
globals, "__builtins__",
538+
Runtime.PyEval_GetBuiltins()
539+
);
540+
}
541+
else
542+
{
543+
int result = Runtime.PyDict_Update(globals, parent.globals);
544+
if (result < 0)
545+
{
546+
throw new PythonException();
547+
}
548+
result = Runtime.PyDict_Update(globals, parent.locals);
549+
if (result < 0)
550+
{
551+
throw new PythonException();
552+
}
553+
}
554+
}
555+
556+
/// <summary>
557+
/// the dict for global variables
558+
/// </summary>
559+
public IntPtr globals
560+
{
561+
get;
562+
private set;
563+
}
564+
565+
/// <summary>
566+
/// the dict for local variables
567+
/// </summary>
568+
public IntPtr locals
569+
{
570+
get;
571+
private set;
548572
}
549573

550-
public PyScope Scope()
574+
public PyScope SubScope()
551575
{
552576
return new PyScope(this, this.state);
553577
}
@@ -558,18 +582,21 @@ public void Suspend()
558582
}
559583

560584
/// <summary>
561-
/// ImportModule Method
585+
/// Import Method
562586
/// </summary>
563587
/// <remarks>
564-
/// Given a fully-qualified module or package name, import the
565-
/// module , add it to the global variable dict and return the resulting module object as a PyObject
566-
/// or null if an exception is raised.
588+
/// The import .. as .. statement in Python.
589+
/// Import a module ,add it to the local variable dict and return the resulting module object as a PyObject.
567590
/// </remarks>
568-
public PyObject Import(string name)
591+
public PyObject Import(string name, string asname = null)
569592
{
570593
this.state.AcquireLock();
571594
PyObject module = PythonEngine.ImportModule(name);
572-
SetGlobal(name, module);
595+
if(asname == null)
596+
{
597+
asname = name;
598+
}
599+
SetLocal(asname, module);
573600
return module;
574601
}
575602

@@ -592,28 +619,22 @@ public PyObject Eval(string code)
592619
}
593620

594621
/// <summary>
595-
/// ExecIn Method
622+
/// Exec Method
596623
/// </summary>
597624
/// <remarks>
598-
/// Evaluate a Python script and save its local variables in local variable dict.
625+
/// Evaluate a Python script and save its local variables in the current local variable dict.
599626
/// </remarks>
600-
public void ExecIn(string code)
627+
public void Exec(string code)
601628
{
602-
Exec(code, locals);
629+
this.state.AcquireLock();
630+
Exec(code, this.globals, this.locals);
603631
}
604-
605-
/// <summary>
606-
/// ExecIn Method
607-
/// </summary>
608-
/// <remarks>
609-
/// Evaluate a Python script and save its local variables in local variable dict.
610-
/// </remarks>
611-
private void Exec(string code, IntPtr _locals)
632+
633+
private void Exec(string code, IntPtr _globals, IntPtr _locals)
612634
{
613-
this.state.AcquireLock();
614635
var flag = (IntPtr)Runtime.Py_file_input;
615636
IntPtr ptr = Runtime.PyRun_String(
616-
code, flag, globals, locals
637+
code, flag, _globals, _locals
617638
);
618639
Py.Throw();
619640
if (ptr != Runtime.PyNone)
@@ -622,30 +643,7 @@ private void Exec(string code, IntPtr _locals)
622643
}
623644
Runtime.XDecref(ptr);
624645
}
625-
626-
/// <summary>
627-
/// Exec Method
628-
/// </summary>
629-
/// <remarks>
630-
/// Evaluate a Python script and discard its local variables.
631-
/// </remarks>
632-
public void Exec(string code)
633-
{
634-
this.state.AcquireLock();
635-
IntPtr _locals = Runtime.PyDict_New();
636-
if (_locals == IntPtr.Zero)
637-
{
638-
throw new PythonException();
639-
}
640-
int result = Runtime.PyDict_Update(_locals, locals);
641-
if (result < 0)
642-
{
643-
throw new PythonException();
644-
}
645-
Exec(code, _locals);
646-
Runtime.XDecref(_locals);
647-
}
648-
646+
649647
/// <summary>
650648
/// SetGlobal Method
651649
/// </summary>

0 commit comments

Comments
 (0)
0