¿Desde dónde se inicializa sys.path de Python?
¿Desde dónde se inicializa sys.path de Python?
UPD : Python está agregando algunas rutas antes de hacer referencia a PYTHONPATH:
>>> import sys
>>> from pprint import pprint as p
>>> p(sys.path)
['',
'C:\\Python25\\lib\\site-packages\\setuptools-0.6c9-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\orbited-0.7.8-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\morbid-0.8.6.1-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\demjson-1.4-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\stomper-0.2.2-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\uuid-1.30-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\stompservice-0.1.0-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\cherrypy-3.0.1-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\pyorbited-0.2.2-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\flup-1.0.1-py2.5.egg',
'C:\\Python25\\lib\\site-packages\\wsgilog-0.1-py2.5.egg',
'c:\\testdir',
'C:\\Windows\\system32\\python25.zip',
'C:\\Python25\\DLLs',
'C:\\Python25\\lib',
'C:\\Python25\\lib\\plat-win',
'C:\\Python25\\lib\\lib-tk',
'C:\\Python25',
'C:\\Python25\\lib\\site-packages',
'C:\\Python25\\lib\\site-packages\\PIL',
'C:\\Python25\\lib\\site-packages\\win32',
'C:\\Python25\\lib\\site-packages\\win32\\lib',
'C:\\Python25\\lib\\site-packages\\Pythonwin']
Mi PYTHONPATH es:
PYTHONPATH=c:\testdir
Me pregunto de dónde vienen esos caminos anteriores a los de PYTHONPATH.
EDITAR
Cuando escribí esto en 2015, no había documentación sobre el tema. Ahora hay comentarios, si quieres comprobarlo también. También hay una explicación en prosa del algoritmo en los comentarios getpath.py
del código base. Sigo creyendo que mi respuesta es relevante y relativamente actual.
SIGUE EL TEXTO ORIGINAL
Python realmente se esfuerza por configurar de forma inteligente sys.path
. La forma en que se configura puede resultar realmente complicada . La siguiente guía es una guía diluida, algo incompleta, algo incorrecta, pero con suerte útil para el programador común de Python sobre lo que sucede cuando Python descubre qué usar como valores iniciales de sys.path
,
sys.executable
, sys.exec_prefix
y sys.prefix
en una instalación normal
de Python.
En primer lugar, Python hace todo lo posible para determinar su ubicación física real en el sistema de archivos en función de lo que le indica el sistema operativo. Si el sistema operativo simplemente dice que "python" se está ejecutando, se encuentra en $PATH. Resuelve cualquier enlace simbólico. Una vez hecho esto, la ruta del ejecutable que encuentra se utiliza como valor para sys.executable
, sin condiciones, ni peros.
A continuación, determina los valores iniciales de sys.exec_prefix
y
sys.prefix
.
Si hay un archivo llamado pyvenv.cfg
en el mismo directorio
sys.executable
o un directorio arriba, Python lo examina. Los diferentes sistemas operativos hacen cosas diferentes con este archivo.
Uno de los valores en este archivo de configuración que busca Python es la opción de configuración home = <DIRECTORY>
. Python usará este directorio en lugar del directorio que contiene sys.executable
cuando establezca dinámicamente el valor inicial de sys.prefix
más tarde. Si la applocal = true
configuración aparece en el
pyvenv.cfg
archivo en Windows, pero no la home = <DIRECTORY>
configuración, sys.prefix
se establecerá en el directorio que contiene sys.executable
.
A continuación, PYTHONHOME
se examina la variable de entorno. En Linux y Mac,
sys.prefix
se sys.exec_prefix
configuran en la PYTHONHOME
variable de entorno, si existe, reemplazando cualquier home = <DIRECTORY>
configuración en pyvenv.cfg
. En Windows,
sys.prefix
y sys.exec_prefix
se establece en la PYTHONHOME
variable de entorno, si existe, a menos que haya una home = <DIRECTORY>
configuración presente en pyvenv.cfg
, que se usa en su lugar.
De lo contrario, estos sys.prefix
y sys.exec_prefix
se encuentran caminando hacia atrás desde la ubicación de sys.executable
o el home
directorio proporcionado por, pyvenv.cfg
si corresponde.
Si el archivo lib/python<version>/dyn-load
se encuentra en ese directorio o en cualquiera de sus directorios principales, ese directorio está configurado para estar
sys.exec_prefix
en Linux o Mac. Si el archivo
lib/python<version>/os.py
se encuentra en el directorio o en cualquiera de sus subdirectorios, ese directorio está configurado sys.prefix
en Linux, Mac y Windows, con sys.exec_prefix
el mismo valor que
sys.prefix
en Windows. Todo este paso se omite en Windows si
applocal = true
está configurado. sys.executable
Se utiliza el directorio de o, si home
está configurado en pyvenv.cfg
, se utiliza en lugar del valor inicial de sys.prefix
.
Si no puede encontrar estos archivos "históricos" o sys.prefix
aún no los ha encontrado, entonces Python establece sys.prefix
un valor "alternativo". Linux y Mac, por ejemplo, utilizan valores predeterminados precompilados como valores de sys.prefix
y sys.exec_prefix
. Windows espera hasta que sys.path
esté completamente resuelto para establecer un valor alternativo para
sys.prefix
.
Luego, (lo que todos estaban esperando), Python determina los valores iniciales que estarán contenidos en sys.path
.
- Se agrega el directorio del script que Python está ejecutando
sys.path
. En Windows, esta es siempre la cadena vacía, lo que le indica a Python que use la ruta completa donde se encuentra el script. - El contenido de la variable de entorno PYTHONPATH, si está configurada, se agrega a
sys.path
, a menos que esté en Windows yapplocal
esté configurada como verdadera enpyvenv.cfg
. - La ruta del archivo zip, que se encuentra
<prefix>/lib/python35.zip
en Linux/Mac yos.path.join(os.dirname(sys.executable), "python.zip")
en Windows, se agrega asys.path
. - Si en Windows y no
applocal = true
se configuró , se agregapyvenv.cfg
el contenido de las subclaves de la clave de registro , si corresponde.HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\
- Si en Windows no
applocal = true
se configurópyvenv.cfg
ysys.prefix
no se pudo encontrar, entonces se agrega el contenido principal de la clave de registroHK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\
, si existe; - Si en Windows y no
applocal = true
se configuró , se agregapyvenv.cfg
el contenido de las subclaves de la clave de registro , si corresponde.HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\
- Si en Windows no
applocal = true
se configurópyvenv.cfg
ysys.prefix
no se pudo encontrar, entonces se agrega el contenido principal de la clave de registroHK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\
, si existe; - Si en Windows y no se configuró PYTHONPATH, no se encontró el prefijo y no había claves de registro presentes, entonces se agrega el valor relativo en tiempo de compilación de PYTHONPATH; de lo contrario, este paso se ignora.
- Las rutas en la macro PYTHONPATH en tiempo de compilación se agregan en relación con el archivo
sys.prefix
. sys.exec_prefix
En Mac y Linux, se agrega el valor de .sys.prefix
En Windows, se agrega el directorio que se usó (o se habría usado) para buscar dinámicamente .
En esta etapa en Windows, si no se encontró ningún prefijo, Python intentará determinarlo buscando en todos los directorios sys.path
los archivos de referencia, como intentó hacer con el directorio sys.executable
anterior, hasta que encuentre algo. Si no es así, sys.prefix
se deja en blanco.
Finalmente, después de todo esto, Python carga el site
módulo, que agrega cosas aún más a sys.path
:
Comienza construyendo hasta cuatro directorios a partir de una parte principal y otra final. Para la parte de la cabeza utiliza
sys.prefix
ysys.exec_prefix
; Se omiten las cabezas vacías. Para la parte final, utiliza la cadena vacía y luegolib/site-packages
(en Windows) olib/pythonX.Y/site-packages
y luegolib/site-python
(en Unix y Macintosh). Para cada una de las distintas combinaciones head-tail, ve si hace referencia a un directorio existente y, de ser así, lo agrega a sys.path y también inspecciona la ruta recién agregada para buscar archivos de configuración.
EDITAR: No hay más getpathp.c
(enlace al principio sobre palabra complicada ) desde diciembre de 2021 porque la implementación se transfirió a Python:getpath.py
"Inicializado desde la variable de entorno PYTHONPATH, más un valor predeterminado que depende de la instalación"
-- http://docs.python.org/library/sys.html#sys.path