InvalidCastException: Dictionary in Rhino 8 GH Python3 Script Component

When passing a list of dictionaries to the Python3 GH Component (no type hint), I get an InvalidCastException:

System.InvalidCastException: Unable to cast object of type 'System.Collections.DictionaryEntry' to type 'System.Collections.Generic.KeyValuePair`2[System.Object,System.Object]'.
   at Rhino.Runtime.Code.Languages.PythonNet.CPythonCode.Execute(RunContext context)
   at Rhino.Runtime.Code.Code.ExecTry(RunContext context, IPlatformDocument& doc, Object& docState)
   at Rhino.Runtime.Code.Code.Run(RunContext context)

This was not the case for Rhino7’s Python2 component:

What am I missing?

Great catch! Will get of fixing it right now

RH-80321 dotnet Dictionaries sometimes fail to convert to python

1 Like

Fixed for Rhino 8.4

1 Like

RH-80321 is fixed in Rhino 8 Service Release 4

A post was split to a new topic: Grasshopper hangs with Py3 Component


I continue here since this problem seems related?

Ooff this is not good. I can replicate this and will put a fix in 8.7

RH-81521 Dictionary conversion to and from python 3 dict fails to grab values

Thanks for testing this out

In the meantime, Shift+RighClick on Python 3 components and “Avoid Marshalling Outputs” for the first component. This way the native Python 3 dict object will be passed between the two components with no marshalling overhead. This is better when the dictionary output is not being used by non-python3 components in the definition.

test_params_marshalling_python_dict_noMarshalling.ghx (55.1 KB)

Here are the options on the first components:

Rhino_8DQ2tE5rhU

Update:

Note that with marshalling disabled, python native objects are carried in Grasshopper wires. Be mindful that if you set Access Kind on the input of any receiving components to List or Tree, the pure python object is still going to be converted into a dotnet list.

I will improve the UX on this to make more clear and simpler to use

Pushed a fix for this in next 8.7 build

Thank you for guidance!

RH-81521 is fixed in Rhino 8 Service Release 7 Release Candidate

Nice that this has been fixed!

Any plans on making dictionaries a native data type in Grasshopper?
I use the trick of passing dictionaries in a list from python A LOT, but it always seems hacky…
Dictionaries are such a clean and efficient way of organizing data, compared to multiple parallel lists or trees. Especially when working several people in the same script.

Classic example:
I import some objects from Rhino, they have user text on them that give me some individual settings for the GH algoritm.
In GH I want to have a clean code where the settings and geometry flow along together and in sync.

The standard GH way seems to be to pass multiple lists in parallel or make a data tree (neither of which are clean solutions).
I then have to keep track of all settings by index instead of name, which is a nightmare when cooperating on scripts.

The dictionary hack mentioned allows me to collect each object as one dictionary in python, with each setting as a key-value pair.
When I pass it along in GH as a list, each item in the list is a dictionary including all I want (and allows me to avoid complex data trees).

In related threads like this one it’s suggested to make a class instead.
This works, and I can put the settings and geometry as attributes on an instance, but I then have to define a class in each python component creating these instances.

Since dictionaries is such an established system, that enables very clean data structures, I really miss it in the native GH system…

1 Like

and just to confirm as well… RH-81521 is fixed in Rhino 8 Service Release 7 now.