После полутора лет разработки представлен значительный релиз языка программирования Python 3.7. Корректирующие обновления для ветки Python 3.7 планируется выпускать в течение 18 месяцев. Критические уязвимости будут исправляться 5 лет до июня 2023 года. Примерно через месяц планируется сформировать первый корректирующий релиз Python 3.7.1.

Среди добавленных новшеств:

  • Реализован новый формат файлов “.pyc”, в которых кэшируется байткод. Ранее факт изменения исходных текстов, указывающий на необходимость обновления кэша, определялся путём простого сравнения времени модификации и размера файлов. В новой версии для выявления изменений в коде в заголовочной секции файлов “.pyc” теперь может сохраняться хэш от кода, на основе которого был создан кэш, что позволяет избавиться от конфузов при переименовании старых версий исходного файла. Кроме того, проверка по времени модификации мешала реализации механизма повторяемых сборок. Для обеспечения совместимости и снижения накладных расходов по умолчанию в pyc по-прежнему сохраняется время модификации, а хэши можно сохранить при помощи утилит py_compile или compileall. Хэши могут генерироваться в двух вариантах – checked и unchecked, в первом случае проверка осуществляется при каждой загрузке файла, а во втором для оптимизации производительности проверка на лету не производится;
  • Предложен новый C API для TLS (Thread-Local Storage), который предоставляет новый TSS (Thread Specific Storage) API вместо ранее предоставляемого интерпретатором
    TLS API, использующего тип int для представления ключей TLS на всех платформах. Новый TSS API вводит в обиход отдельный тип Py_tss_t, определение которого зависит от конкретных реализаций Thread-Local Storage, что позволяет собирать CPython на платформах, в которых ключи TLS не могут быть безопасно транслированы в int;

  • Добавлена новая встроенная функция breakpoint(), позволяющая программно инициировать срабатывание точки останова для перехода в отладчик. Вызываемый отладчик определяется через переменную окружения PYTHONBREAKPOINT (если установить в 0, вызов отладчика пропускается);
  • Добавлен новый модуль dataclass и связанный с ним декоратор dataclass(), предоставляющий средства для определения классов данных, в которых для описания атрибутов применяются аннотации переменных класса с автоматической генерацией методов __repr__(), __eq__() и __hash__(). Например:

    @dataclass
    class Point:
    x: float
    y: float
    z: float = 0.0

    p = Point(1.5, 2.5)
    print(p) # produces “Point(x=1.5, y=2.5, z=0.0)”

  • В основной состав добавлена поддержка модуля “typing” и обобщённых типов (generic). В реализацию модуля typing внесены изменения, которые позволили до 7 раз ускорить операции с типами;
  • Реализованы средства для кастомизации доступа к атрибутам модуля. Разработчик теперь может определить обработчик __getattr__() в модулях, который будет вызываться в случае отсутствия запрошенного атрибута;
  • Добавлена техника отложенной обработки аннотаций с информацией о типах, при которой вместо компиляции кода с выполнением выражений в аннотациях в момент их определения, компилятор сохраняет аннотации в виде строк в дереве AST и обрабатывает их по мере необходимости в процессе выполнения приложения. Подобный подход сокращает время запуска и даёт возможность использования в аннотациях ссылок на ещё не определённые конструкции (ранее допускалось только упоминание имён уже определённых на текущий момент разбора). Так как изменение нарушает совместимость для активации нового поведения требуется использовать флаг __future__ для каждого модуля, например “from __future__ import annotations”. В Python 4.0 новое поведение будет применено по умолчанию;
  • В модуле “time” реализован новый набор функций, оперирующих временем с наносекундной точностью: time.clock_gettime_ns(),
    time.clock_settime_ns(),
    time.monotonic_ns(),
    time.perf_counter_ns(),
    time.process_time_ns() и time.time_ns(). По формату вызова новые функции ничем не отличаются от вариантов без окончания “_ns”;

  • Предупреждения DeprecationWarning теперь
    отображаются для кода в основном модуле (__main__) и при выполнении тестов, но по умолчанию скрываются для всех импортированных модулей и библиотек (ранее предупреждения показывались только в тестах, для сохранения старого поведения следует использовать PendingDeprecationWarning, а для охвата импортированных модулей – FutureWarning);

  • Добавлен новый модуль contextvars и набор новых вызовов в C API с реализацией контекстно-зависимых переменных (Context Variables). Концептуально контекстно-зависимые переменные похожи на TLS-переменные, но в отличие от TLS они корректно могут применяться в асинхронном коде. Модули asyncio и decimal обновлены для обеспечения поддержки контекстно-зависимых переменных;
  • Добавлен новый модуль importlib.resources, предоставляющий API для обращения к ресурсам внутри пакетов;
  • По возможности исключено использование по умолчанию кодировок ASCII: По умолчанию теперь автоматически применяется локаль UTF-8, вместо ранее применяемой по умолчанию локали “C” (ASCII). Добавлена опция командной строки “-X utf8” и переменная окружения PYTHONUTF8, включающие принудительное использование UTF-8, независимо от настроен локали;
  • В классы str, bytes и bytearray добавлен метод isascii() для проверки строки на наличие только ASCII-символов;
  • Добавлен новый режим разработчика, активируемый при указании опции командной строки “-X dev” или установке переменной окружения PYTHONDEVMODE. После включения режима в CPython выполняются дополнительные проверки, которые нецелесообразно выполнять по умолчанию из-за высоких накладных расходов. Например, включается режим вывода предупреждений “-W default”, устанавливаются отладочные обработчики в функции распределения памяти, включается модуль faulthandler, активируется отладочный режим в asyncio и устанавливается атрибут dev_mode в sys.flags;
  • Добавлены опция командной строки “-X importtime” и переменная окружения PYTHONPROFILEIMPORTTIME для отображения времени импорта каждого модуля;
  • В спецификации стандартизировано сохранение порядка следования записей объектов dict;
  • Async и await переведены в категорию зарезервированных ключевых слов;
  • Обеспечена возможность передачи в функции более 255 аргументов;
  • В различные подсистемы внесены оптимизации производительности. Особенно большой прирост производительности отмечается в модуле asyncio.