Skip to content

Commit

Permalink
Incorporate DSCPython3 branch updated to .NET 4.8 (#10682)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmisol authored May 19, 2020
1 parent a84e262 commit 44d02ec
Show file tree
Hide file tree
Showing 48 changed files with 1,551 additions and 746 deletions.
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",
"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]
internal enum EvaluationState { Begin, Success, Failed }

[SupressImportIntoVM]
internal delegate void EvaluationEventHandler(EvaluationState state,
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]
internal static event EvaluationEventHandler EvaluationBegin;

/// <summary>
/// Emitted immediately after execution ends or fails
/// </summary>
[SupressImportIntoVM]
internal 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

0 comments on commit 44d02ec

Please sign in to comment.