@@ -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