Rhino Python Devs, please help.
Whilst the new script editor on Rh8 is a game changer with Python3 support, there are a number of show-stopping issues at the moment that have recently worsened.
For the last two Rhino WIP versions (since at least 8.0.23248.12306, 2023-09-05), I have found Python on Grasshopper on the Mac unusable due to constant crashes and a number of bugs.
1 . Reproducible crash while editing Rh7 GHPython component in Rh8 (Mac)
(Please see attached gh test file)
The main issue lies with editing any GHPython (rhino7) component. As an example, I uploaded an empty grasshopper file saved in Rhino 8 containing a single, default Rhino 7 GHPython component (created in Rhino 7). Whilst it runs correctly in Rhino 8 (as do all my Rh7 GHPython components, no matter how complex), ANY edit will crash Rhino. If you open the component, make any edit at all, close it, and click ‘Yes’ to save, Rhino will crash. This is reproducible on my system with brand new files and components. The only way to edit the code, is by attaching a file reader to the input, editing externally, and then internalising the data. This works.
Rh8 script component not recognising custom external modules (Mac and Windows)
While trying to debug this, I attempted to move Rhino 7 GHPython code into the new Script Editor under Python 2. Again, there is a bug here, of a different sort that will affect several plugins and gh definitions. In this case, the Script component will fail if it does not recognise a module - it expects them all to have been installed in its environment (presumably with
# r: lib). A common way of using python external or custom modules in Rhino 7 was simply to append to the Python library path in the code (
sys.path.append(custom_site_packages). This does not work in the new script editor (in Py3 or Py2).
I have this in a try except clause within an if statement checking whether the path has already been appended - the code never reaches this point. If I try and force the append by removing try and if, the directory get appended to the sys.path and the module gets recognised, but does not work properly. These are pure python modules without external dependencies (granted, I did not check if the Py2 version in Rh8 is different to Rh7)
Please remove --update in python install default and fix windows installs
In the case of windows system, a working gh file on the mac will fail. The culprit here is Rhino on windows fails to install some python requirements (i.e. pandas). We tried enforcing specific pandas versions but this still would not work. Our current workaround is to install these libraries in a specific order. This works as long as we remove the
# r: pandas line after install (otherwise Grasshopper will retry an install later, presumably due to the update clause, and corrupt the environment). Beyond fixing the issues on Windows, there should be a way to have more control over an # r: clause (update, cache, build from source - all pip clauses should be accepted here).
Geometry trees with empty or null branches cause an exception in script editor (Py3)
Tracked an exception (instance not found) to any Tree input connected to any geometry component feeding a tree with either nulls or empty items. Cleaning the tree would solve the issue. Replacing the tree with an identical (non-geometry) tree with empty or null items would also solve the issue. Problem is, at the very least, null items in geometry component should be allowed to be fed into Python.
Would appreciate help on these, and confirmation that they are reproducible on your systems.
Attached is a simple grasshopper file saved in Rhino8 containing a
print("test") line within a GHPython component. Any edits to this code will crash Rhino on my system.
Thanks for any help.
crash_test.gh (2.3 KB)
There were many fixes in this area in the last few days. I can’t reproduce 1. anymore so the next release should have solved it.
We’ll look at the points 2, 3, and 4 that you bring up.
Hello and thanks for the great feedback. Here are some thoughts and bug fixes:
- R8 Python 2 is the same as R7 (IronPython 2.7.11). I fixed a bug in the way the value for
__file__ was setup and now a script like below correctly adds the path to
sys.path and imports the external library. Of course you have to make sure the library is compatible with python 2:
import os.path as op
p = op.join(op.dirname(op.dirname(__file__)), "custom_libs")
# make sure not to add the path too many times
if p not in sys.path:
- If you are handling package management yourself, do not use the
# r: pattern to ask the script editor to install the packages for you as it will update to the latest or specify the exact version like `# r: numpy==1.2.3"
Let me know what kind of errors you are seeing especially with installing
- Would you mind sharing a case that shows the error? I don’t see this in my unit tests. A tree with
<null> values fed into the component just passes them thru
Thanks for looking into this @Alain @eirannejad
Great to see we can add paths to sys.path again. A lot of Rh7 scripts used this.
In terms of issue 3:
We’re not handling package management ourselves yet (we were in Rh7). We were hoping to work with the
# r: pattern to take care of management. I see an issue here though with cross-compatibility between windows and mac. We sometimes require different packages depending on the platform, or they need to be installed in different ways. Previously, when we handled package management ourselves, we would take care of this inside an if statement that checked for the platform type. It does not seem possible to do this with the
# r: pattern.
3b: The errors installing pandas only occur on windows. There are two. One is an ‘unknown locale error’ followed by a hashtable error upon iport. We can fix this by adding a
locale.setlocale(locale.LC_ALL, 'en-US.utf8') (or en_US.UTF-8) before calling the install or import.
The other error in installing pandas on windows is related to missing dependencies. It seems that pip does not install all the necessary requirements for pandas (not sure why). This happens with other libraries as well. On mac, i can just type pandas and geopandas. On windows, we have to specify some extra packages first (packaging, pyproj for pandas / geopandas). A good example is mapclassify and matplotlib. Those also require some of their dependencies to be explicitly installed first.
- The error only occurs when trying to feed script editor running python 3 (with a tree input) a tree containing geometry objects with empty or null branches. It does not occur with any other object type (strings, integers are fine).
Here’s a MWE of the tree issue in python. The script component is empty. (gh file attached):
geom_plus_empty_tree.gh (7.0 KB)
I fixed and will be available in next build. Thank you!!
can we use specific python environments created through conda or mamba while using the python script editor?
Not really. You can add a folder path with Python dependencies and add these to the Python path if you must, but these should be pure Python libraries without c dependencies (I.e. no numpy or similar). It’s a way of keeping control or using different libraries or versions for different platforms (see ladybug GitHub repo for examples). This was what we did in rhino 7, but in rh8 we’re just installing straight. Not sure how this will work when people start using gh files each wanting to install different libraries……
Thanks @eirannejad . Makes it much easier not having to worry about those geom trees.
As long as the modules run in python 3.9 you should be good. Add the path to
sys.path and test it out
Is python 3.9 the upper limit for support with WIP as of now?
Yes that is the python we will ship Rhino 8 with as of now. Moving to 3.11 is more challenging with the pythonnet wrapper library so that will happen later. I’d really like to get the crux of running python 3 in a dotnet application fixed and stable before attempting for more