Rhino scripts default install path is wrong for Rhino 8
Opened this issue · 15 comments
python -m compas_rhino.install
adds the COMPAS packages to ~/.rhinocode/py27-rh8/Lib/site-packages
instead of \AppData\Roaming\McNeel\Rhinoceros\8.0\scripts
. Grasshopper components cannot then import the modules.
there is a workaround which is to include
pt = r"C:\Users\obucklin/.rhinocode/py27-rh8/Lib/site-packages"
if pt not in sys.path:
sys.path.append(pt)
at the top of a python component. This fixes IronPython components.
I'm not sure if it's the same problem, but cpython components built with invoke build-cpython-ghuser-components
do not instantiate on the canvas and result in a User Object failed to deserialize
error:
Windows 11
Rhino 8 SR6 2024-4-10
COMPAS 2.1.0
Thanks!
I guess ScriptEditor usage for Rhino8 is still experimental as stated in the Compas documentation:
compas/src/compas_rhino/install.py
Line 35 in 08f0624
Python library installation directory and Grasshopper are two different directories.
What works for me is following:
Grasshopper for ScriptEditor Rhino8 CPython on Windows:
python src\rhino\gh\componentize_cpy.py src\rhino\gh\cpy %APPDATA%\Grasshopper\UserObjects
on mac
python src/rhino/gh/componentize_cpy.py src/rhino/gh/cpy "/Users/petras/Library/Application Support/McNeel/Rhinoceros/8.0/Plug-ins/Grasshopper (b45a29b1-4343-4035-989e-044e8580d9cf)/UserObjects"
or the package manager directory (manual upload to Rhino).
The python libraries I install as described in compas main page:
https://compas.dev/compas/latest/userguide/cad.rhino8.html
When a library is ready, I do it via pip, since this is the only possible solution to link a library in script editor is via # r:
keyword.
Conda environments will be supported "maybe" in the future. This whole thing is painful, but at least it is CPython not IronPython...
@petrasvestartas I followed this thread and it suggests adding # env: /path/to/site-package
to the script to enable using that environment in Rhino. After adding this line, there's no need to use # r: module
.
I used conda
to create an environment with the same Python version as Rhino 8, then installed compas
and compas_fab
packages. I tried importing the modules, and they worked successfully.
While I haven't investigated this further, it seems like a viable workaround to make conda
work with Rhino 8.
This is very good news! Thanks @ChiaChing-Yen !
I've run into the same issue: compas
explicitly installs in the ironpython
folder (/.rhinocode/py27-rh8/Lib/site-packages
vs /.rhinocode/py39-rh8/Lib/site-packages
, over rhino3
, which seems at odds with the herculean effort of the compas team working towards python3
compatibility.
# In Rhino 8 there is no scripts folder
if version == "8.0":
installation_path = compas_rhino._get_default_rhino_ironpython_sitepackages_path(version)
else:
installation_path = compas_rhino._get_rhino_scripts_path(version)
So @obucklin suggestion makes perfect sense to install into the scripts
directory, so just factoring out the if statement should resolve things:
In [6]: compas_rhino._get_rhino_scripts_path("8.0")
Out[6]: '/Users/jelle/Library/Application Support/McNeel/Rhinoceros/8.0/scripts'
In my view, this is a pressing issue, given that compas
is getting increasing less / incompatible with ironpython
and the considerable hinderance associated to running iron python (no numpy etc). To speak for myself: python3
compatibility was more then sufficient reason to move to rhino 8 ;)
not sure i understand what is being proposed.
the current installation mechanism is not wrong. in Rhino 8, COMPAS packages should indeed be installed in the site packages folder of the Python flavour and version you intend to use. there are two reasons for this.
- if the scripts folder is used we can't differentiate between IronPython and CPython installs. using the scripts folder can create really weird clashes between packages and package versions that are difficult to debug.
- specifically for CPython installs,
pip
can now be used to install packages directly from the Python Package Index. if we install packages in the scripts folder using symlinks as we did with older versions of Rhino, this installation mechanism no longer works properly.
if there are other problems with correct versions of packages not being found by other components of Rhino, i would prefer trying to solve those problems specifically. changing the installation mechanism is not the solution in my opinion...
Sorry, I'm late for the party.
I made #1384 and only then saw this thread after..
@tomvanmele could you please elaborate on point 1.? I don't quite get it.
I find installing compas to 3 places is necessary in Rhino8 as there seems to be 3 different interpreters (or 2 in 3 environments):
- Legacy IronPython (
Old
label) - IronPython (this is both new GH IronPython components and the EditPythonCode diaglog in Rhino)
- CPython
And the corresponding locations are:
McNeel/Rhinoceros/8.0/scripts
py27-rh8/Lib/site-packages
py39-rh8/lib/site-packages
I do agree we should utilize the pip
mechanism that's now made possible but I had some weird issue happening when I tried it out with compas_rhino.install_with_pip
plus I think it should eventually be integrated into the compas_rhino.install
.
Another related issue I'm having is I cannot for the life of me import compas_ghpython
in a python3 components. It doesn't matter if I install via pip or with symlinks. Just getting this persistent NotSupportedInGHException
. It seems to be for some call related to layers but even removing all those I could find didn't get me anywhere.
Any of you stumbled upon that or had better luck?
can we either close this issue or add an update about the current status?
based on some of the questions i have been receiving it is a source of confusion for people...
We need to fix the GH components situation in order to really close this as solved. Right now, GH components of extensions (including those few ones in core), do not work on rhino 8.
not sure if they are helpful, but here are a few thoughts...
Rhino CPython (py39)
Basic users should use the default installation mechanism provided by Rhino, using # r: compas, ...
.
#! python3
# r: compas, ...
Different combinations of requirements for different projects can be isolated from each other using # venv: ...
.
#! python3
# venv: projectA
# r: compas, ...
More advanced users may want to/need to use pip
directly themselves instead of using # r: ...
. There are two options:
- use Rhino's
pip
- use the
pip
of a external (conda
) environment with the correct--target
.
the target directive can also be combined with the usage of Rhino's pip
to install packages into specific venv
. not however, that Rhino adds a random string to the names of the virtual environments in site-envs
(don't know why) and that you need to know what this string is in order to use --target
properly.
Rhino pip
Install compas
into the default site-env using Rhino's pip
, directly from PyPI:
~/.rhinocode/py39-rh8/python3.9 -m pip install compas
Install compas
into a specific site-env ("projectA") using Rhino's pip
, directly from PyPI:
(The random string i used ("projectA-htl4ZgZ0") will be different for everyone, and needs to be looked up first.)
~/.rhinocode/py39-rh8/python3.9 -m pip install compas --target ~/.rhinocode/py39-rh8/site-envs/projectA-htl4ZgZ0
The same can be done with source installs into the default or a specific site-env:
cd path/to/compas
~/.rhinocode/py39-rh8/python3.9 -m pip install .
cd path/to/compas
~/.rhinocode/py39-rh8/python3.9 -m pip install . --target ~/.rhinocode/py39-rh8/site-envs/projectA-htl4ZgZ0
NOT Rhino pip
Instead of using Rhino's pip
, you can also use the pip
of an external environment you might be working in (ideally this environment is based on Python 3.9, but depending on the requirements of the packages you install this is not always absolutely necessary). however, in this case --target
is not optional, even for the default site-env.
conda activate compas-dev
cd path/to/compas
python -m pip install . --target ~/.rhinocode/py39-rh8/site-envs/projectA-htl4ZgZ0
Using an external environment directly as suggested above (using # env: path/to/site-packages
) is not something i have been able to get to work, but i have only tried it on Mac. In any case, i doubt it will work for packages that are built and have build requirements like compas_cgal
.
Rhino IronPython
the "py27-rh8" folder has a very similar structure as the one of "py39-rh8" so i assume that at least the installation procedures listed above that use local source will work as well, but i haven't tried this...
GH
About Grasshopper i have no idea, but i can confirm that Python 3 components have access to the same "site-envs" as the Rhino ScriptEditor.
That is my understanding of the situation as well.
We're basically retiring the compas_rhino.install
mechanism, where, starting from Rhino8, you're expected to install compas inside Rhino as you described above.
I find the instructions in https://compas.dev/compas/latest/userguide/cad.rhino8.html pretty clear and complete.
Perhaps we should remove the Rhino8 switch from compas_rhino.install
so that it's not used as well as provide some kind of an uninstall script to allow removing COMPAS symlinks from AppData\Roaming\McNeel\Rhinoceros\8.0\scripts
in case anyone has them there. This as a replacement for this PR #1383 if @tetov agree.
Once we've dealt with that, I'm fine with closing this issue.
Regarding Grasshopper
I think the way forward is components with #r: ..
in header and that are distributed as YAK packages over Food4Rhino.
We'd probably need to separate the IPY and CPython component definitions and make some changes to compas_invocation2
as well as integrate that to the componentizer action.
We're currently trying this out with COMPAS Timber. still some things that used to work differently in Rhino7 we're struggling with. will update.
For completeness sake I'll just mention that this #r: ...
syntax doesn't quite work for me in the IronPython components in Rhino8. maybe I'll post in the mcneel forum.
Finally there's the legacy ironpython components which perhaps we shouldn't support.
Maybe we can post updates about the Grasshopper situation somewhere, pinned discussion in the forum? a new issue?
One open question for me is how to continue supporting Rhino7 Grasshopper component installation. If we continue installing the user objects to the same place we do now (AppData\Roaming\Grasshopper\UserObjects
) the components appear in both Rhino7 and Rhino8..
Evidently, you can get Grasshopper plugins for Rhino7 over Food4Rhino they are then presumably installed to \AppData\Roaming\McNeel\Rhinoceros\packages\7.0
, but how they manage python library dependencies I have no idea.
it sounds like AppData\Roaming\Grasshopper\UserObjects
is more or less the equivalent of the scripts folder. can we not install directly into AppData\Roaming\McNeel\Rhinoceros\packages\7.0
?
that way 7.0 and 8.0 are cleanly separated, which allows us to use different installation and dependency management approaches in both cases...
Agree.
to sum up and make actionable I propose the following (I can make the changes)
compas_invocations2
add ability to distinguish between component source for ironpython and cpython (as these will most likely need to co-exist)compas-actions.ghpython_components
add theyakerize.py
script (thanks @9and3!) to the componentizer and expose it via the github actioncompas_invocations2
addyakerize
invoke command to allow local packagingcompas
- remove the8.0
flag fromcompas_rhino.install
compas
- add cpython compatible copy of the components tocompas_ghpython\components_cpython
compas-actions.build/publish
- extend to build yak packages for rhino7 and rhino8
when using YAK, components are installed to AppData\Roaming\McNeel\Rhinoceros\packages\7.0
and ...\8.0
the Rhino8 components need to have #r: compas
at the top which will take care of the python dependencies.
Rhino7 components would need the good old compas_rhino.install -v7.0
to have their dependencies available (AKA symlinks in \AppData\Roaming\McNeel\Rhinoceros\7.0\scripts
)
@tetov ping
@chenkasirer just fyi...
when releasing the new version of RhinoVault through Yak, we noticed that, at least on the Rhino side, you have to be careful with the requirements inside the command scripts. for some strange reason, even if there are no conflicts between versions, having compas
listed alongside other requirements which in turn listed compas
as one of their requirements in their requirements.txt
made the commands reinstall all requirements every time they were run. once we removed compas
from the list, the problem went away...
the problem didn't occur as long as we were using locally build packages.
for example, a script with # r: compas, compas_tna, compas_session
would trigger this behaviour.
however, the same script with # r: compas_tna, compas_session
would not...