Skip to content
Open
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
57 changes: 57 additions & 0 deletions DSPythonNet3/DSPythonNet3Evaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
internal class DynamoCPythonHandleComparer : IEqualityComparer<DynamoCPythonHandle>
{

public bool Equals(DynamoCPythonHandle x, DynamoCPythonHandle y)

Check warning on line 23 in DSPythonNet3/DSPythonNet3Evaluator.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Nullability of reference types in type of parameter 'y' of 'bool DynamoCPythonHandleComparer.Equals(DynamoCPythonHandle x, DynamoCPythonHandle y)' doesn't match implicitly implemented member 'bool IEqualityComparer<DynamoCPythonHandle>.Equals(DynamoCPythonHandle? x, DynamoCPythonHandle? y)' (possibly because of nullability attributes).

Check warning on line 23 in DSPythonNet3/DSPythonNet3Evaluator.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Nullability of reference types in type of parameter 'x' of 'bool DynamoCPythonHandleComparer.Equals(DynamoCPythonHandle x, DynamoCPythonHandle y)' doesn't match implicitly implemented member 'bool IEqualityComparer<DynamoCPythonHandle>.Equals(DynamoCPythonHandle? x, DynamoCPythonHandle? y)' (possibly because of nullability attributes).
{
return x.PythonObjectID.Equals(y.PythonObjectID);
}
Expand Down Expand Up @@ -74,7 +74,7 @@
try
{
var pyobj = DSPythonNet3Evaluator.globalScope.Get(PythonObjectID.ToString());
return pyobj.ToString();

Check warning on line 77 in DSPythonNet3/DSPythonNet3Evaluator.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Possible null reference return.
}
catch (Exception e)
{
Expand Down Expand Up @@ -143,8 +143,8 @@
{ // Session is null when running unit tests.
if (ExecutionEvents.ActiveSession != null)
{
dynamoLogger = ExecutionEvents.ActiveSession.GetParameterValue(ParameterKeys.Logger) as DynamoLogger;

Check warning on line 146 in DSPythonNet3/DSPythonNet3Evaluator.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Possible null reference assignment.
return dynamoLogger;

Check warning on line 147 in DSPythonNet3/DSPythonNet3Evaluator.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Possible null reference return.
}
return dynamoLogger;
}
Expand Down Expand Up @@ -799,6 +799,61 @@
public override event EvaluationFinishedEventHandler EvaluationFinished;

private bool registeredUnwrapMarshaler;
private const string ConnectionNodeCompatSentinel = "__dspynet3_connnode_compat__";

/// <summary>
/// Compatibility shim for "node-first" static methods exposed by some Dynamo/Revit libraries.
/// In older engines these could be invoked like instance methods (e.g. node.SubNodesOfSize(2)).
/// Python.NET 3 binds static methods strictly, so we patch a small set of known APIs to keep
/// existing graphs working.
/// </summary>
private static string ConnectionNodeCompatPatchCode()
{
return $@"
import builtins as __builtins__
try:
from AdvanceSteel.ConnectionAutomation.Nodes import ConnectionNode as __ConnectionNode
except Exception:
__ConnectionNode = None
if __ConnectionNode is not None:
if not getattr(__builtins__, '{ConnectionNodeCompatSentinel}', False):
def __dspynet3__patch_connnode_instance(__obj):
# Attach instance-callable wrappers for node-first static methods.
try:
if not isinstance(__obj, __ConnectionNode):
return
def __subnodes(__n, *args, __obj=__obj, **kwargs):
return __ConnectionNode.SubNodesOfSize(__obj, __n, *args, **kwargs)
def __existing(*args, __obj=__obj, **kwargs):
return __ConnectionNode.ExistingConnections(__obj, *args, **kwargs)
try:
setattr(__obj, 'SubNodesOfSize', __subnodes)
except Exception:
pass
try:
setattr(__obj, 'ExistingConnections', __existing)
except Exception:
pass
except Exception:
pass
def __dspynet3__walk_and_patch(__x):
try:
if isinstance(__x, (list, tuple)):
for __i in __x:
__dspynet3__walk_and_patch(__i)
else:
__dspynet3__patch_connnode_instance(__x)
except Exception:
pass
setattr(__builtins__, '__dspynet3__walk_and_patch_connnode', __dspynet3__walk_and_patch)
setattr(__builtins__, '{ConnectionNodeCompatSentinel}', True)
try:
__inp = globals().get('IN', None)
__builtins__.__dspynet3__walk_and_patch_connnode(__inp)
except Exception:
pass
";
}

/// <summary>
/// Called immediately before evaluation starts
Expand Down Expand Up @@ -844,6 +899,8 @@

registeredUnwrapMarshaler = true;
}

scope.Exec(ConnectionNodeCompatPatchCode());
}

/// <summary>
Expand Down
Loading