Pensé agregar un poco a la estrategia defendida por la respuesta de Wim: obtener la versión adecuada de Django trabajando primero en 2.7 y 3.x, y describir algunas tácticas que funcionaron para mí.
Python 2.7 es tu cápsula de escape, hasta que aprietes el gatillo en 3.x
- sus pruebas deben ejecutarse en ambos
- no use ninguna característica específica de 3.x, como f-strings
- primero Python 3.x, luego solo luego Django 2.x que no se ejecuta en 2.7
- Comience temprano, no analice en exceso, pero evite el enfoque del Big Bang
- archivo por archivo al principio.
- comience con el código de nivel más bajo, como las bibliotecas de utilidades, para las que tiene suites de pruebas.
- si es posible, intente fusionar gradualmente sus cambios en las ramas de producción 2.7 y mantenga actualizado su código de transferencia 3.x con los cambios de producción.
¿Con qué versión menor de Django para empezar?
Mi criterio aquí es que las migraciones de Django pueden estar bastante involucradas (y en realidad requieren más reflexión que 2 => 3 trabajos). Así que me trasladaría al 1.11 más reciente y mejor de esa manera, ya está proporcionando algo de valor a sus 2.7 usuarios. Probablemente haya una buena cantidad de cuñas de compatibilidad anteriores a 2.x en 1.11 y recibirá sus advertencias de desaprobación 2.x.
¿Con qué versión menor de Python 3.x comenzar?
Es mejor tener en cuenta todos los ángulos, como la disponibilidad de sus librerías de terceros, el soporte de su suite CI / devops y la disponibilidad en las imágenes del sistema operativo de su servidor elegido. Siempre puede instalar 3.8 e intentar una instalación pip de su require.txt solo, por ejemplo.
Aproveche git (o cualquier scm que use) y virtualenv .
- separar
requirement.txt
archivos , pero ...
- si tiene un repositorio git basado en archivos, puede apuntar cada venv a la misma línea de código con un
pip install -e <your directory>
. eso significa que, en 2 terminales diferentes, puede ejecutar 2.7 y 3.x contra las mismas pruebas unitarias.
- incluso podría ejecutar servidores Django 2.7 y 3.x lado a lado en diferentes puertos y señalar, por ejemplo, Firefox y Chrome.
- comprometerse a menudo (al menos en la rama portadora) y aprender sobre git bisect .
hacer uso de 2to3
Sí, romperá el código 2.7 y Django si lo dejas. Entonces...
ejecútelo en modo de vista previa o en un solo archivo. vea lo que se rompe pero también vea lo que hizo bien.
limítelo solo a ciertas conversiones que no rompan 2.7 o Django. print x
=> print (x)
y except(Exception) as e
son 2 no-brainers.
Así es como se veía mi comando estrangulado:
2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
- ejecútelo archivo por archivo hasta que esté realmente seguro.
use sed o awk en lugar de su editor para conversiones masivas.
La ventaja es que, a medida que se vuelve más consciente de las preocupaciones específicas de sus aplicaciones, puede crear un conjunto de cambios que se pueden ejecutar en 1 archivo o en muchos archivos y hacer la mayor parte del trabajo sin romper 2.7 o Django. Aplique esto después de su pase 2to3 adecuadamente acelerado . Eso te deja con limpiezas residuales en tu editor y haciendo que tus pruebas pasen.
(opcional) comience a ejecutarse en negro en el código 2.7.
black, que es un formateador de código, usa Python 3 AST para ejecutar su análisis. No intenta ejecutar el código, pero marcará los errores de sintaxis que impiden que llegue a la etapa AST. Sin embargo, tendrás que trabajar con la magia global de instalación de pip para llegar allí y debes comprar la utilidad de las negras.
Otras personas lo han hecho, aprende de ellos.
Escuchar # 155 Pasos prácticos para pasar a Python 3 debería darle algunas ideas del trabajo. Mira los enlaces del programa. Les encanta hablar sobre el movimiento de Instagram (?) Que involucró un ajuste gradual de la ejecución del código 2.7 a la sintaxis 3.x en una base de código común y en la misma rama git, hasta el día de apretar el gatillo.
Consulte también la Guía de portabilidad conservadora de Python 3
e Instagram hacen un movimiento suave a Python 3 - The New Stack
Conclusión
Su tiempo para Django 1.11 EOL (abril de 2020) es bastante corto, por lo que si tiene más de 2 recursos de desarrollo para lanzar, consideraría hacer lo siguiente en paralelo:
DEV # 1: comience con un golpe Django 1.11 (la teoría es que Django 1.11 probablemente esté mejor posicionado como un punto de partida para Django 2.x), usando 2.7.
DEV # 2: comience en Python 3.6 / 3.7 de su código de utilidad que no sea Django. Como el código es compatible con 2.7 en este punto, combínelo en el # 1 a medida que avanza.
Vea cómo proceden ambas tareas, evalúe cuál es el riesgo del proyecto relacionado con Django y cómo se ve el dolor de Python 3. Ya te estás perdiendo la EOL de Python 2.7, pero un marco web obsoleto es probablemente más peligroso que el Python 2.7 heredado, al menos durante unos meses. Por lo tanto, no esperaría demasiado para comenzar a migrar de Django 1.9 y su trabajo al hacerlo no se desperdiciará. A medida que vea el progreso, comenzará a ver mejor los riesgos del proyecto.
Su progreso inicial de 2 a 3 será lento, pero las herramientas y la orientación son lo suficientemente buenas como para que aumente rápidamente la velocidad, así que no piense demasiado antes de comenzar a acumular experiencia. El lado de Django depende de su exposición a cambios importantes en el marco, por lo que creo que es mejor comenzar temprano.
PD (opinión controvertida / personal) No usé seis u otras bibliotecas puente de 2 a 3 enlatadas.
Sus no porque no me fío de ella - es brillante en las librerías de 3 ª parte - sino más bien que no quería añadir una dependencia permanente compleja (y yo era demasiado perezoso para leer su doc). Había estado escribiendo código 2.7 en sintaxis compatible 3.x durante mucho tiempo, así que realmente no sentía la necesidad de usarlos. Su kilometraje puede variar y no se inicie en este camino si parece mucho trabajo .
En cambio, creé un py223.py (57 LOC con comentarios incluidos) con este tipo de contenido, la mayoría de los cuales se refiere a soluciones para desaprobaciones y cambios de nombre en la biblioteca estándar.
try:
basestring_ = basestring
except (NameError,) as e:
basestring_ = str
try:
cmp_ = cmp
except (NameError,) as e:
# from http://portingguide.readthedocs.io/en/latest/comparisons.html
def cmp_(x, y):
"""
Replacement for built-in function cmp that was removed in Python 3
"""
return (x > y) - (x < y)
Luego importe desde ese py223 para solucionar esas preocupaciones específicas. Más tarde me se acaba de deshacerse de la importación y mover los extraño isinstance(x, basestr_)
a isinstance(x, str)
pero sé de antemano que hay poco de qué preocuparse.