2011-05-26 6 views
6

Tengo un proyecto con un paquete python y un componente compilado dentro de él. el diseño del directorio actual es:Creando/probando un proyecto Python con extensiones C

<project> 
    foo/ 
    foo/__init__.py 
    foo/... 

    src/ 
    src/c_foo.c 

    tests/ 
    tests/test_foo.py 

    setup.py 

Cuando el proyecto se construye, distutils cree un directorio build/lib cual sea añadir a PYTHONPATH o instalar en un entorno virtual. estructura resultante es la siguiente:

<project> 
    build/lib 
    build/lib/foo/__init__.py 
    build/lib/foo/c_foo.so 

El problema con esto es que si comienzo a una sesión de Python intérprete de la raíz del proyecto, las pruebas realizadas a partir de la raíz del proyecto, etc., que recoge el árbol de origen en lugar de la incorporada árbol.

He encontrado varias soluciones existentes a este en uso:

  1. fuentes Place pitón bajo un directorio diferente, por ejemplo. lib/foo, modules/foo etc. Lo que se opone a eso es un nivel de directorio adicional para todos los archivos fuente y la inconsistencia con proyectos que no tienen extensiones compiladas y, por lo tanto, tienen sus paquetes python en el directorio raíz.

  2. Mantener los paquetes en la raíz, lo que significa un inconveniente tener que chdir fuera de la raíz del proyecto (por ejemplo. En pruebas/directorio) para que interprete Python no ver los paquetes fuente (a través de escritura de la estructura o de forma manual).

  3. Mantener los paquetes en la raíz con un nombre diferente (por ejemplo. foo-module o foo-lib) con una línea adecuada package_dir={'foo':'lib-foo'} en setup.py. Esta es una variación de pt. 1 sin un nivel extra de jerarquía de directorios, lo cual es más o menos lo mismo, supongo.

  4. Mantenga los paquetes en la raíz y use setup.py build_ext --inplace, sin embargo, esto contamina el árbol fuente.

En cualquiera de los casos, se presenta un proyecto de tara versus un proyecto simple de python donde se puede modificar/ejecutar código directamente desde el árbol de origen. Me gustaría mucho escuchar las opiniones de todos sobre los pros/contras de lo anterior y qué método particular utilizas para tus proyectos.

+0

Me parece que 'build_ext --inplace' no está nada mal, simplemente agrega los archivos' .so'/'.dll'/... resultantes a' .gitignore' (o equivalente) y listo. – letmaik

Respuesta

1

Es posible que desee probar el objetivo develop en distribute (formerly setuptools).

Asegúrese distribute se instala, modifica la setup.py así:

# the setuptools package name is still used 
from setuptools import setup, Extension 
... 

continuación, introduzca su virtualenv y ejecutar develop:

% source ~/virt/bin/activate 
(virt)% cd ~/project 
(virt)% python setup.py develop 

Usted debe ser capaz de ejecutar las pruebas desde el interior de la raíz del proyecto, y cada vez que active ese virtualenv puede acceder a los paquetes y la extensión de ese proyecto, independientemente de su ruta:

% cd /tmp 
% source ~/virt/bin/activate 
(virt)% python -c 'import foo, c_foo; print foo, c_foo' 

<module 'foo' from '/Users/user/project/foo/__init__.py'> 
<module 'c_foo' from '/Users/user/project/c_foo.so'> 
Cuestiones relacionadas