Pregunta

Supongamos que he desarrollado una utilidad de usuario final de uso general escrita en Python. Anteriormente, solo tenía una versión disponible que era adecuada para Python más tarde que la versión 2.3 más o menos. Fue suficiente decir, "descargue Python si es necesario, luego ejecute este script". Solo había una versión del script en el control de origen (estoy usando Git) para realizar un seguimiento.

Con Python 3, esto ya no es necesariamente cierto. En el futuro previsible, necesitaré desarrollar simultáneamente dos versiones diferentes, una adecuada para Python 2.xy otra adecuada para Python 3.x. Desde una perspectiva de desarrollo, puedo pensar en algunas opciones:

  1. Mantener dos scripts diferentes en la misma rama, haciendo mejoras a ambos simultáneamente.
  2. Mantenga dos ramas separadas y combine cambios comunes de un lado a otro a medida que avanza el desarrollo.
  3. Mantenga solo una versión de la secuencia de comandos, además de incorporar un archivo de parche que convierta la secuencia de comandos de una versión a otra. Cuando se hayan realizado suficientes cambios para que el parche ya no se aplique limpiamente, resuelva los conflictos y cree un nuevo parche.

Actualmente me estoy inclinando hacia la opción 3, ya que las dos primeras implicarían mucho tedio propenso a errores. Pero la opción 3 parece desordenada y se supone que mi sistema de control de fuente debe administrar parches para mí.

Para el empaque de distribución, hay más opciones para elegir:

  1. Ofrezca dos paquetes de descarga diferentes, uno adecuado para Python 2 y otro adecuado para Python 3 (el usuario tendrá que saber descargar el correcto para cualquier versión de Python que tenga).
  2. Ofrezca un paquete de descarga, con dos scripts diferentes dentro (y luego el usuario debe saber ejecutar el correcto).
  3. Un paquete de descarga con dos scripts específicos de la versión y un pequeño cargador de código auxiliar que puede ejecutarse en ambas versiones de Python, que ejecuta el script correcto para la versión de Python instalada.

Nuevamente, me estoy inclinando hacia la opción 3 aquí, aunque todavía no he intentado desarrollar un cargador de código auxiliar similar.

¿Alguna otra idea?

¿Fue útil?

Solución

Editar: mi respuesta original se basó en el estado de 2009, con Python 2.6 y 3.0 como las versiones actuales. Ahora, con Python 2.7 y 3.3, hay otras opciones. En particular, ahora es bastante factible usar una única base de código para Python 2 y Python 3.

Consulte Portar código de Python 2 a Python 3

Respuesta original:

La recomendación oficial dice:

  

Para portar Python 2.5 o 2.6 existentes   código fuente a Python 3.0, el mejor   La estrategia es la siguiente:

     
      
  1. (Prerrequisito :) Comience con una excelente cobertura de prueba.

  2.   
  3. Puerto a Python 2.6. Esto no debería ser más trabajo que el puerto promedio   de Python 2.x a Python 2. (x + 1).   Asegúrese de que todas sus pruebas pasen.

  4.   
  5. (Todavía usando 2.6 :) Active el interruptor de línea de comando -3. Esto permite   advertencias sobre características que serán   eliminado (o cambio) en 3.0. Ejecute su   prueba de nuevo y corrige el código que   recibes advertencias hasta que hay   no quedan advertencias y todas tus pruebas   todavía pasar.

  6.   
  7. Ejecute el traductor de fuente a fuente 2to3 sobre su árbol de código fuente.   (Ver 2to3 - Python automatizado 2 a 3   traducción de código para más información sobre esto   herramienta.) Ejecutar el resultado de la   traducción bajo Python 3.0. A mano   arreglar cualquier problema restante, arreglando   problemas hasta que todas las pruebas pasen nuevamente.

  8.   
     

No se recomienda intentar escribir   código fuente que se ejecuta sin cambios bajo   Python 2.6 y 3.0; tendrías que   usa un estilo de codificación muy retorcido,   p.ej. evitando declaraciones impresas,   metaclases y mucho más. Si usted es   mantener una biblioteca que necesita   compatible con Python 2.6 y Python   3.0, el mejor enfoque es modificar el paso 3 anterior editando el 2.6   versión del código fuente y en ejecución   el traductor 2to3 nuevamente, en lugar de   editando la versión 3.0 de la fuente   código.

