Какая версия Python & Django лучше всего подходит для преобразования кода Python2 в Python3?


11

В настоящее время я работаю в крупной фирме, где нам нужно конвертировать старый большой проект Django на python2 в версию на python3, поэтому я провел много исследований, связанных, но все еще не смог найти идеального ответа, касающегося того, какая версия Python и Django лучше всего подходит для конвертации.

В настоящее время я использую Python: 2.7.16 и Django: 1.9.13 в моей старой версии.

Любой может предложить мне наиболее подходящую версию Python & Django для вышеуказанной старой версии для преобразования python2 в python3.


Текущая версия python3 - это Python 3.8, а последняя версия Django - Django 3.0. На сайте Django рекомендуется последняя версия python 3 , а именно 3.8. Есть ли конкретная причина, по которой вы не хотите ускорить и Python, и Django до их последних версий?
Зеленый Плащ Гай

2
Кстати, я только несколько дней назад осознал, что веб-сайт на Django, который я поддерживаю в течение нескольких лет, на самом деле работает на сервере, на котором он размещен с использованием python2.7, тогда как я запускал его локально с помощью python3. 7. Единственное отличие, которое я обнаружил, состояло в том, что когда я впервые попытался использовать f-строки, и версия веб-сервера потерпела крах; в противном случае он работает точно так же, как и ожидалось (точно так же) локально и удаленно, для целей тестирования и добавления функций. Мой совершенно анекдотичный вывод заключается в том, что Django обычно совместим с большинством вещей.
Зеленый плащ Гай

1
для последней версии я обнаружил, что некоторые люди не рекомендуют, потому что в последней версии, если возникнут какие-либо проблемы, связанные с новыми обновлениями, иногда будет трудно найти решение, поэтому в текущем проекте я не хочу рисковать, а также для В целях тестирования я начал конвертировать свой проект в последнюю версию Python 3.7.3 с последней версией django и уже обнаружил 30 видов проблем.
Луна

Стоит отметить - этот вопрос возник в ходе проверки для меня. «Есть ли какой-либо документ или ссылка» очень явно не по теме (запрашивая сторонний ресурс). Тем не менее, я считаю, что вопрос можно отредактировать так, чтобы он мог лучше привести к принятому ответу ниже.
The Mayer

Ответы:


3

Я подумал, что немного добавлю к стратегии, отстаиваемой ответом Вима, - сначала получу подходящую версию Django, работающую как с 2.7, так и с 3.x, - и нарисую некоторые тактики, которые сработали для меня.

Python 2.7 - это ваш запасной модуль, пока вы не нажмете на 3.x

  • ваши тесты должны выполняться на обоих
  • не используйте 3.x специфические функции, такие как f-строки
  • сначала Python 3.x, потом только Django 2.x, который не работает на 2.7
  • начать рано, не переоценивать, но избегать подхода большого взрыва
    • файл за файлом сначала.
    • Начните с кода самого низкого уровня, например, библиотек утилит, для которых у вас есть наборы тестов.
    • если возможно, попробуйте постепенно объединить ваши изменения с производственными ветками 2.7 и поддерживать ваш код переноса 3.x в актуальном состоянии с изменениями prod.

С какой минорной версии Django начать?

Мои критерии здесь заключаются в том, что миграция Django может быть достаточно вовлечена (и на самом деле требует больше размышлений, чем 2 => 3 работы). Поэтому я бы перешел к последней и лучшей версии 1.11, так что вы уже предоставляете некоторую ценность своим 2.7 пользователям. Там, наверное, большое количество клиньев совместимости предварительно 2.x на 1.11 и вы будете получать свои 2.x устаревания предупреждения.

С какой минорной версии Python 3.x начать?

Лучше всего учитывать все аспекты, такие как доступность ваших сторонних библиотек, поддержка из набора CI / devops и доступность выбранных вами образов ОС сервера. Вы всегда можете установить 3.8 и, например, попробовать установить pip-файл вашего needs.txt.

