[Перевод] Python 3 в Facebook

Всем привет!

Запустили юбилейный пятый поток курса «Разработчик Python». Перед стартом каждого потока часто спрашивают какую версию мы используем в обучении (вообще обе и не только, как бы это странно не звучало, учитывая как называется курс, Python) и разные нюансы миграции с одной версии на другую. Сегодня мы хотим поделиться статьёй об опыте миграцию с 2 на 3 в Facebook, которую рассказывали на PyConf.

Поехали.

Переход на Python 3 стал значительно популярней за последние годы, но процесс еще далек от завершения. В инфраструктуре многих крупных компаний, использующих Python, остаются большие блоки кода на Python 2.7, и Facebook — не исключение. Джейсон Фрайд (Jason Fried) посетил PyCon 2018, чтобы рассказать об изменениях, произошедших в компании за последние 4 года — в самом начале Python 3 практически отсутствовал, но в итоге стал основной версией Python в компании. Джейсон помог достичь этой цели, и его доклад [видео на YouTube] — отличный источник идей для других организаций, которые хотят провести миграцию.

Фрайд начал работать в Facebook в 2011 году и быстро понял, что нужно учить Python, если он хочет получать ревью кода быстрее. Чуть позже он понял, что стал основной движущей силой за переход на Python 3 в Facebook. Это никогда не входило в его планы, и случилось само собой по мере его работы с Python.

r2drx5v-vxvsk3l8pd7eaer8pf4.png

Фрайд начал с того, что стал принимать активное участие во внутренней группе Python, и часто оказывался первым, готовым ответить на возникающие вопросы. В итоге, он прославился («скорее приобрел дурную славу») среди питонистов в Facebook, тем что фиксил код самостоятельно, не спрашивая разрешения, если видел, что язык используется неправильно. Это возможно в Facebook, в связи с отсутствием вертикальной иерархии контроля; у всех есть столько же прав, чтобы откатить ваши изменения, сколько у вас, чтобы изначально эти изменения совершить. Со временем эти правки помогли укрепить авторитет Фрайда в сообществе Python Facebook, который пригодится ему в процессе миграции.

По словам Фрайда, менять что-то вроде версии языка Python в масштабах Facebook требовало некоторого времени и огромного количества дипломатии. Он хотел рассказать «историю о том, как я и пара других инженеров в свободное время и без каких-либо полномочий сделали Python 3 основной версией в Facebook».

В 2013 году в Facebook присутствовала зачаточная поддержка Python 3.3. Она появилась как часть задачи по добавлению поддержки Python 3 в систему сборки. Но эта задача была заблокирована поддержкой Python 3 в библиотеках Facebook, которая в свою очередь была заблокирована отсутствием поддержки Python 3 в системе сборки. Ситуация как из «Уловки-22»: Python 3 был «доступен», но ничто в среде Facebook его не поддерживало.

Кроме того, в 2013 году Python 3 в Facebook был окружен негативными настроениями. Почти все думали, что компания просто останется на Python 2.7 навсегда. Также велись разговоры о переходе на совершенно другой язык. Даже сам Фрайд говорил (во внутренней группе), что переход на Python 3 никогда не произойдет в Facebook. Только один человек бросил вызов этому заявлению и предложил что-то с этим сделать; в тот момент Фрайд проигнорировал призыв к действию, но продолжил думать об этой идее.

Луч надежды

Но, по словам Фрайда, надежда теплилась. В январе 2013 года, используемому «линтеру» потребовались четыре импорта из __future__ (print_function, division, absolute_imports, andunicode_literals). Изначально они появились с целью продлить жизнь кодовой базы Python 2, и были добавлены везде, чтобы линтер перестал ругаться. Это, в итоге, упростило конвертирование модулей на Python 3.

В Facebook «повсеместно используется» фреймворк для сериализация и удаленных вызовов процедур Apache Thrift. И его исключительная совместимость с Python 2 стала основным блокером. Но в опросе на тему потенциально интересных нововведений, проведенном группой Trift в Facebook, популярным вариантом оказалось добавление поддержки Python 3. Фрайд проголосовал именно за него, но еще не потому что хотел заниматься продвижением Python 3; он просто посчитал, что интерфейс Python 2 похож на что-то из Java, и поэтому требует рефакторинга.

