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

Skip to content

Commit f35d75b

Browse files
committed
add a new class PyScopeManager
1 parent df6a49a commit f35d75b

File tree

4 files changed

+77
-55
lines changed

4 files changed

+77
-55
lines changed

src/embed_tests/TestPyScope.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ public void TestVariables()
306306
var a2 = ps.GetVariable<int>("ee");
307307
Assert.AreEqual(220, a2);
308308

309-
var item = (ps as dynamic).locals();
309+
var item = ps.Variables();
310310
item["ee"] = new PyInt(230);
311311
item.Dispose();
312312
var a3 = ps.GetVariable<int>("ee");

src/runtime/pyscope.cs

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ public PyScopeException(string message)
1515
}
1616

1717
/// <summary>
18-
/// Classes implement this interface must be used with GIL obtained.
18+
/// Classes/methods have this attribute must be used with GIL obtained.
1919
/// </summary>
20-
public interface IPyObject : IDisposable
20+
public class PyGILAttribute : Attribute
2121
{
2222
}
2323

24-
public class PyScope : DynamicObject, IPyObject
24+
[PyGIL]
25+
public class PyScope : DynamicObject, IDisposable
2526
{
2627
public readonly string Name;
2728

@@ -33,6 +34,10 @@ public class PyScope : DynamicObject, IPyObject
3334
internal readonly IntPtr variables;
3435

3536
private bool isDisposed;
37+
38+
internal PyScopeManager Manager;
39+
40+
public event Action<PyScope> OnDispose;
3641

3742
internal static PyScope New(string name = null)
3843
{
@@ -64,8 +69,6 @@ private PyScope(IntPtr ptr)
6469
this.Name = this.GetVariable<string>("__name__");
6570
}
6671

67-
public event Action<PyScope> OnDispose;
68-
6972
public PyDict Variables()
7073
{
7174
Runtime.XIncref(variables);
@@ -81,7 +84,7 @@ public PyScope NewScope()
8184

8285
public void ImportAllFromScope(string name)
8386
{
84-
var scope = Py.GetScope(name);
87+
var scope = Manager.Get(name);
8588
ImportAllFromScope(scope);
8689
}
8790

@@ -96,7 +99,7 @@ public void ImportAllFromScope(PyScope scope)
9699

97100
public void ImportScope(string name, string asname = null)
98101
{
99-
var scope = Py.GetScope(name);
102+
var scope = Manager.Get(name);
100103
if(asname == null)
101104
{
102105
asname = name;
@@ -436,4 +439,64 @@ public void Dispose()
436439
Dispose();
437440
}
438441
}
442+
443+
public class PyScopeManager
444+
{
445+
private Dictionary<string, PyScope> NamedScopes = new Dictionary<string, PyScope>();
446+
447+
[PyGIL]
448+
public PyScope Create()
449+
{
450+
var scope = PyScope.New();
451+
scope.Manager = this;
452+
return scope;
453+
}
454+
455+
[PyGIL]
456+
public PyScope Create(string name)
457+
{
458+
if (String.IsNullOrEmpty(name))
459+
{
460+
throw new PyScopeException("Name of ScopeStorage must not be empty");
461+
}
462+
if (name != null && NamedScopes.ContainsKey(name))
463+
{
464+
throw new PyScopeException(String.Format("ScopeStorage '{0}' has existed", name));
465+
}
466+
var scope = PyScope.New(name);
467+
scope.Manager = this;
468+
scope.OnDispose += Remove;
469+
NamedScopes[name] = scope;
470+
return scope;
471+
}
472+
473+
public bool Contains(string name)
474+
{
475+
return NamedScopes.ContainsKey(name);
476+
}
477+
478+
public PyScope Get(string name)
479+
{
480+
if (name != null && NamedScopes.ContainsKey(name))
481+
{
482+
return NamedScopes[name];
483+
}
484+
throw new PyScopeException(String.Format("ScopeStorage '{0}' not exist", name));
485+
}
486+
487+
public void Remove(PyScope scope)
488+
{
489+
NamedScopes.Remove(scope.Name);
490+
}
491+
492+
[PyGIL]
493+
public void Clear()
494+
{
495+
var scopes = NamedScopes.Values.ToList();
496+
foreach (var scope in scopes)
497+
{
498+
scope.Dispose();
499+
}
500+
}
501+
}
439502
}

src/runtime/pythonengine.cs

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ public static void Shutdown()
294294
{
295295
if (initialized)
296296
{
297-
Py.ClearScopes();
297+
Py.PyScopeManager.Clear();
298298
Marshal.FreeHGlobal(_pythonHome);
299299
_pythonHome = IntPtr.Zero;
300300
Marshal.FreeHGlobal(_programName);
@@ -547,61 +547,20 @@ public static GILState GIL()
547547
return new GILState();
548548
}
549549

550-
private static Dictionary<string, PyScope> NamedScopes = new Dictionary<string, PyScope>();
550+
internal static PyScopeManager PyScopeManager = new PyScopeManager();
551551

552552
public static PyScope CreateScope()
553553
{
554-
var scope = PyScope.New();
554+
var scope = PyScopeManager.Create();
555555
return scope;
556556
}
557557

558558
public static PyScope CreateScope(string name)
559559
{
560-
if (String.IsNullOrEmpty(name))
561-
{
562-
throw new PyScopeException("Name of ScopeStorage must not be empty");
563-
}
564-
if (name != null && NamedScopes.ContainsKey(name))
565-
{
566-
throw new PyScopeException(String.Format("ScopeStorage '{0}' has existed", name));
567-
}
568-
var scope = PyScope.New(name);
569-
if (name != null)
570-
{
571-
NamedScopes[name] = scope;
572-
scope.OnDispose += RemoveScope;
573-
}
560+
var scope = PyScopeManager.Create(name);
574561
return scope;
575562
}
576563

577-
public static bool ContainsScope(string name)
578-
{
579-
return NamedScopes.ContainsKey(name);
580-
}
581-
582-
public static PyScope GetScope(string name)
583-
{
584-
if (name != null && NamedScopes.ContainsKey(name))
585-
{
586-
return NamedScopes[name];
587-
}
588-
throw new PyScopeException(String.Format("ScopeStorage '{0}' not exist", name));
589-
}
590-
591-
internal static void RemoveScope(PyScope scope)
592-
{
593-
NamedScopes.Remove(scope.Name);
594-
}
595-
596-
internal static void ClearScopes()
597-
{
598-
var scopes = NamedScopes.Values.ToList();
599-
foreach (var scope in scopes)
600-
{
601-
scope.Dispose();
602-
}
603-
}
604-
605564
public class GILState : IDisposable
606565
{
607566
private IntPtr state;

src/runtime/runtime.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -707,10 +707,10 @@ public static extern int Py_Main(
707707
[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
708708
internal static extern IntPtr PyRun_String(string code, IntPtr st, IntPtr globals, IntPtr locals);
709709

710-
[DllImport(PythonDll)]
710+
[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
711711
internal static extern IntPtr PyEval_EvalCode(IntPtr co, IntPtr globals, IntPtr locals);
712712

713-
[DllImport(PythonDll)]
713+
[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]
714714
internal static extern IntPtr Py_CompileString(string code, string file, IntPtr tok);
715715

716716
[DllImport(PythonDll, CallingConvention = CallingConvention.Cdecl)]

0 commit comments

Comments
 (0)