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

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

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

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

Avatar for Python Community Chelyabinsk

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