Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 4 additions & 2 deletions src/DynamoUtilities/DataMarshaler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ public class DataMarshaler

public DataMarshaler()
{
//RegisterMarshaler((IEnumerable e) => e.Cast<object>().Select(Marshal));
RegisterMarshaler((IList e) => e.Cast<object>().Select(Marshal).ToList());
RegisterMarshaler(
(IDictionary dict) =>
dict.Cast<dynamic>().ToDictionary(x => Marshal(x.Key), x => Marshal(x.Value)));
{
// Dictionary<TKey, TValue> and IronPython.Runtime.PythonDictionary both implement IDictionary
return dict.Keys.Cast<object>().ToDictionary(key => Marshal(key), key => Marshal(dict[key]));
Copy link
Member

Choose a reason for hiding this comment

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

does this work nicely for nested dictionaries?

});
}

/// <summary>
Expand Down
10 changes: 5 additions & 5 deletions src/Libraries/DSIronPython/DSIronPython.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
<Name>DynamoServices</Name>
<Private>False</Private>
</ProjectReference>
<ProjectReference Include="..\DesignScriptBuiltin\DesignScriptBuiltin.csproj">
<Project>{c0d6dee5-5532-4345-9c66-4c00d7fdb8be}</Project>
<Name>DesignScriptBuiltin</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand All @@ -107,10 +111,6 @@
<ItemGroup>
<PythonStdLib Include="$(ProjectDir)..\..\packages\IronPython.StdLib.2.7.8.1\contentFiles\any\any\Lib\**\*.*" />
</ItemGroup>
<Copy
SourceFiles="@(PythonStdLib)"
DestinationFiles="@(PythonStdLib->'$(TargetDir)IronPython.StdLib.2.7.8\%(RecursiveDir)%(Filename)%(Extension)')"
SkipUnchangedFiles="true"
/>
<Copy SourceFiles="@(PythonStdLib)" DestinationFiles="@(PythonStdLib->'$(TargetDir)IronPython.StdLib.2.7.8\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>
</Project>
14 changes: 13 additions & 1 deletion src/Libraries/DSIronPython/IronPythonEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using IronPython.Hosting;

using Microsoft.Scripting.Hosting;
using Microsoft.Scripting.Utils;

namespace DSIronPython
{
Expand Down Expand Up @@ -54,7 +55,8 @@ private static string pythonStandardLibPath()
// Return the standard library path
if (!string.IsNullOrEmpty(dynamoCorePath))
{ return dynamoCorePath + @"\IronPython.StdLib.2.7.8"; }
else { return null; }

return null;
}

