Для перетворення коду Python2 в Python3, яка версія Python & Django найкраще підходить?


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
Анекдотично, я лише кілька днів тому зрозумів, що веб-сайт на базі Джанго, який я підтримую кілька років, насправді працює на сервері, на якому розміщується, використовуючи python2.7, тоді як я його запускаю локально за допомогою python3. 7. Єдина різниця, яку я виявила, полягала в тому, що коли я вперше спробував використати f-рядки, і версія веб-сервера зазнала аварії; в іншому випадку він працює точно так, як очікувалося (абсолютно те саме) локально та віддалено, для тестування та доповнення функцій. Мій цілком анекдотичний висновок полягає в тому, що Джанго загалом сумісний з більшістю речей.
Зелений плащ Гай

1
для останньої версії я виявив, що деякі люди не рекомендують, оскільки в останній версії, якщо є якісь проблеми, пов’язані з новими оновленнями, тоді буде важко знайти рішення іноді, тому в поточному проекті я не хочу створювати такий ризик і також для тестуючи цільове завдання, я почав перетворювати мій проект на останню версію python 3.7.3 з останньою django і вже знайшов 30 видів проблем.
Місяць

Зазначимо - це питання з'явилося для мене з аудиту перегляду. "Чи є якийсь документ чи посилання", це дуже очевидно поза темою (запит на ресурс поза сайтом). Однак я вважаю, що питання можна відредагувати таким чином, щоб воно могло краще призвести до прийнятої відповіді нижче.
theMayer

Відповіді:


3

Я думав, що я додам трохи до стратегії, яку підтримує відповідь Віма, - спочатку знайдіть відповідну версію Джанго, яка працює як на 2.7, так і на 3.x - і окреслю деякі тактики, які працювали на мене.

Python 2.7 - це ваш рятувальний майданчик, поки ви не натиснете курок на 3.x

  • ваші тести повинні працювати на обох
  • не використовуйте жодних особливих функцій 3.x, як-от f-string
  • спочатку Python 3.x, потім лише пізніше Django 2.x, який не працює на 2.7
  • почніть рано, не надмірно аналізуйте, але уникайте підходу великого удару
    • файл спочатку за файлом.
    • почніть з найнижчого рівня коду, як бібліотеки утиліт, для яких у вас є тестові набори.
    • якщо це можливо, спробуйте поступово об'єднати свої зміни до 2,7 виробничих галузей і забезпечити оновлення коду перенесення 3.x із змінами prod.

З якої другої версії Джанго почати?

Мої критерії тут полягають у тому, що міграції Джанго можуть бути досить задіяними (і насправді вимагають більше мислення, ніж 2 => 3 роботи). Тож я перейшов би до останнього та найбільшого 1.11 таким чином, ви вже надаєте деяку цінність своїм 2,7 користувачам. Напевно, існує достатня кількість сумісностей, що працюють до 2.x, на 1.11, і ви отримуватимете її попередження про скорочення 2.x.

З якої другої версії Python 3.x почати?

Найкраще врахувати всі кути, такі як наявність ваших сторонніх ліфтів, підтримка вашого пакета CI / devops та доступність обраних обраних вами серверів ОС. Ви завжди можете встановити 3.8 і спробувати встановити файл pip своїх вимог.txt, наприклад, сам.

Використовуйте git (або будь-яку scm, яку ви використовуєте) та virtualenv .

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

використовувати 2to3

Так, він зламає 2,7 код і Django, якщо ви дозволите. Тому...

  • запустіть його в режимі попереднього перегляду або проти одного файлу. дивіться, що це ламає, а також дивіться, що він зробив правильно.

  • пригнічуйте його лише до певних конверсій, які не порушують 2.7 або Django. print x=> print (x)і except(Exception) as eє двома моніторами.

Ось так виглядала моя затискаюча команда:

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

використовуйте sed або awk, а не редактор для масових конверсій.

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

(необов’язково) почніть працювати чорним кольором на 2,7 коді.

чорний, який є форматором коду, використовує Python 3 ASTs для запуску свого аналізу. Він не намагається запустити код, але позначить помилки синтаксису, які заважають йому потрапити на етап AST. Вам доведеться попрацювати з деякими технологіями встановити глобальну магію, щоб потрапити туди, і вам доведеться купувати корисність чорного.

