What is says on the tin.
I have solved the mystery of how sys.prefix
gets set when using a virtual environment (Python looks for a pyvenv.cfg
file [1]).
However, I don't understand exactly how Python finds sys.base_prefix
.
The default is /usr/local
(on Unix) [2].
However, that doers not seem to be in effect on my Mac.
As the code below shows, symlinks are followed, and in this case the sys.base_prefix
is simply the directory above the actual Python binary:
# Following symlinks to determinw where the actual hard link is
➜ tmp ls -l /usr/local/bin/python3
lrwxr-xr-x 1 jeffhemmen admin 38 23 Jul 12:23 /usr/local/bin/python3 -> ../Cellar/[email protected]/3.8.5/bin/python3
➜ tmp ls -l /usr/local/Cellar/[email protected]/3.8.5/bin/python3
lrwxr-xr-x 1 jeffhemmen staff 55 20 Jul 14:26 /usr/local/Cellar/[email protected]/3.8.5/bin/python3 -> ../Frameworks/Python.framework/Versions/3.8/bin/python3
➜ tmp ls -l /usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/bin/python3
lrwxr-xr-x 1 jeffhemmen staff 9 20 Jul 14:26 /usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/bin/python3 -> python3.8
➜ tmp ls -l /usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/bin/python3.8
-rwxr-xr-x 1 jeffhemmen staff 17704 23 Jul 12:23 /usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/bin/python3.8
# Printing sys.base_prefix for all these links
➜ tmp /usr/local/bin/python3 -c "import sys; print(sys.base_prefix)"
/usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8
➜ tmp /usr/local/Cellar/[email protected]/3.8.5/bin/python3 -c "import sys; print(sys.base_prefix)"
/usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8
➜ tmp /usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/bin/python3 -c "import sys; print(sys.base_prefix)"
/usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8
➜ tmp /usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8/bin/python3.8 -c "import sys; print(sys.base_prefix)"
/usr/local/Cellar/[email protected]/3.8.5/Frameworks/Python.framework/Versions/3.8
However, in the example below (same computer, my Mac), the sys.base_prefix
is completely different:
➜ tmp ls -l /usr/bin/python3
-rwxr-xr-x 1 root wheel 31488 10 Aug 21:56 /usr/bin/python3
➜ tmp /usr/bin/python3 -c "import sys; print(sys.base_prefix)"
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.7
I have read somewhere that this depends on how Python was installed. Does this mean the sys.base_prefix
is actually compiled into the binary? If not is there a text file (config, .py, ...) somewhere that Python reads upon startup?
Bonus question: when/how/why is sys.exec_prefix
actually different from sys.prefix
(and/or sys.base_exec_prefix
from sys.base_prefix`)?
The documentation explains how the values are set and how a virtual environment overrides it.
Here is the source code for the sys module, and it seems to be set at initialization from the interpreter state. I didn't follow that path further.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With