Его мыслительный процесс стал меняться после лекции Гвидо ван Россум (Guido van Rossum) в Yelp, Сан-Франциско на тему «Tulip», который оказался модулем asyncio. Фрайд всегда был фанатом асинхронного программирования на Python, но считал его фрагментированным из-за различий между фреймворками (например, Twisted, gevent), которые его предоставляли. Tulip выглядел так, будто может сделать асинхронный ввод-вывод интероперабельным. Лекция еще не успела закончиться, а Фрайд уже общался с командой Trift Facebook, предлагая внедрить поддержку Tulip для Python 3 вместого того, чтобы ждать порта Twisted, gevent и других. Через несколько дней Trift опубликовали роудмап, показывающий предстоящую поддержку Python 3 и Tulip.

Это произошло в начале 2014 года, но ничего не менялось еще в течение шести месяцев; пользователи не появились и не планировали это делать, на самом деле, они и не знали ни о каких изменениях.

Новый проект

В августе 2014 года, Фрайд начал проект по переписыванию унаследованного сервиса. Изначально для этих целей он планировал использовать Python 2 и gevent, но затем понял, что к моменту завершения работы оно уже устареет. Кто-то должен быть первым, чтобы произошли изменения; для Facebook и Python 3 это был именно Фрайд. «Именно вы должны стать этим человеком для Python 3 в вашей организации».

Итак, он начала свой проект, используя Python 3 и «все было сломано»; неудивительно, что никто не пользовался Python 3. Система сборки даже не могла собрать его код, а все сторонние пакеты wheel были доступны только для Python 2. А когда он все-таки починил достаточно вещей, чтобы собрать свой сервис, тот мгновенно падал на запуске — из-за чего-то глубоко в коде, что настраивало точки входа в системе Facebook.

Поэтому, чтобы заставить код работать, Фрайд был вынужден починить все остальное; Он пересобрал сотни сторонних wheel«ов, чтобы они работали с обеими версиями Python, обновил все внутренние библиотеки, чтобы сделать их совместимыми с 2/3. Однако, каждый день кто-нибудь коммитил в его зависимости изменения только для Python 2. Неудивительно, Фрайд устал фиксить регрессии. Единственное решение — принудительно ввести соответствие требованиям Python 3 внутри организации, но в Facebook подобное невозможно. Однако, если начать себя вести так, будто у тебя есть на это полномочия, люди начнут верить, что они у тебя действительно есть.

Фрайд, используя свое социальное влияние, добавил линтер Pyflakes в процесс сборки. С учетом наличия PEP 8, он обосновал добавление нового тем, что тот будет решать другую категорию проблем кода; плюс, в Pyflakes было меньше ложных срабатываний, поэтому он меньше раздражал разработчиков. Фрайд настроил все так, чтобы Pyflakes запускался на всем коде, отправленном на ревью, сначала для Python 2, а затем Python 3. Это помогло распределить работу по соблюдению совместимости с Python 3 между всеми разработчиками, что позволило достичь прогресса в проекте Фрайда.

Сначала ему приходилось объяснять людям, что линтер не поломан, и есть смысл доработать код до совместимости с Python 3. Если бы разработчики поверили, что переход к Python 3 слишком сложен, они бы вернулись к мысли «останемся с Python 2 навсегда». Силами Фрайда, сделать код совместимым с Python 3 стало гораздо проще. «Заткнуть линтер», а значит и самого Фрайда, стало проще, чем жаловаться на необходимость править код, поэтому все так и поступили.

Обучение

Все это помогло остановить «кровотечение», но не помогло достичь заметного прогресса по внедрению Python 3 в Facebook. Фрайд присоединился к команде, которая преподавала Python новым сотрудникам. Линтеры уже выдавали ошибки, когда код не был совместим с 2 или 3, но Фрайд хотел достичь точки, где код, совместимый с 2/3, писался только для легаси проектов, а новый код писался только на Python 3. В который раз Фрайд взял ситуацию в свои руки: чтобы сделать это заявление, в 2015 году он поменял слайды в классе Python для новых сотрудников. Идея заключалась в том, что в какой-то неизвестный момент в будущем, Facebook захочет переключиться на Python 3, поэтому нет смысла писать код для Python 2 — когда-нибудь его придется переписать. Он объяснил новичкам, что все это должно работать внутри инфраструктуры Facebook и систем сборки, а если это было невозможно, нужно было отправить баг, или починить все самостоятельно. «Как ни странно, это сработало».

