Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Александр Полищук. Как обновить Python 2.7 на Python 3.6 и не умереть

Александр Полищук. Как обновить Python 2.7 на Python 3.6 и не умереть

Первый релиз Python 3 версии состоялся еще в далеком 2000 году, но в продакшне до сих пор многие используют устаревающий Python 2.7. Почему же он все еще используется? Все просто — между версиями отсутствует полная обратная совместимость и миграция может оказаться очень болезненной. Я постараюсь ответить — стоит ли вообще обновляться и с какими трудностями можно столкнуться в процессе обновления.

Python Community Chelyabinsk

December 08, 2018
Tweet

More Decks by Python Community Chelyabinsk

Other Decks in Programming

Transcript

  1. Как обновить Python 2.7 на Python 3.6 и не умереть

    Александр Полищук Twitter, Medium: @alpolishchuk Facebook: @alxpolishchuk
  2. Эволюция Python  Появился в феврале 1991 года  Python

    1.0 – январь 1994 года Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  3. Эволюция Python  Появился в феврале 1991 года  Python

    1.0 – январь 1994 года  Python 2.0 – 16 октября 2000 года Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  4. Эволюция Python  Появился в феврале 1991 года  Python

    1.0 – январь 1994 года  Python 2.0 – 16 октября 2000 года  Python 2.6 – 1 октября 2008 года («соответствует» 3.0, включен ряд возможностей этой версии) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  5. Эволюция Python  Появился в феврале 1991 года  Python

    1.0 – январь 1994 года  Python 2.0 – 16 октября 2000 года  Python 2.6 – 1 октября 2008 года («соответствует» 3.0, включен ряд возможностей этой версии)  Python 3.0 (так же Python 3000 или Py3K) – 3 декабря 2008 года Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  6. Эволюция Python  Появился в феврале 1991 года  Python

    1.0 – январь 1994 года  Python 2.0 – 16 октября 2000 года  Python 2.6 – 1 октября 2008 года («соответствует» 3.0, включен ряд возможностей этой версии)  Python 3.0 (так же Python 3000 или Py3K) – 3 декабря 2008 года  Python 3.1 – 27 июня 2009 года Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  7. Эволюция Python  Появился в феврале 1991 года  Python

    1.0 – январь 1994 года  Python 2.0 – 16 октября 2000 года  Python 2.6 – 1 октября 2008 года («соответствует» 3.0, включен ряд возможностей этой версии)  Python 3.0 (так же Python 3000 или Py3K) – 3 декабря 2008 года  Python 3.1 – 27 июня 2009 года  Python 2.7 – 3 июля 2010 года (соответствует 3.1, включен ряд возможностей этой версии) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  8. Почему Python 2 все еще используется?  Отсутствие обратной совместимости

    между версиями  Отсутствие особых «killer features» Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  9. Почему Python 2 все еще используется?  Отсутствие обратной совместимости

    между версиями  Отсутствие особых «killer features»  В большинстве *nix-дистрибутивов установлен по умолчанию Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  10. Почему Python 2 все еще используется?  Отсутствие обратной совместимости

    между версиями  Отсутствие особых «killer features»  В большинстве *nix-дистрибутивов установлен по умолчанию  Не все библиотеки поддерживают обе версии языка Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  11. Плюсы после обновления  Юникод по умолчанию  Keyword-Only Arguments

    (PEP 3102)  Доступ к переменным из внешнего замыкания (PEP 3104) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  12. Плюсы после обновления  Юникод по умолчанию  Keyword-Only Arguments

    (PEP 3102)  Доступ к переменным из внешнего замыкания (PEP 3104)  Function annotations (PEP 3107) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  13. Плюсы после обновления  Юникод по умолчанию  Keyword-Only Arguments

    (PEP 3102)  Доступ к переменным из внешнего замыкания (PEP 3104)  Function annotations (PEP 3107)  Улучшенная распаковка элементов (PEP 3132) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  14. Плюсы после обновления  Юникод по умолчанию  Keyword-Only Arguments

    (PEP 3102)  Доступ к переменным из внешнего замыкания (PEP 3104)  Function annotations (PEP 3107)  Улучшенная распаковка элементов (PEP 3132)  Asyncio в стандартной библиотеке (PEP 3156) (c версии 3.4) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  15. Плюсы после обновления  Юникод по умолчанию  Keyword-Only Arguments

    (PEP 3102)  Доступ к переменным из внешнего замыкания (PEP 3104)  Function annotations (PEP 3107)  Улучшенная распаковка элементов (PEP 3132)  Asyncio в стандартной библиотеке (PEP 3156) (c версии 3.4)  f-строки (PEP 498) (c версии 3.6) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  16. Плюсы после обновления  Юникод по умолчанию  Keyword-Only Arguments

    (PEP 3102)  Доступ к переменным из внешнего замыкания (PEP 3104)  Function annotations (PEP 3107)  Улучшенная распаковка элементов (PEP 3132)  Asyncio в стандартной библиотеке (PEP 3156) (c версии 3.4)  f-строки (PEP 498) (c версии 3.6)  И т.д. Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  17. Что из себя представляет проект Континент TLS  C++ 

    Python Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  18. Что из себя представляет проект Континент TLS  C++ 

    Python  JavaScript (React) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  19. Что из себя представляет проект Континент TLS  C++ 

    Python  JavaScript (React)  Redis Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  20. Что из себя представляет проект Континент TLS  C++ 

    Python  JavaScript (React)  Redis  PostgreSQL Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  21. Используемые фреймворки и библиотеки в Континент TLS  Django 

    Django REST Framework Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  22. Используемые фреймворки и библиотеки в Континент TLS  Django 

    Django REST Framework  Celery (Redis as broker) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  23. Используемые фреймворки и библиотеки в Континент TLS  Django 

    Django REST Framework  Celery (Redis as broker)  Cryptography Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  24. Используемые фреймворки и библиотеки в Континент TLS  Django 

    Django REST Framework  Celery (Redis as broker)  Cryptography  Python-ldap Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  25. Используемые фреймворки и библиотеки в Континент TLS  Django 

    Django REST Framework  Celery (Redis as broker)  Cryptography  Python-ldap  Requests Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  26. Как мы готовились к обновлению Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk

     Написали unittest’ы  Добавили еще unittest’ов
  27. Как мы готовились к обновлению Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk

     Написали unittest’ы  Добавили еще unittest’ов  Постарались покрыть unittest’ами как можно больше кода
  28. Как мы готовились к обновлению Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk

     Написали unittest’ы  Добавили еще unittest’ов  Постарались покрыть unittest’ами как можно больше кода  Опционально: использование библиотеки __future__ (unicode_literals, division, print_function)
  29. Первые ошибки  Метод encode(decode)string из модуля base64 устарел, вместо

    него – encode(decode)bytes (начиная с версии 3.1) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  30. Первые ошибки  Метод encode(decode)string из модуля base64 устарел, вместо

    него – encode(decode)bytes (начиная с версии 3.1)  Отсутствие метода assertDictContainsSubset (после версии 3.2) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  31. Первые ошибки  Метод encode(decode)string из модуля base64 устарел, вместо

    него – encode(decode)bytes (начиная с версии 3.1)  Отсутствие метода assertDictContainsSubset (после версии 3.2)  Вместо assertItemsEqual – assertCountEqual (появился в версии 3.2) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  32. Первые ошибки  Метод encode(decode)string из модуля base64 устарел, вместо

    него – encode(decode)bytes (начиная с версии 3.1)  Отсутствие метода assertDictContainsSubset (после версии 3.2)  Вместо assertItemsEqual – assertCountEqual (появился в версии 3.2)  Mock в стандартной библиотеке unittest (появился в версии 3.3) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  33. Первые ошибки  Метод encode(decode)string из модуля base64 устарел, вместо

    него – encode(decode)bytes (начиная с версии 3.1)  Отсутствие метода assertDictContainsSubset (после версии 3.2)  Вместо assertItemsEqual – assertCountEqual (появился в версии 3.2)  Mock в стандартной библиотеке unittest (появился в версии 3.3)  encode/decode – теперь это не про кодировку строки Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  34. Первые ошибки  Метод encode(decode)string из модуля base64 устарел, вместо

    него – encode(decode)bytes (начиная с версии 3.1)  Отсутствие метода assertDictContainsSubset (после версии 3.2)  Вместо assertItemsEqual – assertCountEqual (появился в версии 3.2)  Mock в стандартной библиотеке unittest (появился в версии 3.3)  encode/decode – теперь это не про кодировку строки  True division (PEP 238) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  35. Первые ошибки  Некоторые функции (zip, map, filter), а также

    методы словарей (.keys(), .values(), .items()) возвращают итератор вместо списка Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  36. Первые ошибки  Некоторые функции (zip, map, filter), а также

    методы словарей (.keys(), .values(), .items()) возвращают итератор вместо списка  xrange отсутствует, вместо него – range Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  37. Первые ошибки  Некоторые функции (zip, map, filter), а также

    методы словарей (.keys(), .values(), .items()) возвращают итератор вместо списка  xrange отсутствует, вместо него – range  Новый urllib, состоящий из 2-х модулей – urllib.parse и urllib.request Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  38. Первые ошибки  Некоторые функции (zip, map, filter), а также

    методы словарей (.keys(), .values(), .items()) возвращают итератор вместо списка  xrange отсутствует, вместо него – range  Новый urllib, состоящий из 2-х модулей – urllib.parse и urllib.request  Модуль Cookie «переехал» в модуль http (http.cookie) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  39. Первые ошибки  Некоторые функции (zip, map, filter), а также

    методы словарей (.keys(), .values(), .items()) возвращают итератор вместо списка  xrange отсутствует, вместо него – range  Новый urllib, состоящий из 2-х модулей – urllib.parse и urllib.request  Модуль Cookie «переехал» в модуль http (http.cookie)  Новый формат применения прав в os.chmod (0755 устарел, осталось только 0о755) (PEP 3127) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  40. Первые ошибки  Некоторые функции (zip, map, filter), а также

    методы словарей (.keys(), .values(), .items()) возвращают итератор вместо списка  xrange отсутствует, вместо него – range  Новый urllib, состоящий из 2-х модулей – urllib.parse и urllib.request  Модуль Cookie «переехал» в модуль http (http.cookie)  Новый формат применения прав в os.chmod (0755 устарел, осталось только 0о755) (PEP 3127)  Отсутствие литеры L в конце больших чисел (PEP 237) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  41. Вторая волна – самописные модули с C++ extensions  PyString_*

    больше не используется, остался только PyUnicode_* Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  42. Вторая волна – самописные модули с C++ extensions  PyString_*

    больше не используется, остался только PyUnicode_*  PyInt_* больше не используется, остался только PyLong_* Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  43. Вторая волна – самописные модули с C++ extensions  PyString_*

    больше не используется, остался только PyUnicode_*  PyInt_* больше не используется, остался только PyLong_*  Новая инициализация модуля (PEP 3121) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  44. Новая инициализация C++ extensions  PyInit_<modulename> (раньше init<modulename>)  Функция

    инициализации теперь возвращает PyObject* (раньше NULL) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  45. Новая инициализация C++ extensions  PyInit_<modulename> (раньше init<modulename>)  Функция

    инициализации теперь возвращает PyObject* (раньше NULL)  Структура PyModuleDef Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  46. Новая инициализация C++ extensions  PyInit_<modulename> (раньше init<modulename>)  Функция

    инициализации теперь возвращает PyObject* (раньше NULL)  Структура PyModuleDef  Создание объекта модуля - PyModule_Create (раньше Py_InitModule) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  47. Ещё один бонус – обновление DRF  DynamicListRoute устарел, остался

    только DynamicRoute Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  48. Ещё один бонус – обновление DRF  DynamicListRoute устарел, остался

    только DynamicRoute  Новый boolean kwarg для Route и DynamicRoute - detail Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  49. Ещё один бонус – обновление DRF  DynamicListRoute устарел, остался

    только DynamicRoute  Новый boolean kwarg для Route и DynamicRoute - detail  list_route/detail_route устарели, вместо них теперь action(detail: boolean) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  50. Ещё один бонус – обновление DRF  DynamicListRoute устарел, остался

    только DynamicRoute  Новый boolean kwarg для Route и DynamicRoute - detail  list_route/detail_route устарели, вместо них теперь action(detail: boolean)  filters переехали в django_filters.rest_framework (в 3 версии DRF) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  51. Что же в итоге?  Снизилось потребление памяти  Код

    стало удобнее писать Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  52. Что же в итоге?  Снизилось потребление памяти  Код

    стало удобнее писать  Chained exceptions – стало удобнее искать ошибку в коде Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  53. Что же в итоге?  Снизилось потребление памяти  Код

    стало удобнее писать  Chained exceptions – стало удобнее искать ошибку в коде  Удовлетворение от проделанной миграции Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  54. Ложка дегтя  Python-ldap – в результатах теперь bytestring 

    hashlib – на вход только bytestring (на выходе остался string) Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  55. Ложка дегтя  Python-ldap – в результатах теперь bytestring 

    hashlib – на вход только bytestring (на выходе остался string)  Subprocess.communicate – теперь принимает только bytestring и возвращает также bytestring Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  56. Ложка дегтя bytestring = b’bytestring’ f”format with {bytestring}” -> “format

    with b’bytestring’” Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  57. Ложка дегтя bytestring = b’bytestring’ f”format with {bytestring}” -> “format

    with b’bytestring’” >> ‘some_string’ == b’some_string’ Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  58. Ложка дегтя bytestring = b’bytestring’ f”format with {bytestring}” -> “format

    with b’bytestring’” >> ‘some_string’ == b’some_string’ False Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  59. Ложка дегтя bytestring = b’bytestring’ f”format with {bytestring}” -> “format

    with b’bytestring’” >> ‘some_string’ == b’some_string’ False >> ‘test’ in b’test_string’ Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  60. Ложка дегтя bytestring = b’bytestring’ f”format with {bytestring}” -> “format

    with b’bytestring’” >> ‘some_string’ == b’some_string’ False >> ‘test’ in b’test_string’ TypeError Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  61. Ложка дегтя django.shortcuts.redirect  set_cookie(“cookie_key”, “куки”)  force_text(“куки”)  Python2.7

    -> “\u043a\u0443\u043a\u0438”  Python3.6 -> “куки” Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  62. Ложка дегтя django.shortcuts.redirect  set_cookie(“cookie_key”, “куки”)  force_text(“куки”)  Python2.7

    -> “\u043a\u0443\u043a\u0438”  Python3.6 -> “куки” RFC 5987 Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  63. Ложка дегтя django.shortcuts.redirect  set_cookie(“cookie_key”, “куки”)  force_text(“куки”)  Python2.7

    -> “\u043a\u0443\u043a\u0438”  Python3.6 -> “куки” RFC 5987  encode(“unicode-escape”) -> b”\\u043a\\u0443\\u043a\\u0438” Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk
  64. Ложка дегтя django.shortcuts.redirect  set_cookie(“cookie_key”, “куки”)  force_text(“куки”)  Python2.7

    -> “\u043a\u0443\u043a\u0438”  Python3.6 -> “куки” RFC 5987  encode(“unicode-escape”) -> b”\\u043a\\u0443\\u043a\\u0438”  decode(“utf-8”) -> “\\u043a\\u0443\\u043a\\u0438” Twitter, Medium: @alpolishchuk, Facebook: alxpolishchuk