Що робити, якщо потрібний модуль підтримує лише Python 2 покрокове керівництво

Перед вами невелика інструкція з вирішення досить поширеної проблеми: під час роботи над проектом виявляється, що один із необхідних вам модулів не підтримує Python 3. Для прикладу взято клієнтську бібліотеку для Qualys (засіб забезпечення безпеки). Ось що вам слід зробити:

0. Упевнитися, що це питання ще не вирішено

Перш ніж почати, перевірте, чи не стикався хтось раніше з такою ж проблемою, досліджуйте GitHub. Подивіться — можливо, на PyPi знайдеться відповідний пакет, який містить оновлення для Python 3.

1. Зробити форк

Якщо пошуки ні до чого не привели, починайте змінювати вибраний модуль. Варто зауважити, що зазвичай на PyPi вказуються версії Python, що підтримуються. У модулів, що працюють лише з Python 2, ця інформація часто буває опущена. У прикладі ця частина опису модуля виглядає наступним чином:

Отже, відкрийте основний проект GitHub. Перед тим, як вносити будь-які зміни, обов'язково створіть його форк, потім скачайте або клонуйте репозиторій і створіть нову гілку. Назвою для неї буде, наприклад, «python3».

2. Виправити оператори print

Перше, з чим потрібно розібратися до вирішення проблем з імпортуванням, - це звичайні оператори висновку. Старі оператори print без дужок — одна з найпоширеніших перешкод, з якими можна зіткнутися в контексті переходу від Python 2 до Python 3. У третьому кроці ми будемо використовувати пакет Python-Modernize, який полегшує цей перехід, але його робота не торкнеться README, документації та деякі інші файли. Щоб знайти абсолютно всі старі оператори print в межах модуля,скористайтесь рекурсивним пошуком за вкладеними директоріями:

3. Провести тести

«Найкращий» спосіб перевірити сумісність Python 2 і 3 через повне тестування і CI сервіси на кшталт Circle, Snap або Travis. Але ось невдача — для модуля, що модернізується, ніяких тестів немає. І у вас залишається два варіанти:

  • написати тести самому;
  • провести статичний аналіз коду

Якщо ви сумніваєтеся, що другий варіант може вам чимось допомогти, прочитайте нашу статтю про статичне аналізатор.

Статичний аналіз.Встановіть Python-Modernize:

Спочатку запустіть його в режимі info:

Це дозволить отримати загальне уявлення про те, які зміни буде внесено. Все влаштовує? Тоді запускайте процес змін наступною командою:

Потім зробіть окремий коміт.

Додавання тестів.Перша перевірка: чи можна імпортувати модуль, пакет, підмодуль? Цей тест розкриває багато проблем у Python 3, пов'язаних з просторами імен. Використовуйте Tox для тестування в різному оточенні.

Друга перевірка: чи є у проекті обробка рядків. На тему рядків у Python 3 інформації набагато більше, ніж можна вмістити в цьому пості, але ви можете звернутися до проекту six, в якому розглядається проблема визначення, чи є об'єкт рядком, а також використання юнікоду та методів байтової конвертації.

Третя перевірка передбачає наявність деякого досвіду у роботі з модулем. Ви не зможете відразу зайнятися юніт-тестуванням на основі існуючої кодової бази, якщо не розумітимете, наскільки коректно вона працює на даний момент. Рухайтеся у зворотному напрямку - сфокусуйтесь на інтеграційному тестуванні, а від нього перейдіть до юніт-тестів. Спробуйте дляпочала написати простий скрипт, який використовує модуль за прямим призначенням, а потім доповнюйте його іншими сценаріями використання. Якщо ви вже налаштувалися пропустити цю перевірку, прочитайте наш матеріал про користь юніт-тестування.

4. Оновити setup.py

Відкрийте setup.py і подивіться, які зміни в нього потрібно внести, щоб впевнено заявляти, що модуль, що розглядається, тепер підтримує Python 3:

На що варто звернути увагу:

  1. У коді вище виявилося як вказівку ліцензії BSD, і ліцензії Apache 2. У кодових файлах йдеться Apache 2, а директорії взагалі немає файла LICENSE. Така ситуація могла виникнути через помилку, пов'язану з копіпастом, тому в даному випадку її логічно виправити в setup.py, а потім додати відповідний файл LICENSE.
  2. Розмітка PyPi не відображається. Можна з цим змиритися, можна додати файл RST. Головне, пам'ятайте про те, що це все ж таки не ваш проект.
  3. Не написано яку версію Python підтримує модуль. Додайте цю інформацію до setup.py.
  4. Використання Python-Modernize означає, що модуль залежить від пакету six. Позначте це у полі install_requires . А заразом перевірте, що всі вказані там пакети, від яких залежить модуль, що змінюється, теж підтримують Python 3.

Подивимося, що вийшло:

5. Завантажити до основного проекту

Повернемося на початок. При роботі над вашим проектом ви зіткнулися з тим, що один із модулів не підтримує Python 3. Ви позбавилися проблем сумісності, тепер потрібно вказати оновлену версію модуля у файлі requirements.txt . Переконайтеся, що ви спочатку запустили зміни на GitHub. Це робиться командою:

Pip дозволяє вам встановлювати необхідне не тільки зPyPi, а й прямо з репозиторію Git. Ви можете вказати конкретну гілку, використовуючи символ @. Параметр egg= використовується, щоб передати Pip ім'я пакета.

На цьому етапі можна продовжити запуск інтеграційних випробувань для нової версії.

6. Надіслати пулл реквест

Ось такий пулл реквест вийшов за наслідками розглянутого прикладу. Зачекайте, поки ваші зміни заллють у проект, а потім чекайте, коли на PyPi з'явиться оновлення. (Вірніше, сподівайтеся, що воно там з'явиться.)