Translate
August 25, 2019

Ваше руководство по исходному коду CPython

К сожалению данная платформа не поддерживает TOC (Table of Content), также как и не подсвечивает синтаксис кода, что в очередной раз подталкивает меня на ее замену чем-то более универсальным, поэтому содержание без ссылок на якоря, но оно имеется, для того, чтобы совсем не потеряться. Заодно и ссылку на источник оставлю сразу здесь. Приятного прочтения.

Содержание

  • Часть 1. Введение в CPython
    • Что же содержится в исходном коде?
    • Компиляция CPython (macOS)
    • Компиляция CPython (Linux)
    • Компиляция CPython (Windows)
    • Что делает компилятор?
    • Почему CPython написан на C, а не на Python?
    • Спецификация языка Python
    • Управление памятью в CPython
    • Сборщик мусора
    • Заключение
  • Часть 2. Процесс интерпретации в Python
    • Установка конфигурации среды исполнения
    • Чтение файлов/входных данных
    • Лексический и синтаксический анализ
    • Абстрактные синтаксические деревья (AST)
    • Заключение
  • Часть 3. Цикл компиляции и исполнения CPython
    • Компиляция
    • Исполнение
    • Заключение
  • Часть 4. Объекты в CPython
    • Базовый тип объекта
    • Тип Bool и Long Integer
    • Обзор типа Generator
    • Заключение
  • Часть 5. Стандартная библиотека CPython
    • Модули Python
    • Модули Python и C
    • Набор регрессионных тестов CPython
    • Установка определенной версии
  • Исходный код CPython: Заключение

Есть ли какие-то части Python'а, которые кажутся волшебными? Вот, например, как словари работают намного быстрее, чем циклическое перемещение по списку для поиска нужного элемента. Как генератор запоминает состояние переменных каждый раз, когда выдает значение, и почему ему никогда не приходится выделять память, как другим языкам? Оказывается, CPython, наиболее популярная среда исполнения Python написана на удобочитаемом C и Python коде. В этом руководстве мы рассмотрим исходный код CPython.

Вы узнаете обо всех концепциях, лежащих в основе внутреннего устройства CPython, о том, как они работают, и получите наглядные объяснения по ходу процесса.

Вы научитесь:

    • Чтению и навигации по исходному коду
    • Компиляции исходного кода CPython
    • Навигация и понимание внутренней работы таких понятий, как списки, словари и генераторы
    • Запуску набора тестов
    • Изменять или обновлять компоненты библиотеки CPython, добавляя их в будущие версии

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

Данное руководство разделено на пять частей. Не торопитесь с каждой частью и попробуйте демонстрационные и интерактивные компоненты. Вы сможете ощутить чувство прогресса, когда поймете основные понятия Python, которые помогут вам стать лучшим программистом на Python.


Часть 1. Введение в CPython

Когда вы набираете python в консоли или устанавливаете дистрибутив Python с сайта python.org, вы запускаете при помощи CPython. CPython - одна из многих версий Python, поддерживаемая и написанная разными командами разработчиков. Возможно, вам приходилось слышать еще о таких программах, как PyPy, Cython и Jython.

Уникальность CPython заключается в том, что он содержит как среду исполнения, так и общие языковые спецификации, которые используются во всех средах исполнения Python. CPython - это "официальная", или справочная реализация Python.

Спецификация языка Python - это документ, который является описанием языка Python. Например, в нем сказано, что assert является зарезервированным ключевым словом, и что [] используется для индексирования (indexing), нарезки (slicing) и создания пустых списков.

Подумайте о том, что вы ожидаете увидеть в дистрибутиве Python на вашем компьютере:

    • При вводе python без файла или модуля появится интерактивная подсказка.
    • Вы можете импортировать встроенные модули из стандартной библиотеки, такие как json.
    • Вы можете устанавливать пакеты из интернета с помощью pip.
    • Вы можете протестировать свои приложения с помощью встроенной библиотеки модульного тестирования (unittest).

