Flujo de trabajo para mantener diferentes versiones de código base para diferentes versiones de Python

Estoy desarrollando una aplicación de código abierto llamada GarlicSim .

Hasta ahora lo he estado desarrollando solo para Python 2.6. Parece que no funciona en ninguna otra versión.

Decidí que es importante producir versiones que admitan otras versiones de Python. Estoy pensando en hacer una versión para 2.5, 3.1 y tal vez 2.4.

Entonces tengo varias preguntas:

  1. ¿Cuál sería una buena manera de organizar la estructura de carpetas de mi repository para include estas diferentes versiones?
  2. ¿Cuál sería una buena forma de "fusionar" los cambios que hago en una versión del código con otras versiones? Sé cómo hacer fusiones en mi SCM (que es git), pero estas son carpetas que están todas en el mismo repository, y quiero hacer una fusión entre ellas. Por supuesto, existe la opción de tener un repository para cada versión, pero creo que no es una buena idea.

¿Alguien tiene alguna sugerencia?

Necesita twigs separadas para versiones separadas solo en los casos más raros. Mencionas administradores de context, y son geniales, y apetece no usarlos, y tienes razón. Pero para Python 2.4 no tendrás que usarlos. Entonces eso apestará. Por lo tanto, si desea admitir Python 2.4, deberá escribir una versión sin administradores de context. Pero ese funcionará también con Python 2.6, por lo que no tiene sentido tener versiones separadas allí.

En cuanto a Python 3, tener una sucursal separada es una solución, pero en general no es la mejor. Para el soporte de Python 3 hay algo llamado 2to3 que convertirá tu código de Python 2 al código de Python 3. No es perfecto, por lo que a menudo tendrás que modificar el código de Python 2 para generar un buen código de Python 3, pero el código de Python 2 tiende a mejorar como resultado de todos modos.

Con Distribute (una bifurcación mantenida de setuptools) puedes hacer esta conversación automáticamente durante la installation. De esta forma, no es necesario tener una sucursal separada ni siquiera para Python 3. Consulte http://bitbucket.org/tarek/distribute/src/tip/docs/python3.txt para ver los documentos sobre eso.

Como escribe Paul McGuire, incluso es posible admitir Python 3 y Python 2 con el mismo código sin usar 2to3, pero no lo recomendaría si desea soportar algo más que 2.6 y 3.x. Consigues demasiado de estos feos hacks especiales. Con 2.6, hay suficiente compatibilidad con Python 3 para que sea posible escribir código de aspecto decente y admitir Python 2.6 y 3.x, pero no Python 2.5 y 3.x.

Intentaría mantener una twig para cubrir todo el python 2.4-2.6

Las diferencias no son tan buenas, después de todo, si tiene que escribir un montón de código adicional para 2.4 para hacer algo fácil en 2.6, a la larga le resultará less útil usar la versión 2.4 para 2.5 y 2.6. .

Python 3 debe tener una twig diferente, aún así debes tratar de mantener tantos códigos en común como puedas.

Si su código no depende excesivamente del performance del time de ejecución en los manejadores de excepciones, puede incluso alejarse sin tener una sucursal separada para Py3. Logré mantener una versión de pyparsing para todas mis versiones de Py2.x, aunque tuve que seguir el enfoque del "mínimo común denominador", lo que significa que tengo que renunciar a usar algunas construcciones, como expresiones generadoras, y su punto, administradores de context. Utilizo dicts en lugar de sets, y todas las expresiones de mi generador se envuelven como lists de comprensión, por lo que seguirán funcionando desde Python 2.3. Tengo un bloque en la parte superior de mi código que se ocupa de una serie de problemas de 2vs3 (contribuido por el usuario de pyparsing Robert A Clark):

 _PY3K = sys.version_info[0] > 2 if _PY3K: _MAX_INT = sys.maxsize basestring = str unichr = chr unicode = str _str2dict = set alphas = string.ascii_lowercase + string.ascii_uppercase else: _MAX_INT = sys.maxint range = xrange def _str2dict(strg): return dict( [(c,0) for c in strg] ) alphas = string.lowercase + string.uppercase 

La mayor dificultad que he tenido ha sido con la syntax incompatible para capturar excepciones, que se introdujo en Py3, cambiando de

 except exceptiontype,varname: 

a

 except exceptionType as varname: 

Por supuesto, si realmente no necesita la variable de exception, puede simplemente escribir:

 except exceptionType: 

y esto funcionará en Py2 o Py3. Pero si necesita acceder a la exception, todavía puede encontrar una syntax compatible con versiones cruzadas como:

 except exceptionType: exceptionvar = sys.exc_info()[1] 

Esto tiene una penalización menor en el time de ejecución, lo que hace que esto no se pueda usar en algunos lugares en pyparsing, por lo que aún tengo que mantener versiones separadas de Py2 y Py3. Para la fusión de fonts, utilizo la utilidad WinMerge , que me parece muy buena para mantener sincronizados los directorys del código fuente.

Entonces, aunque conservo dos versiones de mi código, algunas de estas técnicas de unificación me ayudan a mantener las diferencias hasta el mínimo absoluto incompatible.

Finalmente decidí tener 4 diferentes horquillas para mi proyecto, para 2.4, 2.5, 2.6 y 3.1. Mi principal prioridad es 2.6 y no quiero comprometer la elegancia de ese código por el bien de 2.4. Así que los feos hacks de compatibilidad estarán en las versiones inferiores, no en las versiones superiores.