Інші люди це зробили - вчіться у них.

Прослуховування №155 Практичні кроки для переходу на Python 3 повинні дати вам декілька ідей роботи. Подивіться на посилання на шоу. Вони люблять спілкуватися з ходом Instagram (?), Який передбачав поступове налаштування запущеного 2,7 коду до синтаксису 3.x на загальній базі коду та в тій же гітці git, поки не відбудеться день запуску.

Дивіться також Посібник з перенесення консервативного Python 3

і Instagram робить плавний перехід до Python 3 - The New Stack

Висновок

Ваш час на 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 буде повільним, але інструментальне та керівництво досить добре, що ви швидко наберете швидкість, тому не переосмислюйте його, перш ніж починати збирати досвід. Сторона Джанго залежить від вашого впливу на порушення змін у рамках, тому я вважаю, що найкраще починати рано.

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

Це pip install -e ...(з нижнього регістру -e), правда?
thebjorn

це, мабуть, є. виправиться
JL

3

Моя пропозиція - спочатку оновити до Django==1.11.26, що є найсвіжішою версією Django, яка підтримує і Python 2, і Python 3. Залишайтеся на поточній версії Python 2.7 поки що.

Уважно прочитайте примітки до випусків для 1.10.x та 1.11.x, перевіряючи наявність застарілих даних і виправляючи все, що перестало працювати з кодом 1.9.x. Речі порушаться. Джанго рухається швидко. Для великого проекту Django може знадобитися багато змін коду, і якщо ви використовуєте багато сторонніх плагінів або бібліотек, можливо, доведеться перемикати їх версії. Можливо, деякі з ваших сторонніх залежностей повністю відмовилися, тому вам доведеться знайти заміни або видалити функції.

Щоб знайти нотатки до випуску для кожного оновлення версії, просто google "Що нового у 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, дотримуючись того самого процесу, що і раніше - читання приміток до випуску, внесення необхідних змін, запуск тестового набору та перевірка webapp на сервері розробників вручну.


1
Однозначно шлях. Завантажте тестовий код як на 2.7, так і на 3.x. Ви можете мати 2 різних virtualenvs, що вказують на один і той же git repo pip install -E. Як тільки одиничні тести запущені, починайте тестове використання Django-on-3x і знову продовжуйте роботу коду в 2 і 3. З обережним кодуванням і будьте обережні, щоб не записати 2.7 мостів - наприклад, жодних струн - перемикання буде дуже антикліматичний. Після того, як 3.x повністю стабільний, починайте використовувати код 3.x тільки. Перевага полягає в тому, що виробництво 2.7 завжди перебуває в кроці до переключення.
Дж. Л.

2

Я б перейшов до py3 спочатку. Вам потрібно буде подивитись у setup.pyрепортаж Django на стабільній / 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

2

У мене такий самий випадок із моїм проектом, і я спробував python 3.7.5 з версією Django 2.2.7.

Ви не повинні користуватися python останньою версією 3.8 або останньою версією Django 3.0, тому що ви, можливо, мали шанси, що для будь-якого виду помилок ви не зможете отримати належне рішення для останніх версій.


Це має бути коментар
Бруно

-2

Спробуйте зняти для поточних версій. Python 3.8 та Django 3.0. Шість бібліотеки допоможуть змінити конвенції. У будь-якому випадку вам доведеться зробити деякий рефакторинг, щоб ви могли також зробити його актуальним.


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 за зайвий ризик.
Дж. Л.

Якісь хороші рекомендації щодо розсилки безпеки?
Дейв

Протягом Python sec, Listennotes.com/podcasts/talk-python-to-me/… Але я думаю, що остерігайтесь-3,8-на-раз, а один є останнім часом. Ризиковий бізнес - це хороший і розважальний безпечний подкаст, особливо якщо ви дотримуєтесь міжнародних відносин. Вибачте за прихильний голос, але так, те, що працювало у вашому випадку, може призвести до того, що хтось інший в іншому контексті. Про перетворення від 2 до 3 див. Listenotes.com/podcasts/talk-python-to-me/…
JL
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.