Используйте git (или любую другую scm, которую вы используете) и virtualenv .

  • отдельные requirement.txtфайлы, но ...
  • если у вас есть git-репозиторий на основе файлов, вы можете указать для каждого venv одну и ту же кодовую строку с помощью a pip install -e <your directory>. это означает, что в 2 разных терминалах вы можете запустить 2.7 и 3.x против одного и того же юнит-теста (ов).
  • вы даже можете запускать серверы Django 2.7 и 3.x параллельно на разных портах и ​​указывать на них Firefox и Chrome.
  • часто делайте коммиты (по крайней мере, в ветке портирования) и изучайте git bisect .

использовать 2to3

Да, он сломает код 2.7 и Django, если вы позволите. Так...

  • запустить его в режиме предварительного просмотра или для одного файла. посмотрите, что он сломает, но и посмотрите, что он сделал правильно.

  • дросселируйте это только до определенных преобразований, которые не нарушают 2.7 или Django. print x=> print (x)и except(Exception) as e2 ежу понятно.

Вот как выглядела моя задушенная команда:

2to3 $tgt -w -f except -f raise -f next -f funcattrs -f print
  • запускайте его файл за файлом, пока вы действительно не будете уверены.

используйте sed или awk вместо вашего редактора для массовых конверсий.

Преимущество состоит в том, что по мере того, как вы будете лучше осознавать специфические проблемы ваших приложений, вы можете создавать набор изменений, которые можно запускать как для одного файла, так и для нескольких файлов, и выполнять большую часть работы, не нарушая 2.7 или Django. Примените это после вашего подходящего удушения прохода 2to3 . Это оставляет вас с остаточными очистками в вашем редакторе и позволяет пройти тесты.

(опционально) начать работать черным на 2.7 кода.

black, который является средством форматирования кода, использует Python 3 AST для выполнения своего анализа. Он не пытается запустить код, но он помечает синтаксические ошибки, которые мешают ему перейти на стадию AST. Вам нужно будет поработать над глобальной магией, чтобы попасть туда, и вам придется потратить на пользу черных.

Другие люди сделали это - учитесь у них.

Прослушивание # 155 Практические шаги по переходу на Python 3 должны дать вам несколько идей о работе. Посмотрите на шоу ссылки для этого. Они любят обсуждать ход Instagram (?), Который включал постепенную корректировку запуска кода 2.7 для синтаксиса 3.x на общей кодовой базе и в той же ветке git, пока не наступит день запуска.

Смотрите также Консервативное руководство по портированию Python 3

и Instagram делают плавный переход на Python 3 - новый стек

Вывод

Ваше время для Django 1.11 EOL (апрель 2020 г.) довольно короткое, поэтому, если у вас есть ресурсы для разработки от 2+, я бы подумал сделать следующее параллельно:

  • DEV # 1: начать с удара Django 1.11 (теория состоит в том, что Django 1.11, вероятно, лучше всего позиционировать как точку перехода к Django 2.x), используя 2.7.

  • DEV # 2: начните работу с Python 3.6 / 3.7 вашего кода не-Django. Поскольку код на данный момент совместим с 2.7, объедините его с # 1 на ходу.

Посмотрите, как выполняются обе задачи, оцените риск проекта, связанный с Django, и как выглядит боль в Python 3. Вам уже не хватает Python 2.7 EOL, но устаревший веб-фреймворк, вероятно, более опасен, чем устаревший Python 2.7, по крайней мере, на несколько месяцев. Так что я бы не стал слишком долго ждать, чтобы начать миграцию с Django 1.9, и ваша работа не будет потрачена впустую. Когда вы увидите прогресс, вы начнете видеть риски проекта лучше.

Ваш первоначальный прогресс 2to3 будет медленным, но инструменты и руководство достаточно хороши, чтобы вы быстро набрали скорость, поэтому не думайте об этом, прежде чем начать набирать опыт. Сторона Django зависит от вашей подверженности критическим изменениям в структуре, поэтому я думаю, что лучше начинать рано.

PS (спорно / личное мнение) я не использовал шесть или другие консервы 2-к-3 библиотеки мостовых много.

Это не потому, что я не доверяю - это замечательно для сторонних библиотек - скорее, я не хотел добавлять сложную постоянную зависимость (и мне было лень читать ее документ). Я долгое время писал код 2.7 в синтаксисе, совместимом с 3.x, поэтому я не чувствовал необходимости использовать их. Ваш пробег может меняться и не идти по этому пути, если кажется, что много работы .

