-
Notifications
You must be signed in to change notification settings - Fork 752
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 |
---|---|---|
|
@@ -15,13 +15,14 @@ public PyScopeException(string message) | |
} | ||
|
||
/// <summary> | ||
/// Classes implement this interface must be used with GIL obtained. | ||
/// Classes/methods have this attribute must be used with GIL obtained. | ||
/// </summary> | ||
public interface IPyObject : IDisposable | ||
public class PyGILAttribute : Attribute | ||
{ | ||
} | ||
|
||
public class PyScope : DynamicObject, IPyObject | ||
[PyGIL] | ||
public class PyScope : DynamicObject, IDisposable | ||
{ | ||
public readonly string Name; | ||
|
||
|
@@ -33,6 +34,10 @@ public class PyScope : DynamicObject, IPyObject | |
internal readonly IntPtr variables; | ||
|
||
private bool isDisposed; | ||
|
||
internal PyScopeManager Manager; | ||
|
||
public event Action<PyScope> OnDispose; | ||
|
||
internal static PyScope New(string name = null) | ||
{ | ||
|
@@ -64,8 +69,6 @@ private PyScope(IntPtr ptr) | |
this.Name = this.GetVariable<string>("__name__"); | ||
} | ||
|
||
public event Action<PyScope> OnDispose; | ||
|
||
public PyDict Variables() | ||
{ | ||
Runtime.XIncref(variables); | ||
|
@@ -81,7 +84,7 @@ public PyScope NewScope() | |
|
||
public void ImportAllFromScope(string name) | ||
{ | ||
var scope = Py.GetScope(name); | ||
var scope = Manager.Get(name); | ||
ImportAllFromScope(scope); | ||
} | ||
|
||
|
@@ -96,7 +99,7 @@ public void ImportAllFromScope(PyScope scope) | |
|
||
public void ImportScope(string name, string asname = null) | ||
{ | ||
var scope = Py.GetScope(name); | ||
var scope = Manager.Get(name); | ||
if(asname == null) | ||
{ | ||
asname = name; | ||
|
@@ -436,4 +439,64 @@ public void Dispose() | |
Dispose(); | ||
} | ||
} | ||
|
||
public class PyScopeManager | ||
{ | ||
private Dictionary<string, PyScope> NamedScopes = new Dictionary<string, PyScope>(); | ||
|
||
[PyGIL] | ||
public PyScope Create() | ||
{ | ||
var scope = PyScope.New(); | ||
scope.Manager = this; | ||
return scope; | ||
} | ||
|
||
[PyGIL] | ||
public PyScope Create(string name) | ||
{ | ||
if (String.IsNullOrEmpty(name)) | ||
{ | ||
throw new PyScopeException("Name of ScopeStorage must not be empty"); | ||
} | ||
if (name != null && NamedScopes.ContainsKey(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.
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. Sorry, I'm not quite understand? 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. You already defined a member function |
||
{ | ||
throw new PyScopeException(String.Format("ScopeStorage '{0}' has existed", name)); | ||
} | ||
var scope = PyScope.New(name); | ||
scope.Manager = this; | ||
scope.OnDispose += Remove; | ||
NamedScopes[name] = scope; | ||
return scope; | ||
} | ||
|
||
public bool Contains(string name) | ||
{ | ||
return NamedScopes.ContainsKey(name); | ||
} | ||
|
||
public PyScope Get(string name) | ||
{ | ||
if (name != null && NamedScopes.ContainsKey(name)) | ||
{ | ||
return NamedScopes[name]; | ||
} | ||
throw new PyScopeException(String.Format("ScopeStorage '{0}' not exist", name)); | ||
} | ||
|
||
public void Remove(PyScope scope) | ||
{ | ||
NamedScopes.Remove(scope.Name); | ||
} | ||
|
||
[PyGIL] | ||
public void Clear() | ||
{ | ||
var scopes = NamedScopes.Values.ToList(); | ||
foreach (var scope in scopes) | ||
{ | ||
scope.Dispose(); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -294,7 +294,7 @@ public static void Shutdown() | |
{ | ||
if (initialized) | ||
{ | ||
Py.ClearScopes(); | ||
Py.PyScopeManager.Clear(); | ||
Marshal.FreeHGlobal(_pythonHome); | ||
_pythonHome = IntPtr.Zero; | ||
Marshal.FreeHGlobal(_programName); | ||
|
@@ -547,61 +547,20 @@ public static GILState GIL() | |
return new GILState(); | ||
} | ||
|
||
private static Dictionary<string, PyScope> NamedScopes = new Dictionary<string, PyScope>(); | ||
internal static PyScopeManager PyScopeManager = new PyScopeManager(); | ||
|
||
public static PyScope CreateScope() | ||
{ | ||
var scope = PyScope.New(); | ||
var scope = PyScopeManager.Create(); | ||
return scope; | ||
} | ||
9E7A |
||
public static PyScope CreateScope(string 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. Should have a default parameter 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. By contrast, I want to split the two methods CreateScope() and CreateScope(string name). CreateScope() is unique, CreateScope(string name) will be put in the ScopeManager class. |
||
{ | ||
if (String.IsNullOrEmpty(name)) | ||
{ | ||
throw new PyScopeException("Name of ScopeStorage must not be empty"); | ||
} | ||
if (name != null && NamedScopes.ContainsKey(name)) | ||
{ | ||
throw new PyScopeException(String.Format("ScopeStorage '{0}' has existed", name)); | ||
} | ||
var scope = PyScope.New(name); | ||
if (name != null) | ||
{ | ||
NamedScopes[name] = scope; | ||
scope.OnDispose += RemoveScope; | ||
} | ||
var scope = PyScopeManager.Create(name); | ||
return scope; | ||
} | ||
|
||
public static bool ContainsScope(string name) | ||
{ | ||
return NamedScopes.ContainsKey(name); | ||
} | ||
|
||
public static PyScope GetScope(string name) | ||
{ | ||
if (name != null && NamedScopes.ContainsKey(name)) | ||
{ | ||
return NamedScopes[name]; | ||
} | ||
throw new PyScopeException(String.Format("ScopeStorage '{0}' not exist", name)); | ||
} | ||
|
||
internal static void RemoveScope(PyScope scope) | ||
{ | ||
NamedScopes.Remove(scope.Name); | ||
} | ||
|
||
internal static void ClearScopes() | ||
{ | ||
var scopes = NamedScopes.Values.ToList(); | ||
foreach (var scope in scopes) | ||
{ | ||
scope.Dispose(); | ||
} | ||
} | ||
|
||
public class GILState : IDisposable | ||
{ | ||
private IntPtr state; | ||
|
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.
Private should be
_isDisposed
.