Description
The snap comes with a series of Python modules preinstalled, which on the host system are installed at:
/snap/freecad/current/usr/lib/python3.10/dist-packages/$MODULE
The user can install new Python modules using the provided freecad.pip
command. Those modules are then installed at:
$HOME/snap/freecad/common/.local/lib/python3.10/site-packages/$MODULE
Sometimes it is useful for one of the preinstalled Python modules (e.g. ifcopenshell
) to be upgraded. Be it to fix a bug, or to use a new feature. This works in principle. E.g.
freecad.pip install ifcopenshell
As expected, we then end up with:
/snap/freecad/current/usr/lib/python3.10/dist-packages/ifcopenshell # The version we just installed: 0.8.1
$HOME/snap/freecad/common/.local/lib/python3.10/site-packages/ifcopenshell # The preinstalled version: 0.8.0
If we then import ifcopenshell from the Python console within FreeCAD:
>>> import ifcopenshell
>>> ifcopenshell.__version__
'0.8.0'
Notice how FreeCAD's Python only saw the preinstalled version. When the snap is launched, a message seems to indicate that the user path is searched for before the system path:
Adding snap-specific PYTHONPATH to sys.path: $HOME/snap/freecad/common/.local/lib/python3.10/site-packages:/snap/freecad/1296/lib/python3.10/site-packages:/snap/freecad/1296/usr/lib/python3/dist-packages
FreeCAD-snap/snap/local/snap-setup-mod/Init.py
Lines 5 to 10 in 4e219a7
However, that does not seem to be the case.
Running:
>>> import sys
>>> print(sys.path)
Returns PYTHONPATH, of which here's an edited extract:
/snap/freecad/1296/usr/lib/python3/dist-packages
/snap/freecad/1296/lib/python3.10/site-packages
$HOME/freecad/common/.local/lib/python3.10/site-packages
$HOME/freecad/common/.local/lib/python3.10/site-packages # <= Injected by $SNAP_PYTHONPATH?
/snap/freecad/1296/usr/local/lib/python3.10/dist-packages # <= Injected by $SNAP_PYTHONPATH?
/snap/freecad/1296/usr/lib/python3/dist-packages # <= Injected by $SNAP_PYTHONPATH?
$HOME/freecad/common/AdditionalPythonPackages/py310
$HOME/freecad/common/AdditionalPythonPackages
$HOME/freecad/common/
$HOME/freecad/common
$/snap/freecad/1296/lib/python3.10/site-packages/ifcopenshell/lib/linux/64bit/python3.10
Notice how /snap/freecad/1296/usr/lib/python3/dist-packages
is listed first, instead of $HOME/freecad/common/.local/lib/python3.10/site-packages
Running this snippet from FreeCAD's Python console:
>>> import os
>>> pythonpath = os.environ.get("SNAP_PYTHONPATH")
>>> pythonpath
'$HOME/snap/freecad/common/.local/lib/python3.10/site-packages:/snap/freecad/1296/lib/python3.10/site-packages:/snap/freecad/1296/usr/lib/python3/dist-packages'
That list of paths seems to be injected somewhere in the middle of the PYTHONPATH
. Since it's inserted after /snap/freecad/1296/usr/lib/python3/dist-packages
, it has no effect. Also note that SNAP_PYTHONPATH
is a custom environment variable that we define in snapcraft.yaml
:
FreeCAD-snap/snap/snapcraft.yaml
Lines 92 to 93 in 4e219a7
In summary, Python packages are forever pinned to the version preinstalled with the snap.