Вместо этого я создал py223.py (57 LOC, включая комментарии) с этим типом контента, большая часть которого связана с обходными путями для устаревания и изменения имени в стандартной библиотеке.

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)

Затем импортируйте из этого py223, чтобы обойти эти конкретные проблемы. В дальнейшем я буду просто канаву импортировать и переместить те странно , isinstance(x, basestr_)чтобы , isinstance(x, str)но я знаю заранее , есть немного , чтобы беспокоиться о.


Хороший совет. Только одно примечание, само Django уже использует sixдля уровня совместимости, поэтому, если вы хотите использовать его в проекте Django во время перехода, это не означает «добавление сложной постоянной зависимости».
Вим

@wim. Я согласен с тобой. шесть, но это зависит от точки зрения. Я уже отмечал, что он поставляется с сторонними библиотеками, поэтому он не «стоит» с точки зрения требований и общих зависимостей. однако я - возможно, ошибочно - посчитал это большим черным ящиком / бородавкой в середине моего кода. если все, что вы делаете, это такие вещи, как тестирование экземпляра string / unicode / basestring и если вы знаете, как это сделать самостоятельно, то вы точно знаете, как поддерживать свои прокладки, когда они больше не нужны. Я перенесу это до конца, хотя.
JL Peyret

Это pip install -e ...(в нижнем регистре -e), верно?
Thebjorn

это, вероятно, так. исправит
JL Peyret

3

Я предлагаю сначала обновить до Django==1.11.26последней версии Django, которая поддерживает как Python 2, так и Python 3. Оставайтесь на текущей версии Python 2.7.

Внимательно прочитайте заметки о выпуске для 1.10.x и 1.11.x, проверяя устаревшие версии и исправляя все, что перестало работать, из вашего кода 1.9.x. Вещи сломаются. Джанго движется быстро. Для большого проекта Django может потребоваться много изменений кода, и, если вы используете множество сторонних плагинов или библиотек, вам, возможно, придется жонглировать их версиями. Некоторые из ваших сторонних зависимостей, вероятно, будут полностью отброшены, поэтому вам придется искать замены или удалять функции.

Чтобы найти примечания к выпуску для каждого обновления версии, просто нажмите "Что нового в Django". Хиты будут тщательно документировать все амортизации и изменения:

После того , как веб - приложение , кажется, работает хорошо на Django 1.11, все тесты попутном (вы делаете есть набор тестов, не так ли?) , То вы можете сделать преобразование Python 3, в то время сохраняя версию Django то же самое. Django 1.11 поддерживает до Python 3.7, так что это хорошая версия для таргетинга. Ожидайте Unicode повсеместно, поскольку неявное преобразование между байтами и текстом уже прошло, и многие веб-приложения Python 2 полагались на это.

Как только проект работает нормально на Django 1.11 и Python 3.7, вы можете подумать об обновлении до Django 3.0, выполнив тот же процесс, что и раньше - чтение заметок о выпуске, внесение необходимых изменений, запуск набора тестов и проверка веб-приложение на сервере разработки вручную.


1
Определенно путь. Получите ваш тестовый код для запуска на 2.7 и 3.x. Вы можете иметь 2 разных virtualenv, указывающих на одно и то же git-репо pip install -E. Как только модульные тесты будут запущены, начните тестовое использование Django-on-3x и снова продолжайте работу кода в 2 и 3. С некоторой осторожностью написания кода и осторожностью, чтобы не сжечь ваши 2,7 моста - например, без строк - переключение будет очень антиклиматично. Как только 3.x станет полностью стабильным, начните использовать только 3.x код. Преимущество в том, что производство 2.7 всегда идет в ногу до момента переключения.
JL Peyret

2