В январе 2015 года Фрайд «наконец выпустил» свой проект. Он потратил остаток года, рассказывая людям о его успешности и о необходимости переключиться на Python 3. В течение года появились новые союзники в переходе на Python 3 в Facebook.

z4lxcvkjk0swjxny1k8ef7rmags.png

Одним из них был Лука Ланга (Łukasz Langa), который «как-то убедил Instagram перейти на Python 3». В 2016 году Ланга сформировал в Facebook новую команду, ответственную за контролем Python, которую назвали «Министерство Глупых Походок». Так как они были «командой Python», «фиктивный авторитет», упомянутый выше, сработал; люди считали, что они могут принимать решения насчет Python в Facebook.

В 2016 году наблюдался медленный, но стабильный рост использования Python 3 в компании. О нем говорили на собраниях, использовали в новых проектах. Мнение менялось, хоть Python 3 все еще не считался версием по умолчанию, и проекты добровольно выбирали его использование. В мае 2016 года Фрайд сообщил о своем намерении переключить систему сборки на Python 3 по умолчанию. Идея была всецело поддержана, поэтому через несколько дней переключение было проведено — без негативных последствий.

В конце 2016 года команда проекта выпустила отчет с результатами переключения на Python 3. Разработчики просто запустили 2to3 в коде и исправили все моменты, на которые он ругался. Когда запустили полученный код, обнаружилось, что он на 40% быстрее и использует только половину памяти. Это указало на миф, с которым Фрайд часто сталкивался: Python 3 медленнее, чем Python 2. Это могло быть правдой для ранних версий Python 3, но сейчас это не актуально.

Хорошие вещи

В начале 2017 года Instagram завершил миграцию на Python 3 и Facebook пожинал плоды «славного будущего, где можно радоваться хорошим вещам». Обновление версии Python оказалось не таким страшным процессом и открыло возможность использовать новые функции. Разработчики Facebook теперь могут сконцентрироваться на таких проблемах, как новые функции статической типизации или миграция сервисов для использования asyncio. «Python в Facebook снова стал веселым».

Новая проблема — люди спрашивают, когда можно отказаться от поддержки Python 2. Когда появляются регрессии в поддержке Python 2 библиотек или модулей, разработчики часто спрашивают, можно ли им просто перейти на Python 3. Проблема противоположна той, что была несколько лет назад. «О, как прекрасен мир, в котором я живу».

Во время лекции Фрайд показал график точек входа в Python сервиса Facebook, начиная с Q3 2015 года — на тот момент в общей сложности было всего 4 точки Python 3. В момент перехода к Python 3, в середине 2016 года, 4% всех точек уже были Python 3. В марте 2018 года их количество перевалило за 50%; в середине мая, на момент лекции, их было 55% «из десятков тысяч точек входа Facebook». По словам Фрайда, в компании теперь стыдно писать код, который работает только на Python 2.

Затем Фрайд проанализировал процесс. Он отметил, что необходимо сделать больше, чем просто создать что-то новое; нужно вести к этому разработчиков, «будучи тем изменением, которое вы хотите увидеть». Нужно привлекать людей, даже если они не будут понимать, что помогают. В этом содействуют линтеры и юнит-тесты. Очень важно учить новых сотрудников тому, к чему вы стремитесь. Когда вы достигните результата, отпразднуйте, наслаждаясь «хорошими вещами»: напишите «классный код на Python 3». Видя, как новые функции могут быть использованы, остальные тоже захотят перейти.

Фрайд ответил на несколько вопросов из аудитории. Один вопрос был посвящен тому, как провести такое изменение в более традиционной, иерархической организации. Фрайд предположил, что это может быть даже проще, так как не нужно убеждать тысячи разработчиков, а лишь цепочку менеджеров, начиная с того, кто видит преимущества перехода. Но с другой стороны, это может быть сложнее, если культура компании консервативна. Здесь поможет фокусирование на улучшении качества кода. Другой вопрос касался неделимого кода, который не разбит на множество входных точек. Для такой ситуации Фрайд предложил посмотреть презентацию Instagram (видео на YouTube) с PyCon 2017.

Другие организации могут многое почерпнуть из этой лекции, но ясно, что важно иметь упорного сторонника, готового контролировать и координировать весь процесс. Компаниям, планирующим подобный переход, понадобится такой человек как Фрайд.

THE END

Ждём вопрос и комментарии, которые можно оставить тут или задать напрямую Стасу на его открытом уроке.

© Habrahabr.ru