Python3 in Rhino 8 execute function error

Hello,

I’ve managed to execute a .py through Grasshopper in Rhino 8. The idea is that eventually the “x” and “y” inputs are float values from a larger workflow.

When I run the file in a terminal within visual studio code to test, two values are returned consistently as shown:

However, when I run the same code in GH, the value seems to add the previous returned value each time it is executed (nothing else changed):


image
image
image

Any advice on why this may be happening? Thank you!

Don’t you see the same thing in a REPL session, started from the command line?

userfunctions.importSources is not pure functional code, it’s keeping some kind of internal state that is not being cleaned up by the end of the function’s call.

Invoking CSCalculator.py from the command line each time, starts a new python.exe process, and imports userfunctions afresh, for each run. All internal state, of userfunctions and of anything else in the Python process, is lost by the end of the command line script, when the python process terminates.

Unlike the command line, In Grasshopper userfunctions is only imported once, for all executions of the script in that Rhino session. Thereafter the module (and all modules it imports itself) is cached for all CPython processes, including any class instances, global and local variables there in. The first import can occur when the worksheet with that activated component is first loaded, or when the component is first placed, or otherwise, whenever Grasshopper first encounters e.g. “import userfunctions” or equivalent.

Make the simplest example possible based on userfunctions that reproduces this. Otherwise, we need to see the code in userfunctions.

Things get even more complicated writing Python for Grasshopper (even more so than RhinoPython) as more than one Python component importing the same module, and calling userfunctions.importSources could be on the same worksheet.

The return values in the function call in the second component can be determined by however many times the first one has been run.

To ensure Python code is correct for Grasshopper therefore, it’s best to design functions to be Pure Functions if possible.

Or at the very least, functions that clean up any state they create afterwards, and that don’t depend on prior state. I.e. avoid global variables wherever possible.

2 Likes

Thank you for this feedback and information. We ended up modifying the python code so that users can run the analysis multiple times without keeping the internal data.

Thanks again

1 Like