Skip to content

Commit 8ef863a

Browse files
committed
wrapper
1 parent 27aadd6 commit 8ef863a

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

DSPythonNet3/DSPythonNet3Evaluator.cs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,61 @@ private static bool IsMarkedToSkipConversion(PyObject pyObj)
799799
public override event EvaluationFinishedEventHandler EvaluationFinished;
800800

801801
private bool registeredUnwrapMarshaler;
802+
private const string ConnectionNodeCompatSentinel = "__dspynet3_connnode_compat__";
803+
804+
/// <summary>
805+
/// Compatibility shim for "node-first" static methods exposed by some Dynamo/Revit libraries.
806+
/// In older engines these could be invoked like instance methods (e.g. node.SubNodesOfSize(2)).
807+
/// Python.NET 3 binds static methods strictly, so we patch a small set of known APIs to keep
808+
/// existing graphs working.
809+
/// </summary>
810+
private static string ConnectionNodeCompatPatchCode()
811+
{
812+
return $@"
813+
import builtins as __builtins__
814+
try:
815+
from AdvanceSteel.ConnectionAutomation.Nodes import ConnectionNode as __ConnectionNode
816+
except Exception:
817+
__ConnectionNode = None
818+
if __ConnectionNode is not None:
819+
if not getattr(__builtins__, '{ConnectionNodeCompatSentinel}', False):
820+
def __dspynet3__patch_connnode_instance(__obj):
821+
# Attach instance-callable wrappers for node-first static methods.
822+
try:
823+
if not isinstance(__obj, __ConnectionNode):
824+
return
825+
def __subnodes(__n, *args, __obj=__obj, **kwargs):
826+
return __ConnectionNode.SubNodesOfSize(__obj, __n, *args, **kwargs)
827+
def __existing(*args, __obj=__obj, **kwargs):
828+
return __ConnectionNode.ExistingConnections(__obj, *args, **kwargs)
829+
try:
830+
setattr(__obj, 'SubNodesOfSize', __subnodes)
831+
except Exception:
832+
pass
833+
try:
834+
setattr(__obj, 'ExistingConnections', __existing)
835+
except Exception:
836+
pass
837+
except Exception:
838+
pass
839+
def __dspynet3__walk_and_patch(__x):
840+
try:
841+
if isinstance(__x, (list, tuple)):
842+
for __i in __x:
843+
__dspynet3__walk_and_patch(__i)
844+
else:
845+
__dspynet3__patch_connnode_instance(__x)
846+
except Exception:
847+
pass
848+
setattr(__builtins__, '__dspynet3__walk_and_patch_connnode', __dspynet3__walk_and_patch)
849+
setattr(__builtins__, '{ConnectionNodeCompatSentinel}', True)
850+
try:
851+
__inp = globals().get('IN', None)
852+
__builtins__.__dspynet3__walk_and_patch_connnode(__inp)
853+
except Exception:
854+
pass
855+
";
856+
}
802857

803858
/// <summary>
804859
/// Called immediately before evaluation starts
@@ -844,6 +899,8 @@ private void OnEvaluationBegin(PyModule scope,
844899

845900
registeredUnwrapMarshaler = true;
846901
}
902+
903+
scope.Exec(ConnectionNodeCompatPatchCode());
847904
}
848905

849906
/// <summary>

0 commit comments

Comments
 (0)