Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
updated according to filmor's comments
  • Loading branch information
yagweb committed May 31, 2017
commit 2c3db3d6eec31f9f88127fbf641652266825fa1f
4 changes: 0 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].

- Deprecated `RunString` (#401)

### Deprecated

- Deprecated `RunString` (#401)

### Fixed

- Fixed crash during Initialization (#262)(#343)
Expand Down
88 changes: 44 additions & 44 deletions src/embed_tests/TestPyScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,13 @@ public void TestImportScope()
ps.SetVariable("bb", 100);
ps.SetVariable("cc", 10);

PyScope scope = Py.CreateScope();
scope.Import(ps, "ps");

scope.Exec("aa = ps.bb + ps.cc + 3");
var result = scope.GetVariable<int>("aa");
Assert.AreEqual(113, result);

scope.Dispose();
using (var scope = Py.CreateScope())
{
scope.Import(ps, "ps");
scope.Exec("aa = ps.bb + ps.cc + 3");
var result = scope.GetVariable<int>("aa");
Assert.AreEqual(113, result);
}

Assert.IsFalse(ps.ContainsVariable("aa"));
}
Expand All @@ -217,13 +216,12 @@ public void TestImportAllFromScope()
ps.SetVariable("bb", 100);
ps.SetVariable("cc", 10);

PyScope scope = ps.NewScope();

scope.Exec("aa = bb + cc + 3");
var result = scope.GetVariable<int>("aa");
Assert.AreEqual(113, result);

scope.Dispose();
using (var scope = ps.NewScope())
{
scope.Exec("aa = bb + cc + 3");
var result = scope.GetVariable<int>("aa");
Assert.AreEqual(113, result);
}

Assert.IsFalse(ps.ContainsVariable("aa"));
}
Expand All @@ -244,28 +242,27 @@ public void TestImportScopeFunction()
"def func1():\n" +
" return cc + bb\n");

PyScope scope = ps.NewScope();

//'func1' is imported from the origion scope
scope.Exec(
"def func2():\n" +
" return func1() - cc - bb\n");
dynamic func2 = scope.GetVariable("func2");

var result1 = func2().As<int>();
Assert.AreEqual(0, result1);

scope.SetVariable("cc", 20);//it has no effect on the globals of 'func1'
var result2 = func2().As<int>();
Assert.AreEqual(-10, result2);
scope.SetVariable("cc", 10); //rollback

ps.SetVariable("cc", 20);
var result3 = func2().As<int>();
Assert.AreEqual(10, result3);
ps.SetVariable("cc", 10); //rollback

scope.Dispose();
using (PyScope scope = ps.NewScope())
{
//'func1' is imported from the origion scope
scope.Exec(
"def func2():\n" +
" return func1() - cc - bb\n");
dynamic func2 = scope.GetVariable("func2");

var result1 = func2().As<int>();
Assert.AreEqual(0, result1);

scope.SetVariable("cc", 20);//it has no effect on the globals of 'func1'
var result2 = func2().As<int>();
Assert.AreEqual(-10, result2);
scope.SetVariable("cc", 10); //rollback

ps.SetVariable("cc", 20);
var result3 = func2().As<int>();
Assert.AreEqual(10, result3);
ps.SetVariable("cc", 10); //rollback
}
}
}

Expand All @@ -280,11 +277,13 @@ public void TestImportScopeByName()
{
ps.SetVariable("bb", 100);

var scope = Py.CreateScope();
scope.ImportAll("test");
//scope.ImportModule("test");
using (var scope = Py.CreateScope())
{
scope.ImportAll("test");
//scope.ImportModule("test");

Assert.IsTrue(scope.ContainsVariable("bb"));
Assert.IsTrue(scope.ContainsVariable("bb"));
}
}
}

Expand All @@ -306,9 +305,10 @@ public void TestVariables()
var a2 = ps.GetVariable<int>("ee");
Assert.AreEqual(220, a2);

var item = ps.Variables();
item["ee"] = new PyInt(230);
item.Dispose();
using (var item = ps.Variables())
{
item["ee"] = new PyInt(230);
}
var a3 = ps.GetVariable<int>("ee");
Assert.AreEqual(230, a3);
}
Expand Down
86 changes: 43 additions & 43 deletions src/runtime/pyscope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ public class PyScope : DynamicObject, IDisposable
internal readonly PyScopeManager Manager;

public event Action<PyScope> OnDispose;
public PyScope(IntPtr ptr, PyScopeManager manager)

