I wonder what the expected behavior is when multiple Grasshopper Python3 components try and pip-install dependencies with different versions? How should we anticipate that the system will behave in that case?
For instance, what if I have a GH definition that includes one component like:
How would the system work in that case? Would the ‘last’ component to run win and get its version installed? Or would the second component be ignored and the first version installed gets preserved?
From my own tests, I get some slightly odd behavior, which is why I wonder how it is ‘supposed’ to work?
Example 1:
If I install v1.10, it installs v1.10. That’s good
However, if I install v1.10 first, then install v2.4, it appears to install v2.4 within the site-env directory, but the interpreter continues to show v1.10:
I would try using #: env to control the isolation and installs, but if sys.modules is shared between CPython components like the Iron Python ones, I would create shell wrapper libraries with a different name for any non standard versions.
However this will rapidly lead to a situation where there’s little advantage in using the automagical #r: syntax and pip, and is likely to make it worse, as you’re not in control of what’s being imported and installed, nor where.
My two pence is: Running multiple library versions together is a terrible idea that will inevitably lead to dependency hell (the whole reason venvs etc were invented in mainstream Pythons).
Getting multiple versions to work together to their satisfaction is the user’s problem. Devs should feel under no obligation to support this.
Number 3) is a only a ‘venv’. It’s a great tool for users. It is not provide isolation like actual venvs. Nor is it a fool proof way of running multiple versions of a single dependency together. I would advise renaming this feature.
Until the fundamental architecture is changed, in Grasshopper, everything is in a single shared. The ‘venv’ isolation only exists for the first component to import a module. After the first version of a module is imported, that version is cached in sys.modules, where all other components that also want to import it will get it from.