Skip to content
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

Incorporate DSCPython3 branch updated to .NET 4.8 #10682

Merged
merged 8 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from 7 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
15 changes: 11 additions & 4 deletions src/Dynamo.All.sln
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamoCrypto", "DynamoCrypt
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstallUpdate", "Tools\InstallUpdate\InstallUpdate.csproj", "{0ED387BC-17B5-49B7-9C1D-BF58A4A5CC4D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Legacy", "Legacy", "{398542E6-659A-48C8-86EB-33164D227C90}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DataBridgeTests", "..\test\Libraries\DataBridgeTests\DataBridgeTests.csproj", "{F0AF3C6E-0E59-4511-A057-79970EA9DC34}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NUnitUtility", "Tools\NUnitUtility\NUnitUtility.csproj", "{D0DC5724-DE00-4201-A659-A9A6CF81290D}"
Expand Down Expand Up @@ -229,6 +227,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkspaceDependencyViewExte
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocumentationBrowserViewExtension", "DocumentationBrowserViewExtension\DocumentationBrowserViewExtension.csproj", "{BE6D0644-05AF-4580-8597-B95920CE923F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DSCPython", "Libraries\DSCPython\DSCPython.csproj", "{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibraryViewExtensionMSWebBrowser", "LibraryViewExtensionMSWebBrowser\LibraryViewExtensionMSWebBrowser.csproj", "{1A5DC90A-477E-4D4A-87BD-0BFB01F056CE}"
EndProject
Global
Expand Down Expand Up @@ -823,6 +823,14 @@ Global
{BE6D0644-05AF-4580-8597-B95920CE923F}.Release|Any CPU.Build.0 = Release|Any CPU
{BE6D0644-05AF-4580-8597-B95920CE923F}.Release|x64.ActiveCfg = Release|x64
{BE6D0644-05AF-4580-8597-B95920CE923F}.Release|x64.Build.0 = Release|x64
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Debug|x64.ActiveCfg = Debug|x64
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Debug|x64.Build.0 = Debug|x64
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Release|Any CPU.Build.0 = Release|Any CPU
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Release|x64.ActiveCfg = Release|x64
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479}.Release|x64.Build.0 = Release|x64
{1A5DC90A-477E-4D4A-87BD-0BFB01F056CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A5DC90A-477E-4D4A-87BD-0BFB01F056CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A5DC90A-477E-4D4A-87BD-0BFB01F056CE}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -859,7 +867,6 @@ Global
{C70FE632-5500-4C57-B3D6-9B5574137551} = {0355EB79-6961-4B8A-8F66-035D4EC0C9FE}
{88A44558-9148-4F1C-876B-46472793F3D6} = {F4D44BC0-32CF-4E58-AD2A-F19CE1450B00}
{1254D922-643B-4F0B-82BD-E9E02399B040} = {88A44558-9148-4F1C-876B-46472793F3D6}
{2B0F2800-6F62-4869-9074-088C5F6DCCA2} = {398542E6-659A-48C8-86EB-33164D227C90}
{672BF8EC-1116-49F6-B253-DFCE5CF7D4C9} = {0355EB79-6961-4B8A-8F66-035D4EC0C9FE}
{6E0A079E-85F1-45A1-AD5B-9855E4344809} = {FA7BE306-A3B0-45FA-9D87-0C69E6932C13}
{9B4FDC96-E2F9-4B8F-894A-4294405D50E7} = {FA7BE306-A3B0-45FA-9D87-0C69E6932C13}
Expand All @@ -873,7 +880,6 @@ Global
{CCB6E56B-2DA1-4EBA-A1F9-E8510E129D12} = {FA7BE306-A3B0-45FA-9D87-0C69E6932C13}
{A84E15A2-6735-4575-A1DA-7C64AF7582B1} = {D114C59C-CF66-4CC2-980F-9301FB4EA4E1}
{0ED387BC-17B5-49B7-9C1D-BF58A4A5CC4D} = {D114C59C-CF66-4CC2-980F-9301FB4EA4E1}
{398542E6-659A-48C8-86EB-33164D227C90} = {FA7BE306-A3B0-45FA-9D87-0C69E6932C13}
{F0AF3C6E-0E59-4511-A057-79970EA9DC34} = {0E492D35-2310-4849-9694-A2A53C09F21B}
{D0DC5724-DE00-4201-A659-A9A6CF81290D} = {D114C59C-CF66-4CC2-980F-9301FB4EA4E1}
{76686ED6-E759-4772-81C2-768740BE13FA} = {FA7BE306-A3B0-45FA-9D87-0C69E6932C13}
Expand Down Expand Up @@ -904,6 +910,7 @@ Global
{47D2166C-5261-4093-9660-E72B7035E666} = {88D45B00-E564-41DB-B57C-9509646CAA49}
{5E76AAB3-6302-473E-9655-081B53FB1419} = {88D45B00-E564-41DB-B57C-9509646CAA49}
{BE6D0644-05AF-4580-8597-B95920CE923F} = {88D45B00-E564-41DB-B57C-9509646CAA49}
{F1541C2D-80A9-4FE7-8D9E-75A8B9FF3479} = {FA7BE306-A3B0-45FA-9D87-0C69E6932C13}
{1A5DC90A-477E-4D4A-87BD-0BFB01F056CE} = {88D45B00-E564-41DB-B57C-9509646CAA49}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
Expand Down
2 changes: 2 additions & 0 deletions src/DynamoApplications/PathResolvers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public SandboxPathResolver(string preloaderLocation)
"DSCoreNodes.dll",
"DSOffice.dll",
"DSIronPython.dll",
"DSCPython.dll",
Copy link
Member

Choose a reason for hiding this comment

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

I guess this should also be added to the CLI path resolver?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks @mjkkirschner , I will update that. Let me know if you find anything else.

"FunctionObject.ds",
"BuiltIn.ds",
"DynamoConversions.dll",
Expand Down Expand Up @@ -94,6 +95,7 @@ public CLIPathResolver(string preloaderLocation)
"DSCoreNodes.dll",
"DSOffice.dll",
"DSIronPython.dll",
"DSCPython.dll",
"FunctionObject.ds",
"BuiltIn.ds",
"DynamoConversions.dll",
Expand Down
244 changes: 244 additions & 0 deletions src/Libraries/DSCPython/CPythonEvaluator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Autodesk.DesignScript.Runtime;
using Dynamo.Utilities;
using Python.Runtime;

namespace DSCPython
{
[SupressImportIntoVM]
Copy link
Member

Choose a reason for hiding this comment

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

is this class actually imported into the VM at all?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure about this. Maybe @reddyashish ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, the class is imported in the VM but not these internal variables. Similar to what is done in IronPythonEvaluator class.

public enum EvaluationState { Begin, Success, Failed }
Copy link
Member

Choose a reason for hiding this comment

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

if this needs to be public can we add summary tags?
If not can we make it internal?


[SupressImportIntoVM]
public delegate void EvaluationEventHandler(EvaluationState state,
Copy link
Member

Choose a reason for hiding this comment

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

same here(public/internal)

PyScope scope,
string code,
IList bindingValues);

/// <summary>
/// Evaluates a Python script in the Dynamo context.
/// </summary>
[IsVisibleInDynamoLibrary(false)]
public static class CPythonEvaluator
{
/// <summary> stores a copy of the previously executed code</summary>
private static string prev_code { get; set; }

/// <summary>
/// Executes a Python script with custom variable names. Script may be a string
/// read from a file, for example. Pass a list of names (matching the variable
/// names in the script) to bindingNames and pass a corresponding list of values
/// to bindingValues.
/// </summary>
/// <param name="code">Python script as a string.</param>
/// <param name="bindingNames">Names of values referenced in Python script.</param>
/// <param name="bindingValues">Values referenced in Python script.</param>
public static object EvaluatePythonScript(
string code,
IList bindingNames,
[ArbitraryDimensionArrayImport] IList bindingValues)
{
if (code != prev_code)
{
Python.Included.Installer.SetupPython().Wait();

if (!PythonEngine.IsInitialized)
{
PythonEngine.Initialize();
PythonEngine.BeginAllowThreads();
}

IntPtr gs = PythonEngine.AcquireLock();
try
{
using (Py.GIL())
{
using (PyScope scope = Py.CreateScope())
{
int amt = Math.Min(bindingNames.Count, bindingValues.Count);

for (int i = 0; i < amt; i++)
{
scope.Set((string)bindingNames[i], InputMarshaler.Marshal(bindingValues[i]).ToPython());
}

try
{
OnEvaluationBegin(scope, code, bindingValues);
scope.Exec(code);
OnEvaluationEnd(false, scope, code, bindingValues);

var result = scope.Contains("OUT") ? scope.Get("OUT") : null;

return OutputMarshaler.Marshal(result);
}
catch (Exception e)
{
OnEvaluationEnd(false, scope, code, bindingValues);
throw e;
}
}
}
}
catch (PythonException pe)
{
throw pe;
}
finally
{
PythonEngine.ReleaseLock(gs);
}
}
return null;
}

#region Marshalling

/// <summary>
/// Data Marshaler for all data coming into a Python node.
/// </summary>
[SupressImportIntoVM]
public static DataMarshaler InputMarshaler
{
get
{
if (inputMarshaler == null)
{
inputMarshaler = new DataMarshaler();
inputMarshaler.RegisterMarshaler(
delegate(IList lst)
{
var pyList = new PyList();
foreach (var item in lst.Cast<object>().Select(inputMarshaler.Marshal))
{
pyList.Append(item.ToPython());
}
return pyList;
});
inputMarshaler.RegisterMarshaler(
delegate (DesignScript.Builtin.Dictionary dict)
{
var pyDict = new PyDict();
foreach (var key in dict.Keys)
{
pyDict.SetItem(inputMarshaler.Marshal(key).ToPython(), inputMarshaler.Marshal(dict.ValueAtKey(key)).ToPython());
}
return pyDict;
});
}
return inputMarshaler;
}
}

/// <summary>
/// Data Marshaler for all data coming out of a Python node.
/// </summary>
[SupressImportIntoVM]
public static DataMarshaler OutputMarshaler
{
get
{
if (outputMarshaler == null)
{
outputMarshaler = new DataMarshaler();
outputMarshaler.RegisterMarshaler(
delegate (PyObject pyObj)
{
if (PyList.IsListType(pyObj))
{
var pyList = new PyList(pyObj);
var list = new List<object>();
foreach (PyObject item in pyList)
{
list.Add(outputMarshaler.Marshal(item));
}
return list;
}
else if (PyDict.IsDictType(pyObj))
{
var pyDict = new PyDict(pyObj);
var dict = new Dictionary<object, object>();
foreach (PyObject item in pyDict.Items())
{
dict.Add(
outputMarshaler.Marshal(item.GetItem(0)),
outputMarshaler.Marshal(item.GetItem(1))
);
}
return dict;
}
else if(PyLong.IsLongType(pyObj))
{
return PyLong.AsLong(pyObj).ToInt64();
}
else
{
return outputMarshaler.Marshal(pyObj.AsManagedObject(typeof(object)));
}
});
}
return outputMarshaler;
}

}

private static DataMarshaler inputMarshaler;
private static DataMarshaler outputMarshaler;

#endregion

#region Evaluation events

/// <summary>
/// Emitted immediately before execution begins
/// </summary>
[SupressImportIntoVM]
public static event EvaluationEventHandler EvaluationBegin;

/// <summary>
/// Emitted immediately after execution ends or fails
/// </summary>
[SupressImportIntoVM]
public static event EvaluationEventHandler EvaluationEnd;

/// <summary>
/// Called immediately before evaluation starts
/// </summary>
/// <param name="scope">The scope in which the code is executed</param>
/// <param name="code">The code to be evaluated</param>
/// <param name="bindingValues">The binding values - these are already added to the scope when called</param>
private static void OnEvaluationBegin( PyScope scope,
string code,
IList bindingValues )
{
if (EvaluationBegin != null)
{
EvaluationBegin(EvaluationState.Begin, scope, code, bindingValues);
}
}

/// <summary>
/// Called when the evaluation has completed successfully or failed
/// </summary>
/// <param name="isSuccessful">Whether the evaluation succeeded or not</param>
/// <param name="scope">The scope in which the code is executed</param>
/// <param name="code">The code to that was evaluated</param>
/// <param name="bindingValues">The binding values - these are already added to the scope when called</param>
private static void OnEvaluationEnd( bool isSuccessful,
PyScope scope,
string code,
IList bindingValues)
{
if (EvaluationEnd != null)
{
EvaluationEnd( isSuccessful ? EvaluationState.Success : EvaluationState.Failed,
scope, code, bindingValues);
}
}

#endregion

}
}
Loading