Script Editor cast to No Type Hint

hi @eirannejad ,

I’m struggling with outputting c# objects from the new python editor.

See attached screenshot. This works fine in the legacy one but not in the new ones CPython and IronPython tested.

Seems some casting is going on, but maybe we can skip it?

slightly related to Rhino 8 Script Editor Default Type Hint - #3 by eirannejad

edit: adding exception text in case other are searching for it:

Traceback (most recent call last):
Exception: Parameter "a" type conversion failed from EP_Room to No Type Hint
Rhino.Runtime.Code.Execution.ParamConvertException: Parameter "a" type conversion failed from EP_Room to No Type Hint
   at Rhino.Runtime.Code.Execution.ParamValue.ConvertValue(ConvertDirection direction, Boolean resetOnError, String name)
   at Rhino.Runtime.Code.Execution.ParamValueSet.Convert(ConvertPolicy policy, ILanguage language)
   at Rhino.Runtime.Code.Code.Run(RunContext context)
Rhino.Runtime.Code.Execution.ExecuteException: Parameter "a" type conversion failed from EP_Room to object
 ---> Rhino.Runtime.Code.Execution.ParamConvertException: Parameter "a" type conversion failed from EP_Room to object
   at Rhino.Runtime.Code.Execution.ParamValue.ConvertValue(ConvertDirection direction, Boolean resetOnError, String name)
   at Rhino.Runtime.Code.Execution.ParamValueSet.Convert(ConvertPolicy policy, ILanguage language)
   at Rhino.Runtime.Code.Code.Run(RunContext context)
   --- End of inner exception stack trace ---
Rhino.Runtime.Code.Execution.ParamConvertException: Parameter "a" type conversion failed from EP_Room to object
   at Rhino.Runtime.Code.Execution.ParamValue.ConvertValue(ConvertDirection direction, Boolean resetOnError, String name)
   at Rhino.Runtime.Code.Execution.ParamValueSet.Convert(ConvertPolicy policy, ILanguage language)
   at Rhino.Runtime.Code.Code.Run(RunContext context)


best, Mathias

Tried setting avoid marshalling guids. But somehow it cannot be casted to object.

That is super weird. Everything is an object do that cast should not fail. Something about EP_Room data type makes the cast fail. Would it be possible to share/DM the script and the dlls so I can test and debug?

I am assuming the LINK_EP libraries imported are all dotnet assemblies right?

Yes all dotnet.

My EP_Room inherits from EP_Object:

public abstract partial class EP_Object : UserData, INotifyPropertyChanged, IGH_Goo, IGH_GeometricGoo, IGH_PreviewData, IGH_BakeAwareObject, IComparable<EP_Object>, IDictionary<string, object>
{
}

My EP_Room is

Wrapping it in an EP_RoomParam

public class EP_RoomParam : GH_PersistentParam<EP_Room>, IGH_PreviewObject, IGH_BakeAwareObject
{
} 

kind of works, see:

# hacky, gets some autocasting I guess
b = EP_Room()
wrapper = LINK_GH.EP_RoomParam()
wrapper.SetPersistentData(b)
a = wrapper.PersistentData

Sending the gh and dlls in DM

Sidenote: Works fine with another NET object as you described, see screenshot

The issue was my EP_Room was implementing IDictionary which is also an IEnumerable.

So the automated casting in the scriptcomponent would export any IEnumerable into a list rather than the object itself (i assume)

So my one EP_Room became a list of my dictionary values, and then caused some null handling exceptions in the methods generating that list.

All in all, I guess the script components ToObject casting works but with minor exception handling messaging if outputting an IEnumerable.
Still not 1:1 behavior of the old component but I guess it should do :slight_smile:

2 Likes

I’m not sure if this is exactly related, but I’ve had luck using good ol’ GH_ObjectWrapper when outputting gets fucky with the new script editor. I would assume it also helps speed things up when outputting many objects (i.e. like it does in GhPython), but haven’t tested that conjecture yet:

1 Like

This works perfectly also, Anders!

1 Like

I just checked the files you DM’d and this is exactly the issue. This is definitely a departure from the older script component. The new script component has converters on the outputs so when publishing these components as plugins they can convert types correctly.

The output converter is being to smart about handling the output data and special-cases some things to match legacy behaviour:

I would say wrap the ‘IEnumerable’ data as a parameter as you did if you don’t intend it to be expanded. I created a ticket here to add a flag to the output to Do not Expand Enumerables. Or maybe customize these converters per language so they can detect language-specific list and dictionary types

RH-86062 Add flag to avoid auto-expanding IDictionary and IEnumerable on output parameters

Thanks for quick followup! Love it.

I see it’s a trade off whether you want to hold peoples hands and expand it for them or prioritize legacy behavior. Tough one!

Another legacy behavior is that you export a pythonlist it would show something like PythonList<xx>.
and if I inputted that into an empty python component with the code “a=x” then it would auto expand into a gh list in the ‘a’ output. So your above fix may actually ruin that. I don’t remember the details at hand though.

1 Like