2010-03-08 16 views
7

He escrito un módulo de Python y tengo dos versiones: una implementación de Python pura y una extensión de C. Escribí el archivo __init__.py para que intente importar la extensión C y, si eso falla, importa el código Python puro (¿es razonable?).Cómo crear una distribución de módulos de Python para adaptarla correctamente al código de Python puro

Ahora, me gustaría saber cuál es la mejor manera de distribuir este módulo (por ejemplo, escriba setup.py) para que pueda ser utilizado fácilmente por personas con o sin la posibilidad de construir o usar la extensión C, solo ejecutando:

python setup.py install 

Mi experiencia es limitada, pero veo dos casos posibles:

  • usuario no tiene MS Visual la suite compilador GCC, instalado en su máquina de estudio, o, para construir el Extensión C
  • El usuario ejecuta IronPython, Jython o cualquier otra cosa que no sea CPython. Solo he usado CPython. Así que no estoy seguro de cómo podría distribuir este módulo para que funcione sin problemas y sea fácil de instalar en esas plataformas, si no pueden usar la extensión C.
+0

He planteado un problema sobre esto para http://guide.python-distribute.org/ - ver http://bitbucket.org/tarek/hitchhiker-guide-packaging/issue/14/ how-to-create-a-module-distribution-to-gracefully-fall-back-to-pure-python –

Respuesta

7

(¿es razonable?).

Sí, perfectamente sensato.

Para capturar el "caso de compilador de C no adecuado": la llamada a setup(...) hará un sys.exit en caso de problemas. Así, en primer lugar tratar con el argumento ext_modules configurar como se desee, dentro de un try:

try: 
    setup(..., ext_modules=...) 
except SystemExit: ... 

y en la cláusula except, llamar setup(...) nuevo sin la ext_modules (por lo que se da por vencido en la construcción e instalación de las extensiones) . El usuario que está instalando aún verá mensajes como "no se puede ejecutar gcc-4.0: no existe ese archivo o directorio", pero puede agregar sus propios mensajes para informar al usuario que no es gran cosa y que lo intentará de nuevo sin el módulos de extensión.

Para apoyar las implementaciones no CPython, en su setup.py puede probar sys.version (no estoy seguro de lo que el valor será para cada aplicación no CPython, pero IronPython tiene una subcadena 'IronPython' allí, por ejemplo), para evitar incluso probando la parte ext_modules. Si se pierde alguna de esas implementaciones en sus cheques, el try/except probablemente debería atrapar a la mayoría de los demás, solo con una cantidad modesta de trabajo perdido ;-).

0

"intenta importar la extensión C, y si eso falla, importa el código de Python puro (¿es razonable?)".

Casi. Lea acerca de cStringIO y StringIO. Lea también sobre cPickle y Pickle. Lea también sobre cElementTree y ElementTree.

Si no se puede construir la versión C, ese es un caso de uso. La versión pura de Python es la única disponible.

Sin embargo, si se puede construir la versión C, todavía tengo buenas razones para rechazarla.Principal, consideraría declinar la versión C porque puede no permitir la profundidad de la subclase que requiero para mi aplicación.

No quiero ser forzado a usar la versión C, solo porque tuve el compilador correcto. Prefiero tomar esas decisiones por mi cuenta.

En consecuencia, no me gusta la idea de que una parte de su módulo tome mis decisiones de arquitectura para mí. Prefiero elegir qué importar. Si la versión C no existe, eso no cambia mi proceso de decisión, porque aún puedo crear subclases de la versión pura de Python.

Línea inferior. Automatiza menos Proporcione los dos módulos. Prefiero elegir cuál importar.

+0

En Python 3, se tomó la decisión de ir por el otro lado, si lo entiendo: solo hay un 'pickle' módulo, no 'cPickle'. Citando los documentos de Python 3.1 para 'pickle':" El módulo 'pickle' tiene un optimizador transparente (' _pickle') escrito en C. Se usa siempre que esté disponible. De lo contrario, se usa la implementación pura de Python. " –

+0

¿No es posible subclasificar una clase de Python definida por una extensión C? A propósito, en el módulo que estoy escribiendo, no hay clases, solo unas pocas funciones. Pero todavía tengo curiosidad. –

+0

@Craig McQueen: Sí, hay ejemplos de lo que estás haciendo. ¿Y qué? También hay ejemplos que toman el enfoque opuesto. Ese es mi punto. La creación de una clase de lenguaje C que se puede subclasificar rara vez se hace; No sé lo difícil que es; Asumo muy duro. Un módulo que es todas las funciones sin definición de clase probablemente esté diseñado incorrectamente, pero quizás esté diseñado correctamente. –

0

De acuerdo con la documentation for Planar, puede hacer que el archivo setup.py para la construcción de las extensiones C como normal, y luego:

para construir e instalar planar de la distribución de la fuente o el uso del repositorio:

python setup.py install 

Para instalar sólo los módulos de Python puro sin compilar, utilice:

python setup.py build_py install --skip-build 
Cuestiones relacionadas