Все это часть дистрибутива CPython. Это гораздо больше, чем просто компилятор.

Примечание: Эта статья написана на основе версии 3.8.0b3 исходного кода CPython.

Что же содержится в исходном коде?

Исходный дистрибутив CPython поставляется с целым рядом инструментов, библиотек и компонентов. Мы рассмотрим их в данной статье. Сначала остановимся на компиляторе.

Чтобы скачать копию исходного кода CPython, вы можете использовать git загрузки последней версии в рабочую локальную копию:

~$ git clone https://github.com/python/cpython
~$ cd cpython
~$ git checkout v3.8.0b3
Примечание: Если у вас нет Git'а, вы можете загрузить исходный текст в ZIP-файле, непосредственно с сайта GitHub.

Внутри загруженного каталога cpython вы найдете следующие подкаталоги:

cpython/
│
├── Doc      ← Исходный материал документации
├── Grammar  ← Компьютерно-читаемое определение языка
├── Include  ← Заголовочные файлы на C
├── Lib      ← Стандартные библиотечные модули, написанные на языке Python
├── Mac      ← Файлы поддержки для macOS
├── Misc     ← Различные файлы
├── Modules  ← Стандартные библиотечные модули написанные на C
├── Objects  ← Основные типы данных и модель object
├── Parser   ← Исходный код синтаксического анализатора Python
├── PC       ← Файлы поддержки сборки Windows
├── PCbuild  ← Файлы поддержки сборки Windows для более старых версий Windows
├── Programs ← Исходный код исполняемого файла python и других бинарных файлов
├── Python   ← Исходный код интерпретатора CPython
└── Tools    ← Отдельные инструменты, необходимые для создания или расширения Python

Далее мы скомпилируем CPython из исходного кода. Этот шаг требует компилятора языка С и некоторых инструментов для сборки, которые зависят от используемой вами операционной системы.

Компиляция CPython (macOS)

...

Компиляция CPython (Linux)

...

Компиляция CPython (Windows)

...

Что делает компилятор?

Целью компилятора является преобразование одного языка в другой. Думайте о компиляторе как о переводчике. Вы нанимаете переводчика, который слушает вас на английском языке, а затем говорит на японском:

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

Одним из важных решений, которое необходимо принять при выборе компилятора, являются требования переносимости системы. Java и .NET CLR скомпилируются на промежуточном языке, чтобы скомпилированный код можно было переносить на несколько архитектур систем. C, Go, C++ и Pascal скомпилируются в низкоуровневый исполняемый файл, который будет работать только на системах, похожих на ту, что была скомпилирована.

Поскольку приложения Python обычно распространяются в виде исходного кода, роль Python заключается в преобразовании исходного кода Python и его выполнении за один шаг. Внутри CPython компилирует ваш код. Популярное заблуждение заключается в том, что Python - это интерпретируемый язык. На самом деле, он уже скомпилирован.

Код Python не компилируется в машинный код. Он компилируется в специальный низкоуровневый промежуточный язык под названием bytecode, который понимает только CPython. Этот код хранится в .pyc файлах в скрытом каталоге и кэшируется для исполнения. Если дважды запустить одно и то же приложение Python без изменения исходного кода, то во второй раз оно всегда будет работать намного быстрее. Это связано с тем, что он загружает скомпилированный байт-код и выполняет его напрямую.

Почему CPython написан на C, а не на Python?

...

Спецификация языка Python

...

Вот скриншот грамматики в Python 3.8a2:

Грамматика в Python 3.8a2

Пакет Python, используемый для создания этого графика, instaviz, будет рассмотрен в одной из следующих глав.

Управление памятью в CPython

...

Сборщик мусора

...

Заключение

В первой части мы рассмотрели структуру репозитория исходного кода, процесс его компиляции и спецификацию языка Python. Эти основные понятия будут иметь важнейшее значение во второй части, когда вы погрузитесь в процесс интерпретации Python.