Я бы сначала обновился до py3. Вам нужно будет посмотреть setup.pyрепозиторий Django в ветке stable / 1.9.x ( https://github.com/django/django/blob/stable/1.9.x/setup.py ), чтобы выяснить, что py3 поддерживаются версии 3.4 (мертвые) и 3.5.

Как только вы попадаете на py3.5 и Django 1.9, вы можете обновлять по одному, пока не доберетесь до версии, на которой хотите закончить. Например, Django 1.11 поддерживает py3.5 и py3.7, поэтому

py27/dj19 -> py35/dj19 -> py35/dj1.11 -> py37/dj1.11 ... -> py37/dj2.2

dj2.2 - это первая версия, поддерживающая py3.8, но я бы остановился на py37 / dj2.2, если вы работаете в обычно консервативной среде.

Если у вас есть другие пакеты, вам нужно будет найти комбинации версий, которые будут работать вместе на каждом этапе. Наличие плана является ключевым моментом, и обновление только одного компонента за раз обычно приводит к экономии вашего времени.

Библиотека будущего ( https://python-future.org/ ) поможет вам во многих неприятных ситуациях, в то время как вам нужен код для запуска на py27 и 3.x. шесть тоже отлично. Я бы не стал создавать свой собственный слой совместимости (зачем изобретать велосипед?)

Если это вообще возможно, попробуйте увеличить охват модульных тестов до 75-85% перед запуском и определенно настроить автоматическое тестирование для версий «от» и «до» для каждого шага обновления. Убедитесь, что вы прочитали и исправили все предупреждения от Django перед обновлением до следующей версии - Django очень мало заботится об обратной совместимости, поэтому я обычно рекомендую использовать каждую минорную версию на пути обновления (или, по крайней мере, убедитесь, что вы читаете «назад»). несовместимости "и списки устаревших для каждой минорной версии).

Удачи (сейчас мы обновляем кодовую базу 300 + Kloc с py27 / dj1.7, поэтому я чувствую вашу боль ;-)


1
+1 на тестовое покрытие. Это ключевой показатель здесь, какой бы подход ни подходил. Это действительно помогает при экспериментировании с повсеместными изменениями кода, и я говорю это как человек, который совсем не является поклонником TDD Red / Green. Определите способ определения исходных результатов 2.7, и обновление станет намного проще.
JL Peyret

2

У меня такая же проблема с моим проектом, и я пробовал python 3.7.5 с Django версии 2.2.7.

Вы не должны использовать последнюю версию Python 3.8 или Django последнюю версию 3.0, поскольку у вас могут быть шансы на то, что при любой ошибке вы не сможете найти правильное решение для последних версий.


Это должен быть комментарий
Бруно

-2

Вы должны попробовать снимать для текущих версий. Python 3.8 и Django 3.0. Библиотека Six поможет с некоторыми изменениями в соглашениях. В любом случае вам придется провести некоторый рефакторинг, чтобы вы могли сделать его текущим.


3
Вы когда-нибудь делали апгрейд Django? Это просто желаемое за действительное. Переход непосредственно к Python 3.8 и Django 3.0 из 2.7 / 1.9 будет практически невозможен. Даже обновление минорных версий, таких как Django 1.9 до 1.10, может быть сложным процессом, требующим многих изменений кода.
Вим

Да, при условии, что у меня было достаточно времени и роскоши, чтобы выполнить полный рефакторинг и привести приложение в актуальное состояние. Опять же, размер приложения, логика и временные ограничения являются огромной проблемой для большинства парней, но они никогда не упоминали размер приложения или временные ограничения, поэтому я порекомендовал свое мнение о «лучшем решении» или «желаемом мышлении»;)
Дейв

Кроме того, если вам придется беспокоиться о том, что Ansible и работает на LTS Ubuntu, вы обнаружите, что даже поддержка 3.7 отсутствует в Ubuntu 18.04. Подкасты по безопасности, которые я слушаю, советуют позволить 3.8 немного подождать до момента выпуска или 2. -1 для ненужного риска.
JL Peyret

Любые хорошие рекомендации по подкасту безопасности?
Дейв

Для Python sec, listennotes.com/podcasts/talk-python-to-me/… Но я думаю, что остерегайтесь 3.8 на какое-то время один из них более поздний. Risky Business - это хороший и интересный подкаст безопасности, особенно если вы следите за международными отношениями. Извините за понижение голоса, но да, то, что сработало в вашем случае, может привести к травмированию кого-то другого в другом контексте. Для преобразования 2 в 3 см. Listennotes.com/podcasts/talk-python-to-me/…
JL Peyret
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.