¿Cómo Python realiza un seguimiento de los módulos instalados con huevos?

Si tengo un módulo, foo , en Lib/site-packages , solo puedo import foo y funcionará. Sin embargo, cuando instalo cosas de eggs, obtengo algo como blah-4.0.1-py2.7-win32.egg como una carpeta, con el contenido del módulo dentro, pero solo necesito import foo , no algo más complicado. ¿Cómo Python realiza un seguimiento de los huevos? No es solo una coincidencia de nombre de directorio, ya que si coloco esa carpeta en una instalación de Python sin pasar por los distritos, no encuentra el módulo.

Para ser más claros: acabo de instalar zope. El nombre de la carpeta es “zope.interface-3.3.0-py2.7-win32.egg”. Esto funciona:

 Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import zope.interface >>> 

Creo una carpeta “blah-4.0.1-py2.7-win32.egg” con un módulo vacío “jaja” (y __init__.py ). Esto no funciona:

 Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import blah.haha Traceback (most recent call last): File "", line 1, in  ImportError: No module named blah.haha >>> 

Esto hace, sin embargo:

 Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from pkg_resources import require >>> require("blah>=1.0") [blah 4.0.1 (c:\python27\lib\site-packages\blah-4.0.1-py2.7-win32.egg)] >>> import haha >>> 

Entonces, ¿cómo puedo hacer que funcione sin necesidad?

Si usa el script easy_install proporcionado por setuptools (o la setuptools Distribute ) para instalar paquetes como huevos, verá que, de manera predeterminada, crea un archivo llamado easy-install.pth en el directorio site-packages de su Python. instalación. Los archivos de configuración de ruta son una característica estándar de Python:

Un archivo de configuración de ruta es un archivo cuyo nombre tiene el formato package.pth y existe en uno de los cuatro directorios mencionados anteriormente; su contenido son elementos adicionales (uno por línea) que se agregarán a sys.path.

easy_install hace un uso intensivo de esta característica de Python. Cuando utiliza easy_install para agregar o actualizar una distribución, modifica easy-install.pth para agregar el directorio de egg o el archivo zip. De esta manera, easy_install mantiene el control del orden de búsqueda del módulo y garantiza que los huevos que instala aparezcan al principio del orden de búsqueda. Aquí hay un ejemplo del contenido de un easy-install.pth :

 import sys; sys.__plen = len(sys.path) ./appscript-0.21.1-py2.6-macosx-10.5-ppc.egg ./yolk-0.4.1-py2.6.egg ./Elixir-0.7.1-py2.6.egg ./Fabric-0.9.0-py2.6.egg import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,'__egginse rt',0); sys.path[p:p]=new; sys.__egginsert = p+len(new) 

Como puede ver aquí y si examina el código en las setuptools de setuptools , encontrará algunos trucos para arrancar y luego cubrir sus pistas, lo que puede hacer que los problemas de depuración con site.py y el inicio del intérprete sean un poco interesantes . (Esa es una de las razones por las que a algunos desarrolladores no les gusta usarla).

Si usa el parámetro -m de easy_install para instalar una distribución como multi-versión , la entrada easy-install.pth para ella no se agrega o se elimina si ya existe. Esta es la razón por la que la documentación de instalación easy_install le indica que use -m antes de eliminar un huevo instalado.

Cuando ejecuta easy_install, copia el huevo en los paquetes de sitio y coloca la ruta de acceso a ese huevo en su variable sys.path. (Tenga en cuenta que sys.path no es su variable de entorno PATH, se construye a partir de PYTHONPATH y otras variables de entorno. Por lo tanto, el archivo .egg que instala con easy_install se incluye en alguna variable de entorno y Python sabe que debe agregarlo a sys.path cuando inicia el intérprete de python).

Para que blah.haha funcione en su ejemplo, ejecute easy_install blah-4.0.1-py2.7-win32.egg y luego puede import haha desde python, o simplemente coloque el módulo jaja directamente en los paquetes de sitio.