/// <summary>
Expand Down Expand Up @@ -155,6 +157,16 @@ public static DataMarshaler InputMarshaler
}
return pyList;
});
inputMarshaler.RegisterMarshaler(
delegate (DesignScript.Builtin.Dictionary dict)
{
var pyDict = new IronPython.Runtime.PythonDictionary();
foreach (var key in dict.Keys)
{
pyDict.Add(inputMarshaler.Marshal(key), inputMarshaler.Marshal(dict.ValueAtKey(key)));
}
return pyDict;
});
}
return inputMarshaler;
}
Expand Down
59 changes: 44 additions & 15 deletions test/DynamoCoreTests/DSEvaluationUnitTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ protected void AssertValue(MirrorData data, object value)
{
if (!(value is IEnumerable))
{
Assert.Fail("Data is collection but expected vlaue is not.");
Assert.Fail("Data is collection but expected value is not.");
}
AssertCollection(data, value as IEnumerable);
}
Expand All @@ -180,7 +180,7 @@ protected void AssertValue(MirrorData data, object value)
try
{
double mirrorData = Convert.ToDouble(data.Data);
Assert.AreEqual((double)value, Convert.ToDouble(data.Data), 0.00001);
Assert.AreEqual((double)value, mirrorData, 0.00001);
}
catch (Exception e)
{
Expand All @@ -191,30 +191,59 @@ protected void AssertValue(MirrorData data, object value)
{
Assert.AreEqual(data.Class.ClassName, value);
}
else if (data.IsPointer && value is DesignScript.Builtin.Dictionary)
else if (data.IsDictionary)
{
var thisData = data.Data as DesignScript.Builtin.Dictionary;

if (thisData == null)
if (value is DesignScript.Builtin.Dictionary)
{
Assert.Fail("Data is expected to be DS Dictionary but is not.");
}
var otherVal = (DesignScript.Builtin.Dictionary) value;
var otherVal = (DesignScript.Builtin.Dictionary) value;

if (otherVal.Count != thisData.Count)
{
Assert.Fail("Data and expected value are 2 different dictionaries.");
if (otherVal.Count != thisData.Count)
{
Assert.Fail("Data and expected value are 2 different dictionaries.");
}

foreach (var key in otherVal.Keys)
{
var val = thisData.ValueAtKey(key);
if (val == null)
{
Assert.Fail("Data and expected value are 2 different dictionaries.");
}

if (val.GetType().IsValueType)
{
Assert.AreEqual(val, thisData.ValueAtKey(key));
}
}
}
foreach (var key in otherVal.Keys)
else if (value is IDictionary)
{
var val = thisData.ValueAtKey(key);
if (val == null)
var otherVal = (IDictionary)value;

if (otherVal.Count != thisData.Count)
{
Assert.Fail("Data and expected value are 2 different dictionaries.");
}
if (val.GetType().IsValueType)

foreach (var key in otherVal.Keys)
{
Assert.AreEqual(val, thisData.ValueAtKey(key));
if (!(key is string))
{
Assert.Fail("Expected value is a dictionary with non-string key(s).");
}
var strKey = (string) key;
var val = thisData.ValueAtKey(strKey);
if (val == null)
{
Assert.Fail("Data and expected value are 2 different dictionaries.");
}

if (val.GetType().IsValueType)
{
Assert.AreEqual(val, thisData.ValueAtKey(strKey));
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added support to compare Dictionaries directly to test API: AssertValue

}
}
}
Expand Down
40 changes: 39 additions & 1 deletion test/Libraries/DynamoPythonTests/PythonEditTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class PythonEditTests : DynamoViewModelUnitTest
{
protected override void GetLibrariesToPreload(List<string> libraries)
{
libraries.Add("DesignScriptBuiltin.dll");
libraries.Add("DSIronPython.dll");
base.GetLibrariesToPreload(libraries);
}
Expand Down Expand Up @@ -159,7 +160,7 @@ public void VerifyPythonLoadsFromCore()
foreach(NodeModel node in allNodes) {
var guid = node.GUID.ToString();

// if node is a test node, verify truthy value
// if node is a test node, verify truth value
if (testingNodeGUIDS.Contains(guid) ) {
AssertPreviewValue(guid, true);
}
Expand All @@ -169,6 +170,43 @@ public void VerifyPythonLoadsFromCore()
Assert.NotNull(pynode);
}

[Test]
public void ReturnPythonDictionary_AsDynamoDictionary()
{
// open test graph
var examplePath = Path.Combine(TestDirectory, @"core\python", "python_dict.dyn");
ViewModel.OpenCommand.Execute(examplePath);

var guid = "490a8d54d0fa4782ae18c81f6eef8306";

AssertPreviewValue(guid, new Dictionary<string, int> { { "abc", 123 }, { "def", 345 } });
}

[Test]
public void InputDynamoDictionary_AsPythonDictionary()
{
// open test graph
var examplePath = Path.Combine(TestDirectory, @"core\python", "python_dict2.dyn");
ViewModel.OpenCommand.Execute(examplePath);

var guid = "490a8d54d0fa4782ae18c81f6eef8306";

AssertPreviewValue(guid,
new List<object> {new Dictionary<string, int> {{"abcd", 123}}, new List<int> {1, 2, 3, 4, 5, 6, 7, 8, 9}});
}

[Test]
public void ReturnIronPythonDictionary_AsDynamoDictionary()
{
// open test graph
var examplePath = Path.Combine(TestDirectory, @"core\python", "netDict_from_python.dyn");
ViewModel.OpenCommand.Execute(examplePath);

var guid = "490a8d54d0fa4782ae18c81f6eef8306";

AssertPreviewValue(guid, new Dictionary<string, int> {{"abc", 123}, {"def", 10}});
}

private void UpdatePythonNodeContent(ModelBase pythonNode, string value)
{
var command = new DynCmd.UpdateModelValueCommand(
Expand Down
Loading