I am trying to install packages to a virtual environment, and then uninstall them when I made a mistake.
In the script editor, I have found the Open Python 3 Shell. When running python there, it doesn’t have numpy installed, so I tried looking for a venv activate file, but the site-envs seems to just be a folder.
From what I gather, there aren’t really virtual environments, just directories with names on them.
The issue I have is managing the env: directive at the top of a python script. This seems to be persistent, or is corrupting something. I’m not sure what about running a script is causing the issue, but it essentially is:
A local project folder that has scripts and calls a module in that folder.
Open one of those scripts in the Script editor, run it.
this works fine. I suspect because it is using the file/script directory (maybe relative path context?)
Copy that same files code, and put in the script editor directly to run.
to compensate for the local module, I add the path of the file i copied into env: path/to/file
this causes permanent crashing, until the editor.json is deleted
You are correct. The subfolders under site-envs are not virtual environments. It is key to know that you are running in a single long-running process. So one a version of numpy libraries are loaded, loading another version causes conflicts.
The site-env folders are designed to allow multiple package versions and their dependencies to be installed separately from each other. Each folder can contain a combination of packages required by one of your scripts. But you still need be aware of multiple versions of the same library loaded in Rhino:
Imagine this scenario:
file script_a.py requires numpy version 1
file script_b.py requires pytorch version 2 which is dependent on numpy version 2
On a clean Rhino, running script_a installs and loads numpy v1
On a clean Rhino, running script_b installs and loads pytorch + numpy v2
Conflict:: Currently running script_b right after script_a might cause conflicts since numpy v1 is already loaded. So when pip wants to uninstall numpy v1 to install numpy v2 on windows it fails to delete numpy’s native libraries that are loaded in Rhino memory as these files are locked.
Workaround: Specify a venv: some-env-name at the top of your scripts. This will create a subfolder under site-env for this script and installs the packages there. And since there is no numpy v1 is installed in this folder there is no install conflict.
Now all the packages required for the two scripts are installed. You still need to run each script in a fresh Rhino instance since you need to make sure two version of numpy are not loaded at the same time. But the separate environments cache the necessary packages so they don’t need to get installed-uninstalled every time you are running multiple packages with different package requirements.
I would advise against manually adding the paths to these folders to your script. Just use the venv: specifier. Note that env: is different from venv:
Python Shell
When using the python shipped with Rhino, in the python shell, and manually adding/removing packages, you need to specify the --target which is the subfolder inside site-envs directory. The prompt on the shell has a note for this. See highlighted text below:
It was not script_a then script_b, it was script_a twice in a row.
I think the terminal is confusing for me for a few reasons;
there is no site-packages under libs folder.
When running python.exe, I would expect the modules installed to be part of it. I guess this has something to do with this sort of runtime loading.
a. but typically executing python.exe and in that environment I should import numpy, when it is part of the pip-installed modules
b. since this is framed as ‘a single long-running process’, I would expect it to have all installed modules available
So, how could I start the python instance in the terminal, where it is pulling the modules from the folders?
Some unsolicited and uninformed , respectfully, thoughts/questions on, ‘why not do…’:
Maybe loaded modules can be tracked with modulefinder and/or sys dictionary, then 1. Raise a warning, but use an existing module instance instead of installing to a new ‘pseudo’ environment or 2. raise an exception when there are requirements set at the script level with conflicting module versions (i.e. numpy 1.12 is already loaded, but user puts # r: numpy==1.13 in their own script.
I just got this documented here with some sketches/images to explain. Take a look and see if it makes sense. I am all for making improvements and getting the package conflict issues resolved. You definitely should have a site-packages directory as pip and some other utilities are installed there. It is under ~/.rhinocode/py38-rh8/lib/python3.9/site-packages on macOS and %USERPROFILE%\.rhinocode\py38-rh8\lib\site-packages on Windows: