Skip to content

Commit 3e20ba4

Browse files
BogdanZavuzavub
andauthored
DYN-7400 : handle host data marshaler dependent on python runtime (#15537)
Co-authored-by: Bogdan Zavu <[email protected]>
1 parent eb1559a commit 3e20ba4

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

src/Libraries/DSCPython/CPythonEvaluator.cs

+40
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,46 @@ private static string GetTraceBack(Exception e)
447447

448448
#region Marshalling
449449

450+
/// <summary>
451+
/// Add additional data marshalers to handle host data.
452+
/// </summary>
453+
[SupressImportIntoVM]
454+
internal override void RegisterHostDataMarshalers()
455+
{
456+
DataMarshaler dataMarshalerToUse = HostDataMarshaler as DataMarshaler;
457+
dataMarshalerToUse?.RegisterMarshaler((PyObject pyObj) =>
458+
{
459+
try
460+
{
461+
using (Py.GIL())
462+
{
463+
if (PyDict.IsDictType(pyObj))
464+
{
465+
using (var pyDict = new PyDict(pyObj))
466+
{
467+
var dict = new PyDict();
468+
foreach (PyObject item in pyDict.Items())
469+
{
470+
dict.SetItem(
471+
ConverterExtension.ToPython(dataMarshalerToUse.Marshal(item.GetItem(0))),
472+
ConverterExtension.ToPython(dataMarshalerToUse.Marshal(item.GetItem(1)))
473+
);
474+
}
475+
return dict;
476+
}
477+
}
478+
var unmarshalled = pyObj.AsManagedObject(typeof(object));
479+
return dataMarshalerToUse.Marshal(unmarshalled);
480+
}
481+
}
482+
catch (Exception e)
483+
{
484+
DynamoLogger?.Log($"error marshaling python object {pyObj.Handle} {e.Message}");
485+
return pyObj;
486+
}
487+
});
488+
}
489+
450490
/// <summary>
451491
/// Data Marshaler for all data coming into a Python node.
452492
/// </summary>

src/NodeServices/Properties/AssemblyInfo.cs

+1
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@
4444
[assembly: InternalsVisibleTo("DynamoApplications")]
4545
[assembly: InternalsVisibleTo("DynamoUnits")]
4646
[assembly: InternalsVisibleTo("DSPythonNet3")]
47+
[assembly: InternalsVisibleTo("DynamoRevitDS")]

src/NodeServices/PythonServices.cs

+15
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ public abstract object OutputDataMarshaler
6363
get;
6464
}
6565

66+
/// <summary>
67+
/// Data marshaler for host data used during the execution of a Python node.
68+
/// This can be implemented differently across various Python engines due to
69+
/// factors such as differing PythonNet APIs or other specific requirements.
70+
/// </summary>
71+
internal object HostDataMarshaler { get; set; }
72+
6673
/// <summary>
6774
/// Name of the Python engine
6875
/// </summary>
@@ -93,6 +100,14 @@ public abstract string Name
93100
public abstract object Evaluate(string code,
94101
IList bindingNames,
95102
[ArbitraryDimensionArrayImport] IList bindingValues);
103+
104+
/// <summary>
105+
/// Add additional data marshalers to handle host data.
106+
/// While some data marshalers are specific to the host application,
107+
/// they must be implemented at the Dynamo Core level in order to
108+
/// avoid host dependencies on the Python runtime.
109+
/// </summary>
110+
internal virtual void RegisterHostDataMarshalers() { }
96111
}
97112

98113
/// <summary>

0 commit comments

Comments
 (0)