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
|
pythonpath = os.environ.get("SNAP_PYTHONPATH") |
|
if pythonpath: |
|
print(f"Adding snap-specific PYTHONPATH to sys.path: {pythonpath}") |
|
os.environ["PYTHONPATH"] = pythonpath |
|
for path in pythonpath.split(":"): |
|
sys.path.insert(0, path) |
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:
|
PYTHONPATH: &pypath $PYTHONUSERBASE/lib/python3.10/site-packages:$SNAP/lib/python3.10/site-packages:$SNAP/usr/lib/python3/dist-packages |
|
SNAP_PYTHONPATH: *pypath |
In summary, Python packages are forever pinned to the version preinstalled with the snap.
The snap comes with a series of Python modules preinstalled, which on the host system are installed at:
The user can install new Python modules using the provided
freecad.pipcommand. Those modules are then installed at: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.As expected, we then end up with:
If we then import ifcopenshell from the Python console within FreeCAD:
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:
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:
Returns PYTHONPATH, of which here's an edited extract:
Notice how
/snap/freecad/1296/usr/lib/python3/dist-packagesis listed first, instead of$HOME/freecad/common/.local/lib/python3.10/site-packagesRunning this snippet from FreeCAD's Python console:
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 thatSNAP_PYTHONPATHis a custom environment variable that we define insnapcraft.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.