Idealmente, terminaría con una única versión, que es compatible con 2.6 y se puede traducir a 3.0 usando 2to3. En la práctica, es posible que no pueda lograr este objetivo por completo. Por lo tanto, es posible que necesite algunas modificaciones manuales para que funcione en 3.0.

Mantendría estas modificaciones en una rama, como su opción 2. Sin embargo, en lugar de mantener la versión final compatible con 3.0 en esta rama, consideraría aplicar las modificaciones manuales antes del 2to3 traducciones, y ponga este código 2.6 modificado en su rama. La ventaja de este método sería que la diferencia entre esta rama y la troncal 2.6 sería bastante pequeña, y solo consistiría en cambios manuales, no en los cambios realizados por 2to3. De esta manera, las ramas separadas deberían ser más fáciles de mantener y fusionar, y debería poder beneficiarse de futuras mejoras en 2to3.

Alternativamente, tome un poco de " espere y vea " enfoque. Continúe con su portabilidad solo hasta donde pueda llegar con una única versión 2.6 más traducción 2to3, y posponga la modificación manual restante hasta que realmente necesite una versión 3.0. Tal vez en este momento, ya no necesite ningún ajuste manual ...

Otros consejos

Para el desarrollo, la opción 3 es demasiado engorrosa. Mantener dos ramas es la forma más fácil, aunque la forma de hacerlo variará entre los VCS. Muchos DVCS estarán más contentos con repositorios separados (con una ascendencia común para ayudar a la fusión) y VCS centralizados probablemente serán más fáciles de trabajar con dos ramas. La opción 1 es posible, pero puede perderse algo para fusionar y un poco más IMO propenso a errores.

Para distribución, usaría la opción 3 también si es posible. Las 3 opciones son válidas de todos modos y he visto variaciones en estos modelos de vez en cuando.

No creo que tome este camino en absoluto. Es doloroso de cualquier manera que lo mires. Realmente, a menos que haya un fuerte interés comercial en mantener ambas versiones simultáneamente, esto es más dolor de cabeza que ganancia.

Creo que tiene más sentido seguir desarrollando para 2.x por ahora, al menos durante unos meses, hasta un año. En algún momento será el momento de declarar una versión final estable para 2.xy desarrollar las siguientes para 3.x +

Por ejemplo, no cambiaré a 3.x hasta que algunos de los principales marcos funcionen de esa manera: PyQt, matplotlib, numpy y algunos otros. Y realmente no me importa si en algún momento dejan de admitir 2.x y simplemente comienzan a desarrollar para 3.x, porque sabré que en poco tiempo podré cambiar a 3.x también.

Comenzaría migrando a 2.6, que está muy cerca de python 3.0. Incluso es posible que desee esperar a 2.7, que estará aún más cerca de Python 3.0.

Y luego, una vez que haya migrado a 2.6 (o 2.7), le sugiero que simplemente mantenga una sola versión del script, con cosas como "si PY3K: ... más: ..." en los lugares raros donde será obligatorio. Por supuesto, no es el tipo de código que a los desarrolladores nos gusta escribir, pero no tiene que preocuparse por administrar múltiples scripts o ramas o parches o distribuciones, lo que será una pesadilla.

Elija lo que elija, asegúrese de tener pruebas exhaustivas con una cobertura de código del 100%.

¡Buena suerte!

Cualquiera que sea la opción de desarrollo elegida, la mayoría de los problemas potenciales podrían aliviarse con pruebas unitarias exhaustivas para garantizar que las dos versiones produzcan resultados coincidentes. Dicho esto, la opción 2 me parece más natural: aplicar cambios de un árbol de origen a otro árbol de origen es una tarea (la mayoría) de los sistemas de control de versiones fueron diseñados; ¿por qué no aprovechar las herramientas que proporcionan para facilitar esto?

Para el desarrollo, es difícil decirlo sin 'conocer a tu audiencia'. Los usuarios de Power Python probablemente apreciarían no tener que descargar dos copias de su software todavía para una base de usuarios más general, probablemente debería 'simplemente funcionar'.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top