internal PyScope(IntPtr ptr, PyScopeManager manager)
{
if (Runtime.PyObject_Type(ptr) != Runtime.PyModuleType)
{
throw new PyScopeException("object is not a module");
}
if(manager == null)
if (manager == null)
{
manager = PyScopeManager.Global;
}
Expand Down Expand Up @@ -80,19 +80,23 @@ public PyScope NewScope()
public dynamic Import(string name, string asname = null)
{
Check();
if (asname == null)
if (String.IsNullOrEmpty(asname))
{
asname = name;
}
var scope = Manager.TryGet(name);
if(scope != null)
PyScope scope;
Manager.TryGet(name, out scope);
if (scope != null)
{
Import(scope, asname);
return scope;
}
PyObject module = PythonEngine.ImportModule(name);
Import(module, asname);
return module;
else
{
PyObject module = PythonEngine.ImportModule(name);
Import(module, asname);
return module;
}
}

public void Import(PyScope scope, string asname)
Expand All @@ -109,7 +113,7 @@ public void Import(PyScope scope, string asname)
/// </remarks>
public void Import(PyObject module, string asname = null)
{
if (asname == null)
if (String.IsNullOrEmpty(asname))
{
asname = module.GetAttr("__name__").ToString();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use .As<string>() instead? ToString is much too forgiving here.

}
Expand All @@ -118,14 +122,18 @@ public void Import(PyObject module, string asname = null)

public void ImportAll(string name)
{
var scope = Manager.TryGet(name);
if(scope != null)
PyScope scope;
Manager.TryGet(name, out scope);
if (scope != null)
{
ImportAll(scope);
return;
}
PyObject module = PythonEngine.ImportModule(name);
ImportAll(module);
else
{
PyObject module = PythonEngine.ImportModule(name);
ImportAll(module);
}
}

public void ImportAll(PyScope scope)
Expand Down Expand Up @@ -323,27 +331,13 @@ public bool ContainsVariable(string name)
/// </remarks>
public PyObject GetVariable(string name)
{
Check();
using (var pyKey = new PyString(name))
PyObject scope;
var state = TryGetVariable(name, out scope);
if(!state)
{
if (Runtime.PyMapping_HasKey(variables, pyKey.obj) != 0)
{
IntPtr op = Runtime.PyObject_GetItem(variables, pyKey.obj);
if (op == IntPtr.Zero)
{
throw new PythonException();
}
if (op == Runtime.PyNone)
{
return null;
}
return new PyObject(op);
}
else
{
throw new PyScopeException(String.Format("'ScopeStorage' object has no attribute '{0}'", name));
}
throw new PyScopeException($"The scope of name '{Name}' has no attribute '{name}'");
}
return scope;
}

/// <summary>
Expand All @@ -367,6 +361,7 @@ public bool TryGetVariable(string name, out PyObject value)
}
if (op == Runtime.PyNone)
{
Runtime.XDecref(op);
value = null;
return true;
}
Expand Down Expand Up @@ -401,11 +396,18 @@ public bool TryGetVariable<T>(string name, out T value)
{
value = default(T);
return false;
}
}
if (pyObj == null)
{
value = default(T);
return true;
if(typeof(T).IsValueType)
{
throw new PyScopeException($"The value of the attribute '{name}' is None which cannot be convert to '{typeof(T).ToString()}'");
}
else
{
value = default(T);
return true;
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that if someone does TryGetVariable<int>("something", out val) where something = None, they will get as a result val = 0 without any further indication. Seems like a very bad idea for value types.

value = pyObj.As<T>();
return true;
Expand All @@ -427,7 +429,7 @@ private void Check()
{
if (isDisposed)
{
throw new PyScopeException("'ScopeStorage' object has been disposed");
throw new PyScopeException($"The scope of name '{Name}' object has been disposed");
}
}

Expand Down Expand Up @@ -484,7 +486,7 @@ public PyScope Create(string name)
}
if (name != null && NamedScopes.ContainsKey(name))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contains(name)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm not quite understand?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already defined a member function Contains, use that one.

{
throw new PyScopeException($"PyScope '{name}' has existed");
throw new PyScopeException($"A scope of name '{name}' does already exist");
}
var scope = this.NewScope(name);
scope.OnDispose += Remove;
Expand All @@ -507,14 +509,12 @@ public PyScope Get(string name)
{
return NamedScopes[name];
}
throw new PyScopeException($"PyScope '{name}' not exist");
throw new PyScopeException($"There is no scope named '{name}' registered in this manager");
}

public PyScope TryGet(string name)
public bool TryGet(string name, out PyScope scope)
{
PyScope value;
NamedScopes.TryGetValue(name, out value);
return value;
return NamedScopes.TryGetValue(name, out scope);
}

public void Remove(PyScope scope)
Expand Down