Часть 2. Процесс интерпретации в Python

Теперь, когда вы увидели грамматику Python и управление памятью, вы можете следить за процессом от написания кода до части, где ваш код выполняется.

Существует пять способов вызова бинарных файлов Python:

    • Для выполнения одной команды с параметрами -c и команды Python
    • Чтобы запустить модуль с параметрами -m и именем модуля
    • Чтобы запустить файл с указанием имени файла
    • Для запуска stdin с помощью пайпа оболочки
    • Для запуска REPL и выполнения команд по одной за раз
У Python так много способов выполнения скриптов, что это может быть немного ошеломляющим. Даррен Джонс разработал отличный курс по работе со сценариями Python, если вы хотите узнать об этом больше.

Три исходных файла, которые вам нужно просмотреть, чтобы увидеть данный процесс:

    1. Programs/python.c это простая точка входа.
    2. Modules/main.c содержит код, объединяющий весь процесс, конфигурацию загрузки, исполняемый код и очистку памяти.
    3. Python/initconfig.c загружает конфигурацию из системного окружения и объединяет ее с любыми флагами командной строки.

Данная диаграмма показывает, как вызывается каждая из этих функций:

Диаграмма вызова каждой из вышеперечисленных функций

Режим исполнения определяется конфигурацией.

...

Установка конфигурации среды исполнения

Диаграмма вызова каждой из вышеперечисленных функций

...

Чтение файлов/входных данных

...

Лексический и синтаксический анализ

...

Абстрактные синтаксические деревья (AST)

...

Заключение

Универсальность CPython и API низкого уровня исполнения делают его идеальным кандидатом для встроенного скриптового движка. Вы увидите CPython, используемый во многих приложениях пользовательского интерфейса, таких как дизайн игр, 3D графика и системы автоматизации.

Процесс интерпретатора является гибким и эффективным, и теперь у вас есть понимание того, как он работает, и вы готовы понять работу компилятора.


Часть 3. Цикл компиляции и исполнения CPython

Во второй части вы видели, как интерпретатор CPython принимает входной данные, например, файл или строку, и преобразует их в логическое Абстрактное Синтаксическое Дерево (AST). Мы по-прежнему не достигли стадии, на которой этот код может быть выполнен. Далее, нам нужно углубиться в конвертацию Абстрактного Синтаксического Дерева в набор последовательных команд, которые процессор может понять.

Компиляция

...

Исполнение

...

Заключение

В этой части вы рассмотрели самый сложный элемент CPython: компилятор. Оригинальный автор Python, Гвидо ван Россум, заявил, что компилятор CPython должен быть "тупым", чтобы люди могли его понять.

Разбив процесс компиляции на небольшие, логические этапы, его гораздо легче понять.

В следующей главе мы свяжем процесс компиляции с основой всего Python-кода, объектом (object).


Часть 4. Объекты в CPython

...

Базовый тип объекта

...

Тип Bool и Long Integer

...

Обзор типа Generator

...

Заключение

...


Часть 5. Стандартная библиотека CPython

...

Модули Python

...

Модули Python и C

...

Набор регрессионных тестов CPython

...

Установка определенной версии

...


Исходный код CPython: Заключение

Поздравляю, ты сделал это! Твой чай остыл? Сделай себе еще одну чашку. Ты заслужил это.

Теперь, когда вы увидели исходный код CPython, модули, компилятор и инструменты, вы, возможно, захотите внести некоторые изменения и вернуть их в экосистему Python.

Официальное руководство по разработке содержит много ресурсов для новичков. Вы уже сделали первый шаг, чтобы понять исходный текст, зная, как изменять, компилировать и тестировать приложения CPython.

Вспомните все, что вы узнали о CPython в этой статье. Все кусочки магии, к которым вы узнали секреты. Путешествие не заканчивается на этом месте.

Возможно, сейчас самое время узнать еще больше о Python и C. Кто знает: вы можете вносить всё больший вклад в проект CPython!