Что нового в Python 3.10

Редактор:

Пабло Галиндо Сальгадо

В этой статье рассказывается о новых возможностях Python 3.10 по сравнению с 3.9. Python 3.10 был выпущен 4 октября 2021 года. Более подробную информацию можно найти в changelog.

Резюме - Основные моменты выпуска

Новые возможности синтаксиса:

  • PEP 634, Структурное сопоставление шаблонов: спецификация

  • PEP 635, Структурное сопоставление паттернов: мотивация и обоснование

  • PEP 636, Структурное сопоставление образов: учебное пособие

  • bpo-12782, Контекстные менеджеры с парентезой теперь официально разрешены.

Новые возможности в стандартной библиотеке:

  • PEP 618, Добавить необязательную проверку длины в zip.

Улучшения в работе переводчика:

  • PEP 626, Точные номера строк для отладки и других инструментов.

Новые возможности набора текста:

  • PEP 604, Разрешить записывать типы союзов как X | Y

  • PEP 612, Переменные спецификации параметров

  • PEP 613, Явные псевдонимы типов

  • PEP 647, Охранники пользовательского типа

Важные устаревания, удаления или ограничения:

  • PEP 644, требуется OpenSSL 1.1.1 или новее

  • PEP 632, Утратить модуль distutils.

  • PEP 623, Устаревает и готовится к удалению члена wstr в PyUnicodeObject.

  • PEP 624, Удалить API кодировщика Py_UNICODE

  • PEP 597, Добавить опцию EncodingWarning

Новые возможности

Парентезные контекстные менеджеры

Теперь поддерживается использование заключительных скобок для продолжения нескольких строк в контекстных менеджерах. Это позволяет форматировать длинную коллекцию контекстных менеджеров в несколько строк аналогично тому, как это было возможно ранее с операторами импорта. Например, все эти примеры теперь корректны:

with (CtxManager() as example):
    ...

with (
    CtxManager1(),
    CtxManager2()
):
    ...

with (CtxManager1() as example,
      CtxManager2()):
    ...

with (CtxManager1(),
      CtxManager2() as example):
    ...

with (
    CtxManager1() as example1,
    CtxManager2() as example2
):
    ...

также можно использовать запятую в конце вложенной группы:

with (
    CtxManager1() as example1,
    CtxManager2() as example2,
    CtxManager3() as example3,
):
    ...

Этот новый синтаксис использует не LL(1) возможности нового парсера. Более подробную информацию можно найти в PEP 617.

(При участии Гвидо ван Россума, Пабло Галиндо и Лисандроса Николау в bpo-12782 и bpo-40334).

Улучшенные сообщения об ошибках

Синтаксические ошибки

При разборе кода, содержащего незакрытые круглые скобки или скобки, интерпретатор теперь указывает местоположение незакрытой скобки или скобок вместо того, чтобы выводить SyntaxError: unexpected EOF while parsing или указывать на какое-то неправильное место. Например, рассмотрим следующий код (обратите внимание на незакрытые „{„):

expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
            38: 4, 39: 4, 45: 5, 46: 5, 47: 5, 48: 5, 49: 5, 54: 6,
some_other_code = foo()

В предыдущих версиях интерпретатора в качестве места синтаксической ошибки указывались запутанные места:

File "example.py", line 3
    some_other_code = foo()
                    ^
SyntaxError: invalid syntax

но в Python 3.10 выдается более информативная ошибка:

File "example.py", line 1
    expected = {9: 1, 18: 2, 19: 2, 27: 3, 28: 3, 29: 3, 36: 4, 37: 4,
               ^
SyntaxError: '{' was never closed

Аналогичным образом ошибки, связанные с незамкнутыми строковыми литералами (с одинарными и тройными кавычками), теперь указывают на начало строки вместо сообщения EOF/EOL.

Эти улучшения вдохновлены предыдущей работой над интерпретатором PyPy.

(При участии Пабло Галиндо в bpo-42864 и Батухана Таская в bpo-40176).

SyntaxError исключения, вызванные интерпретатором, теперь будут выделять весь диапазон ошибок в выражении, составляющем саму синтаксическую ошибку, а не только место обнаружения проблемы. Таким образом, вместо отображения (до Python 3.10):

>>> foo(x, z for z in range(10), t, w)
  File "<stdin>", line 1
    foo(x, z for z in range(10), t, w)
           ^
SyntaxError: Generator expression must be parenthesized

теперь Python 3.10 отобразит исключение в виде:

>>> foo(x, z for z in range(10), t, w)
  File "<stdin>", line 1
    foo(x, z for z in range(10), t, w)
           ^^^^^^^^^^^^^^^^^^^^
SyntaxError: Generator expression must be parenthesized

Это улучшение было внесено Пабло Галиндо в bpo-43914.

Было включено большое количество новых специализированных сообщений для исключений SyntaxError. Наиболее заметные из них следующие:

  • Отсутствие : перед блоками:

    >>> if rocket.position > event_horizon
      File "<stdin>", line 1
        if rocket.position > event_horizon
                                          ^
    SyntaxError: expected ':'
    

    (Предоставлено Пабло Галиндо в bpo-42997).

  • Непарные кортежи в целях понимания:

    >>> {x,y for x,y in zip('abcd', '1234')}
      File "<stdin>", line 1
        {x,y for x,y in zip('abcd', '1234')}
         ^
    SyntaxError: did you forget parentheses around the comprehension target?
    

    (Предоставлено Пабло Галиндо в bpo-43017).

  • Отсутствие запятых в литералах коллекции и между выражениями:

    >>> items = {
    ... x: 1,
    ... y: 2
    ... z: 3,
      File "<stdin>", line 3
        y: 2
           ^
    SyntaxError: invalid syntax. Perhaps you forgot a comma?
    

    (Предоставлено Пабло Галиндо в bpo-43822).

  • Несколько типов исключений без скобок:

    >>> try:
    ...     build_dyson_sphere()
    ... except NotEnoughScienceError, NotEnoughResourcesError:
      File "<stdin>", line 3
        except NotEnoughScienceError, NotEnoughResourcesError:
               ^
    SyntaxError: multiple exception types must be parenthesized
    

    (Предоставлено Пабло Галиндо в bpo-43149).

  • Отсутствие : и значений в словарных литералах:

    >>> values = {
    ... x: 1,
    ... y: 2,
    ... z:
    ... }
      File "<stdin>", line 4
        z:
         ^
    SyntaxError: expression expected after dictionary key and ':'
    
    >>> values = {x:1, y:2, z w:3}
      File "<stdin>", line 1
        values = {x:1, y:2, z w:3}
                            ^
    SyntaxError: ':' expected after dictionary key
    

    (Предоставлено Пабло Галиндо в bpo-43823).

  • try блоков без except или finally блоков:

    >>> try:
    ...     x = 2
    ... something = 3
      File "<stdin>", line 3
        something  = 3
        ^^^^^^^^^
    SyntaxError: expected 'except' or 'finally' block
    

    (Предоставлено Пабло Галиндо в bpo-44305).

  • Использование = вместо == в сравнениях:

    >>> if rocket.position = event_horizon:
      File "<stdin>", line 1
        if rocket.position = event_horizon:
                           ^
    SyntaxError: cannot assign to attribute here. Maybe you meant '==' instead of '='?
    

    (Предоставлено Пабло Галиндо в bpo-43797).

  • Использование * в f-строках:

    >>> f"Black holes {*all_black_holes} and revelations"
      File "<stdin>", line 1
        (*all_black_holes)
         ^
    SyntaxError: f-string: cannot use starred expression here
    

    (Предоставлено Пабло Галиндо в bpo-41064).

IndentationErrors

Многие исключения IndentationError теперь имеют больше контекста относительно того, какой блок ожидал отступа, включая местоположение утверждения:

>>> def foo():
...    if lel:
...    x = 2
  File "<stdin>", line 3
    x = 2
    ^
IndentationError: expected an indented block after 'if' statement in line 2

Ошибки атрибутов

При печати AttributeError, PyErr_Display() будут предложены похожие имена атрибутов в объекте, из которого было вызвано исключение:

>>> collections.namedtoplo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'collections' has no attribute 'namedtoplo'. Did you mean: namedtuple?

(Предоставлено Пабло Галиндо в bpo-38530).

Предупреждение

Обратите внимание, что это не сработает, если PyErr_Display() не вызывается для отображения ошибки, что может произойти, если используется какая-то другая пользовательская функция отображения ошибок. Это распространенный сценарий в некоторых REPL, таких как IPython.

NameErrors

При печати NameError, вызванной интерпретатором, PyErr_Display() предложит предложения по схожим именам переменных в функции, из которой было вызвано исключение:

>>> schwarzschild_black_hole = None
>>> schwarschild_black_hole
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'schwarschild_black_hole' is not defined. Did you mean: schwarzschild_black_hole?

(Предоставлено Пабло Галиндо в bpo-38530).

Предупреждение

Обратите внимание, что это не сработает, если PyErr_Display() не вызывается для отображения ошибки, что может произойти, если используется какая-то другая пользовательская функция отображения ошибок. Это распространенный сценарий в некоторых REPL, таких как IPython.

PEP 626: Точные номера строк для отладки и других инструментов

PEP 626 обеспечивает более точные и надежные номера строк для инструментов отладки, профилирования и покрытия. События трассировки с правильным номером строки генерируются для всех выполняемых строк кода и только для выполняемых строк кода.

Атрибут f_lineno объектов кадра всегда будет содержать ожидаемый номер строки.

Атрибут co_lnotab в методе code objects устарел и будет удален в версии 3.12. Код, которому нужно преобразовать смещение в номер строки, должен использовать новый метод co_lines().

PEP 634: Структурное сопоставление паттернов

Структурное сопоставление шаблонов было добавлено в виде оператора match и оператора case шаблонов с соответствующими действиями. Паттерны состоят из последовательностей, отображений, примитивных типов данных, а также экземпляров классов. Сопоставление шаблонов позволяет программам извлекать информацию из сложных типов данных, разветвляться по структуре данных и применять определенные действия на основе различных форм данных.

Синтаксис и операции

Общий синтаксис сопоставления образцов таков:

match subject:
    case <pattern_1>:
        <action_1>
    case <pattern_2>:
        <action_2>
    case <pattern_3>:
        <action_3>
    case _:
        <action_wildcard>

Оператор match принимает выражение и сравнивает его значение с последовательными шаблонами, заданными в виде одного или нескольких блоков case. В частности, сопоставление шаблонов работает следующим образом:

  1. использование данных с типом и формой (subject)

  2. вычисление subject в выражении match

  3. сравнение предмета с каждым шаблоном в операторе case сверху вниз до тех пор, пока не будет подтверждено совпадение.

  4. выполнение действия, связанного с шаблоном подтвержденного совпадения

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

Декларативный подход

Читатели могут знать о сопоставлении образцов на простом примере сопоставления субъекта (объекта данных) с литералом (образцом) с помощью оператора switch, встречающегося в C, Java или JavaScript (и многих других языках). Часто оператор switch используется для сравнения объекта/выражения с операторами case, содержащими литералы.

Более мощные примеры сопоставления образцов можно найти в таких языках, как Scala и Elixir. При структурном сопоставлении шаблонов подход является «декларативным» и явно указывает условия (шаблоны), которым должны соответствовать данные.

Хотя «императивная» серия инструкций с использованием вложенных операторов «if» может быть использована для достижения чего-то похожего на структурное сопоставление образцов, она менее понятна, чем «декларативный» подход. Вместо этого в «декларативном» подходе указываются условия, которые необходимо выполнить для совпадения, и он более удобен для чтения благодаря явным шаблонам. Хотя структурное сопоставление образцов можно использовать в его простейшей форме, сравнивая переменную с литералом в операторе case, его истинная ценность для Python заключается в обработке типа и формы объекта.

Простой шаблон: совпадение с литералом

Давайте рассмотрим этот пример как сопоставление шаблонов в его простейшей форме: значение, субъект, сопоставляется с несколькими литералами, шаблонами. В приведенном ниже примере status - это субъект оператора соответствия. Шаблонами являются все операторы case, где литералы представляют собой коды состояния запроса. После совпадения выполняется действие, соответствующее случаю:

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"
        case _:
            return "Something's wrong with the internet"

Если вышеприведенной функции передать status, равное 418, то будет возвращено «Я чайник». Если вышеприведенной функции передать status, равное 500, то оператор case с _ будет соответствовать подстановочному символу, и вернется «Что-то не так с интернетом». Обратите внимание на последний блок: имя переменной, _, действует как волшебный знак и гарантирует, что тема всегда будет совпадать. Использование _ необязательно.

Вы можете объединить несколько литералов в одном шаблоне с помощью | («или»):

case 401 | 403 | 404:
    return "Not allowed"
Поведение без подстановочного знака

Если мы изменим приведенный выше пример, удалив последний блок case, пример станет таким:

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"

Без использования _ в операторе case, совпадение может не существовать. Если совпадения нет, то поведение является безотказным. Например, если передается status из 500, то происходит отказ.

Паттерны с литералом и переменной

Паттерны могут выглядеть как задания на распаковку, и паттерн может использоваться для связывания переменных. В этом примере точка данных может быть распакована в ее координату x и координату y:

# point is an (x, y) tuple
match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        raise ValueError("Not a point")

Первый шаблон состоит из двух литералов, (0, 0), и его можно рассматривать как расширение шаблона литералов, показанного выше. Следующие два шаблона объединяют литерал и переменную, причем переменная связывает значение из субъекта (point). Четвертый паттерн фиксирует два значения, что делает его концептуально похожим на задание распаковки (x, y) = point.

Узоры и классы

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

class Point:
    x: int
    y: int

def location(point):
    match point:
        case Point(x=0, y=0):
            print("Origin is the point's location.")
        case Point(x=0, y=y):
            print(f"Y={y} and the point is on the y-axis.")
        case Point(x=x, y=0):
            print(f"X={x} and the point is on the x-axis.")
        case Point():
            print("The point is located somewhere else on the plane.")
        case _:
            print("Not a point")
Узоры с позиционными параметрами

Вы можете использовать позиционные параметры с некоторыми встроенными классами, которые обеспечивают упорядочивание своих атрибутов (например, классы данных). Вы также можете задать определенную позицию для атрибутов в шаблонах, установив специальный атрибут __match_args__ в ваших классах. Если он установлен в («x», «y»), то все следующие шаблоны эквивалентны (и все связывают атрибут y с переменной var):

Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)

Вложенные узоры

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

match points:
    case []:
        print("No points in the list.")
    case [Point(0, 0)]:
        print("The origin is the only point in the list.")
    case [Point(x, y)]:
        print(f"A single point {x}, {y} is in the list.")
    case [Point(0, y1), Point(0, y2)]:
        print(f"Two points on the Y axis at {y1}, {y2} are in the list.")
    case _:
        print("Something else is found in the list.")

Сложные шаблоны и подстановочный знак

До сих пор в примерах использовался только _ в последнем выражении case. Подстановочный знак можно использовать в более сложных шаблонах, например ('error', code, _). Например:

match test_variable:
    case ('warning', code, 40):
        print("A warning has been received.")
    case ('error', code, _):
        print(f"An error {code} occurred.")

В приведенном выше случае test_variable будет соответствовать („error“, code, 100) и („error“, code, 800).

Охранник

Мы можем добавить к шаблону предложение if, известное как «охрана». Если охранник ложен, match переходит к попытке выполнения следующего блока case. Обратите внимание, что перехват значения происходит до того, как будет оценена защита:

match point:
    case Point(x, y) if x == y:
        print(f"The point is located on the diagonal Y=X at {x}.")
    case Point(x, y):
        print(f"Point is not on the diagonal.")

Другие ключевые особенности

Еще несколько ключевых особенностей:

  • Как и задания на распаковку, шаблоны tuple и list имеют точно такое же значение и фактически соответствуют произвольным последовательностям. Технически, субъект должен быть последовательностью. Поэтому важным исключением является то, что шаблоны не соответствуют итераторам. Также, во избежание распространенной ошибки, шаблоны последовательностей не соответствуют строкам.

  • Шаблоны последовательностей поддерживают подстановочные знаки: [x, y, *rest] и (x, y, *rest) работают аналогично подстановочным знакам в заданиях распаковки. Имя после * также может быть _, поэтому (x, y, *_) соответствует последовательности как минимум из двух элементов, не связывая остальные элементы.

  • Шаблоны отображения: {"bandwidth": b, "latency": l} захватывает значения "bandwidth" и "latency" из dict. В отличие от шаблонов последовательности, дополнительные ключи игнорируются. Также поддерживается подстановочный знак **rest. (Но **_ будет избыточным, поэтому не допускается).

  • Подшаблоны могут быть захвачены с помощью ключевого слова as:

    case (Point(x1, y1), Point(x2, y2) as p2): ...
    

    Это связывает x1, y1, x2, y2, как и следовало ожидать, без клаузулы as, а p2 - со всем вторым элементом темы.

  • Большинство литералов сравниваются по равенству. Однако синглтоны True, False и None сравниваются по тождеству.

  • Именованные константы могут использоваться в шаблонах. Эти именованные константы должны быть именами с точкой, чтобы константа не интерпретировалась как переменная захвата:

    from enum import Enum
    class Color(Enum):
        RED = 0
        GREEN = 1
        BLUE = 2
    
    color = Color.GREEN
    match color:
        case Color.RED:
            print("I see red!")
        case Color.GREEN:
            print("Grass is green")
        case Color.BLUE:
            print("I'm feeling the blues :(")
    

Полная спецификация приведена в PEP 634. Мотивация и обоснование приведены в PEP 635, а более подробное руководство - в PEP 636.

Необязательные опции EncodingWarning и encoding="locale"

Кодировка по умолчанию TextIOWrapper и open() зависит от платформы и локали. Поскольку на большинстве Unix-платформ используется UTF-8, отсутствие опции encoding при открытии UTF-8 файлов (например, JSON, YAML, TOML, Markdown) является очень распространенной ошибкой. Например:

# BUG: "rb" mode or encoding="utf-8" should be used.
with open("data.json") as f:
    data = json.load(f)

Чтобы найти этот тип ошибки, добавляется необязательный EncodingWarning. Он выдается, когда sys.flags.warn_default_encoding равен true и используется локальная кодировка по умолчанию.

Для включения предупреждения добавлены опции -X warn_default_encoding и PYTHONWARNDEFAULTENCODING.

Дополнительные сведения см. в разделе Кодирование текста.

Другие языковые изменения

  • В типе int появился новый метод int.bit_count(), возвращающий количество единиц в двоичном разложении данного целого числа, также известный как счетчик населенности. (Внесено Никласом Фиекасом в bpo-29882).

  • Представления, возвращаемые dict.keys(), dict.values() и dict.items(), теперь имеют атрибут mapping, который дает объект types.MappingProxyType, оборачивающий исходный словарь. (Внесено Деннисом Суини в bpo-40890).

  • PEP 618: Функция zip() теперь имеет необязательный флаг strict, используемый для требования, чтобы все итерабели имели одинаковую длину.

  • Встроенные и расширенные функции, принимающие целочисленные аргументы, больше не принимают Decimals, Fractions и другие объекты, которые могут быть преобразованы в целые числа только с потерей (например, имеющие метод __int__(), но не имеющие метода __index__()). (Внесено Сергеем Сторчакой в bpo-37999).

  • Если object.__ipow__() возвращает NotImplemented, оператор корректно вернется к object.__pow__() и object.__rpow__(), как и ожидалось. (Внесено Алексом Шкопом в bpo-38302).

  • Выражения присваивания теперь можно использовать в литералах множеств и осмыслениях множеств, а также в индексах последовательностей (но не в срезах).

  • У функций появился новый атрибут __builtins__, который используется для поиска встроенных символов при выполнении функции, вместо того чтобы искать их в __globals__['__builtins__']. Атрибут инициализируется из __globals__["__builtins__"], если он существует, иначе из текущих встроенных символов. (Внесено Марком Шенноном в bpo-42990).

  • Добавлены две новые встроенные функции - aiter() и anext(), обеспечивающие асинхронные аналоги iter() и next(), соответственно. (Вклад Джошуа Бронсона, Дэниела Поупа и Джастина Ванга в bpo-31861).

  • Статические методы (@staticmethod) и методы классов (@classmethod) теперь наследуют атрибуты методов (__module__, __name__, __qualname__, __doc__, __annotations__) и имеют новый атрибут __wrapped__. Кроме того, статические методы теперь можно вызывать как обычные функции. (Внесено Виктором Стиннером в bpo-43682).

  • Аннотации для сложных целей (все, кроме целей simple name, определенных PEP 526) больше не вызывают никаких эффектов во время выполнения from __future__ import annotations. (Внесено Батуханом Таская в bpo-42737).

  • Объекты классов и модулей теперь лениво создают пустые списки аннотаций по требованию. Для обеспечения обратной совместимости пакеты аннотаций хранятся в __dict__ объекта. Это улучшает лучшие практики работы с __annotations__; для получения дополнительной информации смотрите Лучшие практики использования аннотаций. (Внесено Ларри Гастингсом в bpo-43901).

  • Аннотации, состоящие из yield, yield from, await или именованных выражений, теперь запрещены в from __future__ import annotations из-за их побочных эффектов. (Внесено Батуханом Таская в bpo-42725).

  • Использование несвязанных переменных, super() и других выражений, которые могут изменить обработку таблицы символов в качестве аннотаций, теперь не имеет силы в from __future__ import annotations. (Внесено Батуханом Таская в bpo-42725).

  • Хеширование NaN-значений как типа float, так и типа decimal.Decimal теперь зависит от идентичности объекта. Раньше они всегда хешировались в 0, даже если NaN-значения не равны друг другу. Это приводило к потенциально квадратичному поведению во время выполнения из-за чрезмерных хэш-коллизий при создании словарей и наборов, содержащих несколько NaN. (Внесено Раймондом Хеттингером в bpo-43475).

  • При удалении константы __debug__ будет выдаваться сообщение SyntaxError (вместо NameError). (Внесено Донгхи На в bpo-45000).

  • Исключения SyntaxError теперь имеют атрибуты end_lineno и end_offset. Они будут None, если не определены. (Внесено Пабло Галиндо в bpo-43914).

Новые модули

  • Нет.

Улучшенные модули

asyncio

Добавьте недостающий метод connect_accepted_socket(). (Внесено Алексом Грёнхольмом в bpo-41332).

argparse

Ошибочная фраза «необязательные аргументы» была заменена на «опции» в справке argparse. Некоторые тесты могут потребовать адаптации, если они полагаются на точное совпадение вывода. (Внесено Раймондом Хеттингером в bpo-9694).

массив

Метод index() из array.array теперь имеет необязательные параметры start и stop. (Внесено Андерсом Лоренценом и Закери Спитцем в bpo-31956).

asynchat, asyncore, smtpd

Эти модули были помечены как устаревшие в документации к модулю начиная с Python 3.6. Теперь для всех трех этих модулей добавлено время импорта DeprecationWarning.

base64

Добавьте base64.b32hexencode() и base64.b32hexdecode() для поддержки кодировки Base32 с расширенным шестнадцатеричным алфавитом.

bdb

Добавьте clearBreakpoints(), чтобы сбросить все установленные точки останова. (Внесено Ирит Катриэль в bpo-24160).

биссектриса

Добавлена возможность предоставления ключевой функции для API в модуле bisect. (Внесено Раймондом Хеттингером в bpo-4356).

кодеки

Добавьте функцию codecs.unregister() для снятия с регистрации функции поиска кодеков. (Внесено Хай Ши в bpo-41842).

коллекции.abc

__args__ из parameterized generic для collections.abc.Callable теперь соответствует typing.Callable. collections.abc.Callable generic теперь сглаживает параметры типа, аналогично тому, как это делает typing.Callable в настоящее время. Это означает, что collections.abc.Callable[[int, str], str] будет иметь __args__ из (int, str, str); ранее это был ([int, str], str). Чтобы разрешить это изменение, types.GenericAlias теперь может быть подклассом, и подкласс будет возвращаться при подписке на тип collections.abc.Callable. Обратите внимание, что при недопустимых формах параметризации collections.abc.Callable, которые в Python 3.9 могли проходить молча, может возникнуть ошибка TypeError. (Внесено Кеном Джином в bpo-42195).

contextlib

Добавьте менеджер контекста contextlib.aclosing() для безопасного закрытия асинхронных генераторов и объектов, представляющих асинхронно освобождаемые ресурсы. (Внесено Джунги Кимом и Джоном Белмонте в bpo-41229).

Добавьте поддержку асинхронного менеджера контекста в contextlib.nullcontext(). (Внесено Томом Грингаузом в bpo-41543).

Добавьте AsyncContextDecorator для поддержки использования асинхронных менеджеров контекста в качестве декораторов.

проклятия

Расширенные функции цвета, добавленные в ncurses 6.1, будут прозрачно использоваться функциями curses.color_content(), curses.init_color(), curses.init_pair() и curses.pair_content(). Новая функция, curses.has_extended_color_support(), указывает, обеспечивается ли поддержка расширенного цвета базовой библиотекой ncurses. (Вклад Джеффри Кинчера и Ханса Петтера Янссона в bpo-36982).

Константы BUTTON5_* теперь открываются в модуле curses, если они предоставляются базовой библиотекой curses. (Внесено Закери Спитцем в bpo-39273).

классы данных

__слоты__

Добавлен параметр slots в декораторе dataclasses.dataclass(). (Внесено Юрием Карабасом в bpo-42269)

Поля только для ключевых слов

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

Можно сказать, что каждое поле содержит только ключевые слова:

from dataclasses import dataclass

@dataclass(kw_only=True)
class Birthday:
    name: str
    birthday: datetime.date

И name, и birthday являются параметрами только ключевого слова для сгенерированного метода __init__.

Вы можете указать только ключевые слова для каждого поля:

from dataclasses import dataclass, field

@dataclass
class Birthday:
    name: str
    birthday: datetime.date = field(kw_only=True)

Здесь только birthday относится к полям только с ключевыми словами. Если вы устанавливаете kw_only для отдельных полей, помните, что существуют правила переупорядочивания полей, согласно которым поля, содержащие только ключевые слова, должны следовать за полями, не содержащими только ключевые слова. Подробности см. в полной документации по классам данных.

Вы также можете указать, что все поля, следующие за маркером KW_ONLY, предназначены только для ключевых слов. Это, вероятно, наиболее распространенный вариант использования:

from dataclasses import dataclass, KW_ONLY

@dataclass
class Point:
    x: float
    y: float
    _: KW_ONLY
    z: float = 0.0
    t: float = 0.0

Здесь z и t являются параметрами только для ключевого слова, а x и y - нет. (Внесено Эриком В. Смитом в bpo-43532).

distutils

Весь пакет distutils является устаревшим и будет удален в Python 3.12. Его функциональность для указания сборок пакетов уже полностью заменена сторонними пакетами setuptools и packaging, а большинство других часто используемых API доступны в других частях стандартной библиотеки (например, platform, shutil, subprocess или sysconfig). Перенос других функций из distutils не планируется, и приложениям, использующим другие функции, следует планировать создание закрытых копий кода. Обсуждение см. в PEP 632.

Команда bdist_wininst, устаревшая в Python 3.8, была удалена. Теперь для распространения бинарных пакетов под Windows рекомендуется использовать команду bdist_wheel. (Внесено Виктором Стиннером в bpo-42802).

doctest

Если модуль не определяет __loader__, вернитесь к __spec__.loader. (Внесено Бреттом Кэнноном в bpo-42133).

кодировки

encodings.normalize_encoding() теперь игнорирует символы, отличные от ASCII. (Внесено Хай Ши в bpo-39337).

enum

Enum __repr__() теперь возвращает enum_name.member_name, а __str__() - member_name. Перечисления Stdlib, доступные как константы модуля, имеют значение repr() от module_name.member_name. (Внесено Итаном Фурманом в bpo-40066).

Добавьте enum.StrEnum для перечислений, все члены которых являются строками. (Внесено Итаном Фурманом в bpo-41816).

fileinput

Добавьте параметры encoding и errors в fileinput.input() и fileinput.FileInput. (Внесено Инадой Наоки в bpo-43712).

fileinput.hook_compressed() теперь возвращает объект TextIOWrapper, если mode равен «r» и файл сжат, как и несжатые файлы. (Внесено Инадой Наоки в bpo-5758).

faulthandler

Модуль faulthandler теперь определяет, произошла ли фатальная ошибка во время сборки сборщика мусора. (Внесено Виктором Стиннером в bpo-44466).

gc

Добавьте крючки аудита для gc.get_objects(), gc.get_referrers() и gc.get_referents(). (Внесено Пабло Галиндо в bpo-43439).

глобус

Добавьте параметры root_dir и dir_fd в glob() и iglob(), которые позволяют указать корневой каталог для поиска. (Внесено Сергеем Сторчакой в bpo-38144).

hashlib

Для работы модуля hashlib требуется OpenSSL 1.1.1 или более новая версия. (Внесено Кристианом Хаймсом в PEP 644 и bpo-43669).

Модуль hashlib имеет предварительную поддержку OpenSSL 3.0.0. (Внесено Кристианом Хаймсом в bpo-38820 и другие вопросы).

Обратный ход pbkdf2_hmac() в чистом Python устарел. В будущем PBKDF2-HMAC будет доступен только тогда, когда Python будет собран с поддержкой OpenSSL. (Внесено Кристианом Хаймсом в bpo-43880).

hmac

Модуль hmac теперь использует внутреннюю реализацию HMAC от OpenSSL. (Внесено Кристианом Хаймсом в bpo-40645).

IDLE и idlelib

Заставляет IDLE вызывать sys.excepthook() (при запуске без „-n“). Пользовательские крючки ранее игнорировались. (Внесено Кеном Хилтоном в bpo-43008).

Перестройте диалог настроек. Разделите вкладку Общие на вкладки Windows и Shell/Ed. Переместите источники справки, которые расширяют меню Справка, на вкладку Расширения. Освободите место для новых опций и сократите диалог. Благодаря последнему диалог лучше подходит для маленьких экранов. (Внесено Терри Джен Риди в bpo-40468.) Переместите настройку отступа с вкладки Font на новую вкладку Windows. (Вклад Марка Розмана и Терри Джен Риди в bpo-33962).

Вышеуказанные изменения были перенесены в релиз сопровождения 3.9.

Добавьте боковую панель Shell. Переместите основную подсказку („>>>“) на боковую панель. Добавьте вторичные подсказки (“…“) на боковую панель. Левый щелчок и дополнительное перетаскивание выделяют одну или несколько строк текста, как и в случае с боковой панелью номера строки редактора. Правый щелчок после выделения строк текста вызывает контекстное меню с пунктом «Копировать с подсказками». Это позволяет скопировать подсказки из боковой панели со строками выделенного текста. Эта опция также появляется в контекстном меню для текста. (Внесено Тал Эйнат в bpo-37903).

Используйте пробелы вместо табуляций для отступов интерактивного кода. Это позволяет интерактивным кодам «выглядеть правильно». Создание такой возможности было основной мотивацией для добавления боковой панели оболочки. (Внесено Терри Яном Риди в bpo-37892).

Выделите новые soft keywords match, case и _ в операторах сопоставления с образцом. Однако это выделение не идеально и в некоторых редких случаях будет некорректным, включая некоторые _-ы в шаблонах case. (Внесено Талем Эйнатом в bpo-44010).

Новое в обновлении 3.10.

Применяйте подсветку синтаксиса к файлам .pyi. (Внесено Алексом Уэйгудом и Терри Джен Риди в bpo-45447).

Включение подсказок при сохранении Shell с входами и выходами. (Внесено Терри Яном Риди в gh-95191).

importlib.metadata

Паритет характеристик с importlib_metadata 4.6 (history).

importlib.metadata entry points теперь предоставляет более приятные возможности для выбора точек входа по группе и имени с помощью нового класса importlib.metadata.EntryPoints. Более подробную информацию об устаревании и использовании см. в примечании о совместимости в документации.

Добавлены importlib.metadata.packages_distributions() для разрешения модулей и пакетов Python верхнего уровня к их importlib.metadata.Distribution.

осмотреть

Если модуль не определяет __loader__, вернитесь к __spec__.loader. (Внесено Бреттом Кэнноном в bpo-42133).

Добавьте inspect.get_annotations(), который безопасно вычисляет аннотации, определенные для объекта. Она обходит причуды доступа к аннотациям для различных типов объектов и делает очень мало предположений об объекте, который исследует. inspect.get_annotations() также может корректно разгруппировать строковые аннотации. В настоящее время inspect.get_annotations() считается лучшей практикой для доступа к дикту аннотаций, определенному для любого объекта Python; более подробную информацию о лучших практиках работы с аннотациями можно найти в Лучшие практики использования аннотаций. Кроме того, inspect.signature(), inspect.Signature.from_callable() и inspect.Signature.from_function() теперь вызывают inspect.get_annotations() для получения аннотаций. Это означает, что inspect.signature() и inspect.Signature.from_callable() теперь также могут удалять строковые аннотации. (Внесено Ларри Гастингсом в bpo-43817).

itertools

Добавьте itertools.pairwise(). (Внесено Раймондом Хеттингером в bpo-38200).

linecache

Если модуль не определяет __loader__, вернитесь к __spec__.loader. (Внесено Бреттом Кэнноном в bpo-42133).

os

Добавьте поддержку os.cpu_count() для VxWorks RTOS. (Внесено Peixing Xin в bpo-41440).

Добавьте новую функцию os.eventfd() и связанные с ней помощники для обертывания системного вызова eventfd2 в Linux. (Внесено Кристианом Хаймсом в bpo-41001).

Добавьте os.splice(), позволяющий перемещать данные между двумя файловыми дескрипторами без копирования между адресным пространством ядра и адресным пространством пользователя, где один из файловых дескрипторов должен ссылаться на трубу. (Внесено Пабло Галиндо в bpo-41625).

Добавьте O_EVTONLY, O_FSYNC, O_SYMLINK и O_NOFOLLOW_ANY для macOS. (Внесено Донгхи На в bpo-43106).

os.path

os.path.realpath() теперь принимает строгий аргумент, состоящий только из ключевых слов. Если установить значение True, то при отсутствии пути или возникновении цикла симлинка будет вызвана ошибка OSError. (Внесено Барни Гейлом в bpo-43757).

pathlib

Добавьте поддержку срезов в PurePath.parents. (Внесено Джошуа Кэнноном в bpo-35498).

Добавьте поддержку отрицательных индексов в PurePath.parents. (Внесено Ярославом Панковичем в bpo-21041).

Добавьте метод Path.hardlink_to, который заменяет link_to(). Новый метод имеет тот же порядок аргументов, что и symlink_to(). (Внесено Барни Гейлом в bpo-39950).

pathlib.Path.stat() и chmod() теперь принимают аргумент follow_symlinks, состоящий только из ключевого слова, для согласованности с соответствующими функциями в модуле os. (Внесено Барни Гейлом в bpo-39906).

платформа

Добавьте platform.freedesktop_os_release() для получения идентификатора операционной системы из стандартного файла freedesktop.org os-release. (Внесено Кристианом Хаймсом в bpo-28468).

pprint

pprint.pprint() теперь принимает новый аргумент в виде ключевого слова underscore_numbers. (Внесено sblondon в bpo-42914).

pprint теперь может красиво печатать экземпляры dataclasses.dataclass. (Внесено Льюисом Галлом в bpo-43080).

py_compile

Добавьте опцию --quiet в интерфейс командной строки py_compile. (Внесено Григорием Шевченко в bpo-38731).

pyclbr

Добавьте атрибут end_lineno к объектам Function и Class в дереве, возвращаемом pyclbr.readmodule() и pyclbr.readmodule_ex(). Он соответствует существующему (начальному) lineno. (Внесено Авиралом Сриваставой в bpo-38307).

полка

Модуль shelve теперь использует pickle.DEFAULT_PROTOCOL по умолчанию вместо протокола pickle 3 при создании полок. (Внесено Закери Спитцем в bpo-34204).

статистика

Добавьте функции covariance(), correlation() Пирсона и простые linear_regression(). (Внесено Тимотеушем Влодзько в bpo-38490).

сайт

Если модуль не определяет __loader__, вернитесь к __spec__.loader. (Внесено Бреттом Кэнноном в bpo-42133).

сокет

Исключение socket.timeout теперь является псевдонимом TimeoutError. (Внесено Кристианом Хаймсом в bpo-42413).

Добавьте возможность создавать MPTCP-сокеты с помощью IPPROTO_MPTCP (Внесено Rui Cunha в bpo-43571).

Добавьте опцию IP_RECVTOS для получения полей типа обслуживания (ToS) или DSCP/ECN (внесено Георгом Саутхоффом в bpo-44077).

ssl

Для работы модуля ssl требуется OpenSSL 1.1.1 или более новая версия. (Внесено Кристианом Хаймсом в PEP 644 и bpo-43669).

Модуль ssl имеет предварительную поддержку OpenSSL 3.0.0 и новую опцию OP_IGNORE_UNEXPECTED_EOF. (Внесено Кристианом Хаймсом в bpo-38820, bpo-43794, bpo-43788, bpo-43791, bpo-43799, bpo-43920, bpo-43789 и bpo-43811).

Устаревшая функция и использование устаревших констант теперь приводят к ошибке DeprecationWarning. В ssl.SSLContext.options по умолчанию установлены OP_NO_SSLv2 и OP_NO_SSLv3, поэтому он не может предупреждать о повторной установке флага. В deprecation section есть список устаревших функций. (Внесено Кристианом Хаймсом в bpo-43880).

Модуль ssl теперь имеет более безопасные настройки по умолчанию. По умолчанию отключены шифры без прямой секретности или SHA-1 MAC. Уровень безопасности 2 запрещает слабые ключи RSA, DH и ECC с защитой менее 112 бит. По умолчанию SSLContext устанавливает минимальную версию протокола TLS 1.2. Настройки основаны на исследованиях Хинека Шлавака. (Внесено Кристианом Хаймсом в bpo-43998).

Устаревшие протоколы SSL 3.0, TLS 1.0 и TLS 1.1 больше официально не поддерживаются. Python не блокирует их активно. Однако опции сборки OpenSSL, конфигурации дистрибутивов, патчи производителей и наборы шифров могут помешать успешному рукопожатию.

Добавьте параметр timeout в функцию ssl.get_server_certificate(). (Внесено Закери Спитцем в bpo-31870).

Модуль ssl использует heap-типы и многофазную инициализацию. (Внесено Кристианом Хаймсом в bpo-42333).

Добавлен новый флаг проверки VERIFY_X509_PARTIAL_CHAIN. (Внесен l0x в bpo-40849).

sqlite3

Добавьте события аудита для connect/handle(), enable_load_extension() и load_extension(). (Внесено Эрлендом Э. Аасланом в bpo-43762).

sys

Добавьте атрибут sys.orig_argv: список исходных аргументов командной строки, передаваемых исполняемому файлу Python. (Внесено Виктором Стиннером в bpo-23427).

Добавьте sys.stdlib_module_names, содержащий список имен модулей стандартной библиотеки. (Внесено Виктором Стиннером в bpo-42955).

_thread

_thread.interrupt_main() теперь принимает необязательный номер сигнала для имитации (по умолчанию по-прежнему signal.SIGINT). (Внесено Антуаном Питру в bpo-43356).

нарезка резьбы

Добавьте threading.gettrace() и threading.getprofile(), чтобы получить функции, заданные threading.settrace() и threading.setprofile() соответственно. (Внесено Марио Корчеро в bpo-42251).

Добавьте threading.__excepthook__, чтобы можно было восстановить исходное значение threading.excepthook() в случае, если оно установлено в нерабочее или другое значение. (Внесено Марио Корчеро в bpo-42308).

traceback

Функции format_exception(), format_exception_only() и print_exception() теперь могут принимать объект исключения в качестве аргумента только для позиции. (Вклад Закери Шпитца и Маттиаса Буссонье в bpo-26389).

типы

Вновь введите классы types.EllipsisType, types.NoneType и types.NotImplementedType, обеспечив новый набор типов, легко интерпретируемых программами проверки типов. (Внесено Басом ван Биком в bpo-41810).

набор текста

Основные изменения см. в разделе Новые возможности, связанные с подсказками типа.

Поведение typing.Literal было изменено, чтобы соответствовать PEP 586 и соответствовать поведению статических проверяющих типов, указанных в PEP.

  1. Literal теперь не дублирует параметры.

  2. Сравнения равенства между объектами Literal теперь не зависят от порядка.

  3. Сравнения Literal теперь учитывают типы. Например, Literal[0] == Literal[False] раньше оценивался в True. Теперь это False. Чтобы поддержать это изменение, внутренний кэш типов теперь поддерживает дифференцирование типов.

  4. Объекты Literal теперь будут вызывать исключение TypeError при сравнении равенств, если любой из их параметров не является hashable. Обратите внимание, что объявление Literal с нехешируемыми параметрами не приведет к ошибке:

    >>> from typing import Literal
    >>> Literal[{0}]
    >>> Literal[{0}] == Literal[{False}]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'set'
    

(Предоставлено Юрием Карабасом в bpo-42345).

Добавьте новую функцию typing.is_typeddict() для проверки того, является ли аннотация typing.TypedDict. (Внесено Патриком Ридером в bpo-41792).

Подклассы typing.Protocol, в которых объявлены только переменные данных, теперь будут вызывать ошибку TypeError при проверке с помощью isinstance, если они не оформлены с помощью runtime_checkable(). Ранее такие проверки проходили молча. Пользователям следует украсить свои подклассы декоратором runtime_checkable(), если им нужны протоколы времени выполнения. (Внесено Юрием Карабасом в bpo-38908).

При импорте из подмодулей typing.io и typing.re теперь будет выдаваться DeprecationWarning. Эти подмодули устарели с Python 3.8 и будут удалены в одной из следующих версий Python. Все, что относится к этим подмодулям, следует импортировать непосредственно из typing. (Внесено Себастьяном Риттау в bpo-38291).

unittest

Добавьте новый метод assertNoLogs() в дополнение к существующему assertLogs(). (Внесен Китом Яном Чоем в bpo-39385).

urllib.parse

Версии Python ранее Python 3.10 позволяли использовать в качестве разделителей параметров запроса ; и & в urllib.parse.parse_qs() и urllib.parse.parse_qsl(). По соображениям безопасности и в соответствии с новыми рекомендациями W3C это было изменено, чтобы разрешить только один ключ-разделитель, а по умолчанию используется &. Это изменение также затрагивает cgi.parse() и cgi.parse_multipart(), поскольку они используют затронутые функции внутри. Более подробную информацию можно найти в соответствующей документации. (Внесено Адамом Голдшмидтом, Сентхилом Кумараном и Кеном Джином в bpo-42967).

Наличие символов новой строки или табуляции в части URL позволяет осуществлять некоторые виды атак. В соответствии со спецификацией WHATWG, которая обновляет RFC 3986, символы ASCII новой строки \n, \r и табуляции \t удаляются из URL парсером в urllib.parse, предотвращая такие атаки. Символы удаления контролируются новой переменной уровня модуля urllib.parse._UNSAFE_URL_BYTES_TO_REMOVE (см. gh-88048).

xml

Добавьте класс LexicalHandler в модуль xml.sax.handler. (Вклад Джонатана Госсаджа и Закери Спитца в bpo-35018).

zipimport

Добавьте методы, связанные с PEP 451: find_spec(), zipimport.zipimporter.create_module() и zipimport.zipimporter.exec_module(). (Внесено Бреттом Кэнноном в bpo-42131).

Добавьте метод invalidate_caches(). (Внесено Десмондом Чонгом в bpo-14678).

Оптимизации

  • Конструкторы str(), bytes() и bytearray() теперь работают быстрее (примерно на 30-40% для небольших объектов). (Внесено Сергеем Сторчакой в bpo-41334).

  • Модуль runpy теперь импортирует меньше модулей. Время запуска команды python3 -m module-name в среднем в 1,4 раза быстрее. В Linux python3 -I -m module-name импортирует 69 модулей на Python 3.9, а на Python 3.10 - только 51 модуль (-18). (Вклад Виктора Стиннера в bpo-41006 и bpo-41718).

  • Инструкция LOAD_ATTR теперь использует новый механизм «кэш на опкод». Теперь она примерно на 36% быстрее для обычных атрибутов и на 44% - для слотов. (Вклад Пабло Галиндо и Юрия Селиванова в bpo-42093 и Гвидо ван Россума в bpo-42927, основанный на идеях, первоначально реализованных в PyPy и MicroPython).

  • При сборке Python с --enable-optimizations теперь -fno-semantic-interposition добавляется как в строку компиляции, так и в строку линковки. Это ускоряет сборку интерпретатора Python, созданного с помощью --enable-shared, с помощью gcc на 30 %. Более подробную информацию см. в this article. (Внесено Виктором Стиннером и Пабло Галиндо в bpo-38980).

  • Используйте новый код управления выходным буфером для bz2 / lzma / zlib модулей, а также добавлена функция .readall() в класс _compression.DecompressReader. bz2-декомпрессия теперь быстрее на 1,09x ~ 1,17x, lzma-декомпрессия быстрее на 1,20x ~ 1,32x, GzipFile.read(-1) 1,11x ~ 1,18x быстрее. (Внесено Ма Линем, рецензировано Грегори П. Смитом, в bpo-41486)

  • При использовании строковых аннотаций дикты аннотаций для функций больше не создаются при создании функции. Вместо этого они хранятся в виде кортежа строк, а объект функции лениво преобразует их в дикту аннотаций по требованию. Эта оптимизация сокращает процессорное время, необходимое для определения аннотированной функции, в два раза. (Вклад Юрия Карабаса и Инады Наоки в bpo-42202).

  • Функции поиска подстрок, такие как str1 in str2 и str2.find(str1), теперь иногда используют алгоритм поиска строк Crochemore & Perrin «Two-Way», чтобы избежать квадратичного поведения на длинных строках. (Внесено Деннисом Суини в bpo-41972)

  • Добавьте микрооптимизацию в _PyType_Lookup(), чтобы улучшить производительность поиска в кэше атрибутов типов в часто встречающемся случае попадания в кэш. Это делает интерпретатор в среднем в 1,04 раза быстрее. (Внесено Дино Вьеландом в bpo-43452).

  • Следующие встроенные функции теперь поддерживают более быстрое соглашение о вызове векторного вызова PEP 590: map(), filter(), reversed(), bool() и float(). (Вклад Донгхи На и Йеруна Демейера в bpo-43575, bpo-43287, bpo-41922, bpo-41873 и bpo-41870).

  • Производительность BZ2File повышается за счет удаления внутренних RLock. Это делает поток BZ2File небезопасным перед лицом нескольких одновременных читателей или писателей, как это всегда делали эквивалентные классы в gzip и lzma. (Внесено Инадой Наоки в bpo-43785).

Утратившие актуальность

  • В настоящее время Python принимает числовые литералы, за которыми сразу следуют ключевые слова, например 0in x, 1or x, 0if 1else 2. Это позволяет использовать такие запутанные и неоднозначные выражения, как [0x1for x in y] (которое может быть интерпретировано как [0x1 for x in y] или [0x1f or x in y]). Начиная с этого выпуска, если за числовым литералом сразу следует одно из ключевых слов and, else, for, if, in, is и or, то выдается предупреждение об устаревании. В последующих выпусках она будет заменена на предупреждение о синтаксисе и, наконец, на ошибку синтаксиса. (Внесено Сергеем Сторчакой в bpo-43833).

  • Начиная с этого выпуска, будут предприняты целенаправленные усилия по очистке старых семантик импорта, которые были сохранены для совместимости с Python 2.7. В частности, find_loader()/find_module() (заменено на find_spec()), load_module() (заменено на exec_module()), module_repr() (о чем система импорта позаботится за вас), атрибут __package__ (заменен на __spec__.parent), атрибут __loader__ (заменен на __spec__.loader) и атрибут __cached__ (заменен на __spec__.cached) будут постепенно удаляться (как и другие классы и методы в importlib). По мере необходимости будут подниматься ImportWarning и/или DeprecationWarning, чтобы помочь определить код, который нуждается в обновлении во время этого перехода.

  • Все пространство имен distutils является устаревшим и будет удалено в Python 3.12. Для получения дополнительной информации обратитесь к разделу module changes.

  • Нецелые аргументы в random.randrange() устарели. Утрачивается ValueError в пользу TypeError. (Внесено Сергеем Сторчакой и Раймондом Хеттингером в bpo-37319).

  • Различные методы load_module() из importlib были задокументированы как устаревшие начиная с Python 3.6, но теперь они также будут вызывать DeprecationWarning. Вместо этого используйте exec_module(). (Внесено Бреттом Кэнноном в bpo-26131).

  • zimport.zipimporter.load_module() был упразднен в пользу exec_module(). (Внесено Бреттом Кэнноном в bpo-26131).

  • Использование load_module() системой импорта теперь вызывает появление ImportWarning, поскольку предпочтительнее exec_module(). (Внесено Бреттом Кэнноном в bpo-26131).

  • Использование importlib.abc.MetaPathFinder.find_module() и importlib.abc.PathEntryFinder.find_module() системой импорта теперь вызывает срабатывание ImportWarning, так как предпочтительны importlib.abc.MetaPathFinder.find_spec() и importlib.abc.PathEntryFinder.find_spec() соответственно. Вы можете использовать importlib.util.spec_from_loader(), чтобы помочь в переносе. (Внесено Бреттом Кэнноном в bpo-42134).

  • Использование importlib.abc.PathEntryFinder.find_loader() системой импорта теперь вызывает появление ImportWarning, так как предпочтительнее importlib.abc.PathEntryFinder.find_spec(). Вы можете использовать importlib.util.spec_from_loader(), чтобы помочь в портировании. (Внесено Бреттом Кэнноном в bpo-43672).

  • Различные реализации importlib.abc.MetaPathFinder.find_module() ( importlib.machinery.BuiltinImporter.find_module(), importlib.machinery.FrozenImporter.find_module(), importlib.machinery.WindowsRegistryFinder.find_module(), importlib.machinery.PathFinder.find_module(), importlib.abc.MetaPathFinder.find_module() ), importlib.abc.PathEntryFinder.find_module() ( importlib.machinery.FileFinder.find_module() ) и importlib.abc.PathEntryFinder.find_loader() ( importlib.machinery.FileFinder.find_loader() ) теперь поднимают DeprecationWarning и планируются к удалению в Python 3.12 (ранее они были задокументированы как deprecated в Python 3.4). (Внесено Бреттом Кэнноном в bpo-42135).

  • importlib.abc.Finder устарел (включая его единственный метод, find_module()). И importlib.abc.MetaPathFinder, и importlib.abc.PathEntryFinder больше не наследуются от этого класса. Пользователям следует наследоваться от одного из этих двух классов. (Внесено Бреттом Кэнноном в bpo-42135).

  • Утраты imp, importlib.find_loader(), importlib.util.set_package_wrapper(), importlib.util.set_loader_wrapper(), importlib.util.module_for_loader(), pkgutil.ImpImporter и pkgutil.ImpLoader были обновлены, чтобы указать Python 3.12 в качестве планируемой версии для удаления (они начали поднимать DeprecationWarning в предыдущих версиях Python). (Внесено Бреттом Кэнноном в bpo-43720).

  • Система импорта теперь использует атрибут __spec__ для модулей, прежде чем вернуться к module_repr() для метода __repr__() модуля. Отказ от использования module_repr() запланирован на Python 3.12. (Внесено Бреттом Кэнноном в bpo-42137).

  • importlib.abc.Loader.module_repr(), importlib.machinery.FrozenLoader.module_repr() и importlib.machinery.BuiltinLoader.module_repr() устарели и подлежат удалению в Python 3.12. (Внесено Бреттом Кэнноном в bpo-42136).

  • sqlite3.OptimizedUnicode не документирован и устарел со времен Python 3.3, когда он стал псевдонимом str. Сейчас она устарела и планируется к удалению в Python 3.12. (Внесено Эрлендом Э. Аасланом в bpo-42264).

  • Недокументированная встроенная функция sqlite3.enable_shared_cache уже устарела и планируется к удалению в Python 3.12. Документация по SQLite3 настоятельно не рекомендует ее использовать. Более подробную информацию см. в разделе the SQLite3 docs. Если необходимо использовать общий кэш, откройте базу данных в режиме URI с помощью параметра запроса cache=shared. (Внесено Эрлендом Э. Аасланом в bpo-24464).

  • Следующие методы threading теперь устарели:

    (Предоставлено Jelle Zijlstra в gh-87889).

  • pathlib.Path.link_to() устарел и будет удален в Python 3.12. Вместо него используйте pathlib.Path.hardlink_to(). (Внесено Барни Гейлом в bpo-39950).

  • cgi.log() устарел и будет удален в Python 3.12. (Внесено Инадой Наоки в bpo-41139).

  • Следующие функции ssl были устаревшими с Python 3.6, Python 3.7 или OpenSSL 1.1.0 и будут удалены в версии 3.11:

  • Отладка потоков (PYTHONTHREADDEBUG переменная окружения) устарела в Python 3.10 и будет удалена в Python 3.12. Эта функция требует наличия debug build of Python. (Внесено Виктором Стиннером в bpo-44584).

  • При импорте из подмодулей typing.io и typing.re теперь будет выдаваться DeprecationWarning. Эти подмодули будут удалены в будущей версии Python. Все, что относится к этим подмодулям, следует импортировать непосредственно из typing. (Внесено Себастьяном Риттау в bpo-38291).

Удалено

  • Удалены специальные методы __int__, __float__, __floordiv__, __mod__, __divmod__, __rfloordiv__, __rmod__ и __rdivmod__ класса complex. Они всегда поднимали TypeError. (Внесено Сергеем Сторчакой в bpo-41974).

  • Метод ParserBase.error() из частного и недокументированного модуля _markupbase был удален. html.parser.HTMLParser является единственным подклассом ParserBase, и его реализация error() уже была удалена в Python 3.5. (Внесено Беркером Пексагом в bpo-31844).

  • Удален атрибут unicodedata.ucnhash_CAPI, который был внутренним объектом PyCapsule. Связанная с ним приватная структура _PyUnicode_Name_CAPI была перенесена во внутренний C API. (Внесено Виктором Стиннером в bpo-42157).

  • Удален модуль parser, который был устаревшим в 3.9 в связи с переходом на новый парсер PEG, а также все исходные и заголовочные файлы на Си, которые использовались только старым парсером, включая node.h, parser.h, graminit.h и grammar.h.

  • Удалены функции Public C API PyParser_SimpleParseStringFlags, PyParser_SimpleParseStringFlagsFilename, PyParser_SimpleParseFileFlags и PyNode_Compile, которые были устаревшими в 3.9 в связи с переходом на новый парсер PEG.

  • Удален модуль formatter, который был устаревшим в Python 3.4. Он несколько устарел, мало используется и не тестируется. Изначально планировалось удалить его в Python 3.6, но удаление было отложено до окончания срока действия Python 2.7. Существующие пользователи должны скопировать все классы, которые они используют, в свой код. (Внесено Donghee Na и Terry J. Reedy в bpo-42299).

  • Удалена функция PyModule_GetWarningsModule(), которая теперь была бесполезна из-за того, что модуль _warnings был преобразован во встроенный модуль в 2.6. (Внесено Хай Ши в bpo-42599).

  • Удалите устаревшие псевдонимы на Коллекции Абстрактные базовые классы из модуля collections. (Внесено Виктором Стиннером в bpo-37324).

  • Параметр loop был удален из большинства asyncio' high-level API после того, как он был устаревшим в Python 3.8. Мотивация этого изменения многообразна:

    1. Это упрощает высокоуровневый API.

    2. Начиная с Python 3.7 функции высокоуровневого API неявно получают цикл событий текущего потока. В большинстве обычных случаев нет необходимости передавать цикл событий в API.

    3. Передача циклов событий чревата ошибками, особенно если речь идет о циклах, выполняющихся в разных потоках.

    Обратите внимание, что низкоуровневый API по-прежнему будет принимать loop. Примеры замены существующего кода см. в разделе Изменения в API Python.

    (При участии Юрия Карабаса, Андрея Светлова, Юрия Селиванова и Кайла Стэнли в bpo-42392).

Переход на Python 3.10

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

Изменения в синтаксисе языка Python

  • Теперь при компиляции ранее корректного синтаксиса выдается предупреждение об устаревании, если за числовым литералом сразу следует ключевое слово (как в 0in x). В будущих выпусках оно будет заменено на предупреждение о синтаксисе и, наконец, на синтаксическую ошибку. Чтобы избавиться от предупреждения и сделать код совместимым с будущими выпусками, просто добавьте пробел между числовым литералом и следующим за ним ключевым словом. (Внесено Сергеем Сторчакой в bpo-43833).

Изменения в API Python

  • Параметры etype функций format_exception(), format_exception_only() и print_exception() в модуле traceback были переименованы в exc. (Внесено Закери Шпитцем и Матиасом Буссонье в bpo-26389).

  • atexit: При выходе из Python, если обратный вызов, зарегистрированный в atexit.register(), не работает, его исключение теперь записывается в журнал. Ранее в журнал записывались только некоторые исключения, а последнее исключение всегда молча игнорировалось. (Внесено Виктором Стиннером в bpo-42639).

  • Родовой collections.abc.Callable теперь сглаживает параметры типа, подобно тому, как это делает typing.Callable. Это означает, что collections.abc.Callable[[int, str], str] будет содержать __args__ из (int, str, str); ранее это был ([int, str], str). Код, обращающийся к аргументам через typing.get_args() или __args__, должен учитывать это изменение. Кроме того, TypeError может быть поднят для недопустимых форм параметризации collections.abc.Callable, которые в Python 3.9 могли проходить молча. (Внесено Кеном Джином в bpo-42195).

  • socket.htons() и socket.ntohs() теперь поднимают OverflowError вместо DeprecationWarning, если заданный параметр не помещается в 16-битное беззнаковое целое число. (Внесено Эрлендом Э. Аасланом в bpo-42393).

  • Параметр loop был удален из большинства asyncio' high-level API после того, как он был устаревшим в Python 3.8.

    Корутин, который в настоящее время выглядит следующим образом:

    async def foo(loop):
        await asyncio.sleep(1, loop=loop)
    

    Следует заменить на следующее:

    async def foo():
        await asyncio.sleep(1)
    

    Если foo() был специально разработан не для выполнения в цикле событий текущего потока (например, для выполнения в цикле событий другого потока), используйте вместо него asyncio.run_coroutine_threadsafe().

    (При участии Юрия Карабаса, Андрея Светлова, Юрия Селиванова и Кайла Стэнли в bpo-42392).

  • Конструктор types.FunctionType теперь наследует текущие buildins, если в словаре globals нет ключа "__builtins__", а не использует {"None": None} в качестве builtins: такое же поведение для функций eval() и exec(). Определение функции с помощью def function(...): ... в Python не затрагивается, глобальные функции не могут быть переопределены с помощью этого синтаксиса: они также наследуют текущие встроенные функции. (Внесено Виктором Стиннером в bpo-42990).

Изменения в API языка C

  • Функции C API PyParser_SimpleParseStringFlags, PyParser_SimpleParseStringFlagsFilename, PyParser_SimpleParseFileFlags, PyNode_Compile и тип, используемый этими функциями, struct _node, были удалены в связи с переходом на новый парсер PEG.

    Теперь исходный текст должен быть скомпилирован непосредственно в объект кода, например, с помощью Py_CompileString(). Затем полученный объект кода можно оценить, например, с помощью PyEval_EvalCode().

    В частности:

    • Вызов PyParser_SimpleParseStringFlags с последующим PyNode_Compile может быть заменен вызовом Py_CompileString().

    • Прямой замены для PyParser_SimpleParseFileFlags не существует. Чтобы скомпилировать код из аргумента FILE *, вам нужно прочитать файл на C и передать полученный буфер в Py_CompileString().

    • Чтобы скомпилировать файл с именем char *, нужно явно открыть файл, прочитать его и скомпилировать результат. Один из способов сделать это - использовать модуль io с PyImport_ImportModule(), PyObject_CallMethod(), PyBytes_AsString() и Py_CompileString(), как показано ниже. (Декларации и обработка ошибок опущены.)

      io_module = Import_ImportModule("io");
      fileobject = PyObject_CallMethod(io_module, "open", "ss", filename, "rb");
      source_bytes_object = PyObject_CallMethod(fileobject, "read", "");
      result = PyObject_CallMethod(fileobject, "close", "");
      source_buf = PyBytes_AsString(source_bytes_object);
      code = Py_CompileString(source_buf, filename, Py_file_input);
      
    • Для объектов FrameObject член f_lasti теперь представляет собой смещение кода слова, а не просто смещение в строке байткода. Это означает, что это число нужно умножить на 2, чтобы использовать его в API, которые ожидают байтовое смещение (например, PyCode_Addr2Line()). Заметьте также, что член f_lasti объектов FrameObject не считается стабильным: вместо него используйте PyFrame_GetLineNumber().

Изменения байткода CPython

  • Инструкция MAKE_FUNCTION теперь принимает в качестве аннотации функции либо dict, либо кортеж строк. (Внесено Юрием Карабасом и Инадой Наоки в bpo-42202).

Изменения в конструкции

  • PEP 644: Python теперь требует OpenSSL 1.1.1 или новее. OpenSSL 1.0.2 больше не поддерживается. (Внесено Кристианом Хаймсом в bpo-43669).

  • Функции C99 snprintf() и vsnprintf() теперь необходимы для сборки Python. (Внесено Виктором Стиннером в bpo-36020).

  • Для sqlite3 требуется SQLite 3.7.15 или выше. (Вклад Сергея Федосеева и Эрленда Э. Аасланда в bpo-40744 и bpo-40810).

  • Модуль atexit теперь всегда должен собираться как встроенный модуль. (Внесено Виктором Стиннером в bpo-42639).

  • Добавьте опцию --disable-test-modules в скрипт configure: не собирать и не устанавливать тестовые модули. (Внесено Ксавье де Гаем, Томасом Петаццони и Пейсин Синем в bpo-27640).

  • Добавьте --with-wheel-pkg-dir=PATH option в скрипт ./configure. Если указано, модуль ensurepip ищет в этом каталоге колесные пакеты setuptools и pip: если оба присутствуют, эти колесные пакеты используются вместо колесных пакетов, входящих в комплект поставки ensurepip.

    Некоторые политики упаковки дистрибутивов Linux рекомендуют не связывать зависимости. Например, Fedora устанавливает пакеты wheel в каталог /usr/share/python-wheels/ и не устанавливает пакет ensurepip._bundled.

    (Внесено Виктором Стиннером в bpo-42856).

  • Добавьте новый configure --without-static-libpython option, чтобы не собирать статическую библиотеку libpythonMAJOR.MINOR.a и не устанавливать объектный файл python.o.

    (Внесено Виктором Стиннером в bpo-43103).

  • Скрипт configure теперь использует утилиту pkg-config, если она доступна, для определения местоположения заголовков и библиотек Tcl/Tk. Как и раньше, эти места можно явно указать с помощью опций конфигурации --with-tcltk-includes и --with-tcltk-libs. (Внесено Манолисом Стаматогианнакисом в bpo-42603).

  • Добавьте опцию --with-openssl-rpath в скрипт configure. Опция упрощает сборку Python с пользовательской установкой OpenSSL, например, ./configure --with-openssl=/path/to/openssl --with-openssl-rpath=auto. (Внесено Кристианом Хаймсом в bpo-43466).

Изменения в API на языке C

PEP 652: Поддержание стабильной ПВБ

Стабильный ABI (Application Binary Interface) для модулей расширения или встраивания Python теперь определен в явном виде. C Стабильность API описывает гарантии стабильности C API и ABI, а также лучшие практики использования Stable ABI.

(Внесено Петром Викториным в PEP 652 и bpo-43795).

Новые возможности

  • Результат PyNumber_Index() теперь всегда имеет точный тип int. Ранее результат мог быть экземпляром подкласса int. (Внесено Сергеем Сторчакой в bpo-40792).

  • Добавьте новый член orig_argv в структуру PyConfig: список исходных аргументов командной строки, переданных исполняемому файлу Python. (Внесено Виктором Стиннером в bpo-23427).

  • Макросы PyDateTime_DATE_GET_TZINFO() и PyDateTime_TIME_GET_TZINFO() были добавлены для доступа к атрибутам tzinfo объектов datetime.datetime и datetime.time. (Внесено Закери Спитцем в bpo-30155).

  • Добавьте функцию PyCodec_Unregister() для снятия с регистрации функции поиска кодеков. (Внесено Хай Ши в bpo-41842).

  • Функция PyIter_Send() была добавлена для того, чтобы можно было отправлять значение в итератор, не вызывая исключения StopIteration. (Внесено Владимиром Матвеевым в bpo-41756).

  • Добавьте PyUnicode_AsUTF8AndSize() в ограниченный API языка C. (Внесено Алексом Гейнором в bpo-41784).

  • Добавьте функцию PyModule_AddObjectRef(): аналогично PyModule_AddObject(), но не крадите ссылку на значение при успехе. (Внесено Виктором Стиннером в bpo-1635741).

  • Добавьте функции Py_NewRef() и Py_XNewRef() для увеличения количества ссылок на объект и возврата объекта. (Внесено Виктором Стиннером в bpo-42262).

  • Функции PyType_FromSpecWithBases() и PyType_FromModuleAndSpec() теперь принимают один класс в качестве аргумента bases. (Внесено Сергеем Сторчакой в bpo-42423).

  • Функция PyType_FromModuleAndSpec() теперь принимает слот NULL tp_doc. (Внесено Хай Ши в bpo-41832).

  • Функция PyType_GetSlot() может принимать static types. (Внесено Хай Ши и Петром Викторином в bpo-41073).

  • Добавьте в C-API новую функцию PySet_CheckExact() для проверки, является ли объект экземпляром set, но не является экземпляром подтипа. (Внесено Пабло Галиндо в bpo-43277).

  • Добавьте PyErr_SetInterruptEx(), который позволяет передать номер сигнала для симуляции. (Внесено Антуаном Питру в bpo-43356).

  • Ограниченный C API теперь поддерживается, если Python is built in debug mode (если определен макрос Py_DEBUG). В ограниченном C API функции Py_INCREF() и Py_DECREF() теперь реализованы как непрозрачные вызовы функций, а не как прямое обращение к члену PyObject.ob_refcnt, если Python построен в режиме отладки и макрос Py_LIMITED_API нацелен на Python 3.10 или новее. Поддержка ограниченного C API в режиме отладки стала возможной благодаря тому, что структура PyObject одинакова в режиме выпуска и отладки начиная с Python 3.8 (см. bpo-36465).

    Ограниченный C API по-прежнему не поддерживается в специальной сборке --with-trace-refs (макрос Py_TRACE_REFS). (Внесено Виктором Стиннером в bpo-43688).

  • Добавьте функцию Py_Is(x, y) для проверки, является ли объект x объектом y, как и x is y в Python. Добавьте также функции Py_IsNone(), Py_IsTrue(), Py_IsFalse() для проверки, является ли объект, соответственно, синглтоном None, синглтоном True или синглтоном False. (Внесено Виктором Стиннером в bpo-43753).

  • Добавьте новые функции для управления сборщиком мусора из кода на Си: PyGC_Enable(), PyGC_Disable(), PyGC_IsEnabled(). Эти функции позволяют активировать, деактивировать и запрашивать состояние сборщика мусора из Си-кода без необходимости импортировать модуль gc.

  • Добавьте новый флаг типа Py_TPFLAGS_DISALLOW_INSTANTIATION, чтобы запретить создание экземпляров типа. (Внесено Виктором Стиннером в bpo-43916).

  • Добавьте новый флаг типа Py_TPFLAGS_IMMUTABLETYPE для создания объектов неизменяемого типа: атрибуты типа не могут быть ни установлены, ни удалены. (Внесено Виктором Стиннером и Эрлендом Э. Аасланом в bpo-43908).

Переход на Python 3.10

  • Теперь макрос PY_SSIZE_T_CLEAN должен быть определен для использования форматов PyArg_ParseTuple() и Py_BuildValue(), которые используют #: es#, et#, s#, u#, y#, z#, U# и Z#. См. Разбор аргументов и создание значений и PEP 353. (Внесено Виктором Стиннером в bpo-40943).

  • Поскольку Py_REFCNT() заменен на встроенную статическую функцию, Py_REFCNT(obj) = new_refcnt должен быть заменен на Py_SET_REFCNT(obj, new_refcnt): см. Py_SET_REFCNT() (доступен начиная с Python 3.9). Для обратной совместимости можно использовать этот макрос:

    #if PY_VERSION_HEX < 0x030900A4
    #  define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0)
    #endif
    

    (Внесено Виктором Стиннером в bpo-39573).

  • Вызов PyDict_GetItem() без удержания GIL был разрешен по историческим причинам. Теперь это больше не разрешено. (Внесено Виктором Стиннером в bpo-40839).

  • PyUnicode_FromUnicode(NULL, size) и PyUnicode_FromStringAndSize(NULL, size) теперь повышают DeprecationWarning. Используйте PyUnicode_New() для выделения объекта Unicode без начальных данных. (Внесено Инадой Наоки в bpo-36346).

  • Приватная структура _PyUnicode_Name_CAPI из PyCapsule API unicodedata.ucnhash_CAPI была перенесена во внутренний C API. (Внесено Виктором Стиннером в bpo-42157).

  • Функции Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix(), Py_GetProgramFullPath(), Py_GetPythonHome() и Py_GetProgramName() теперь возвращают NULL, если вызваны до Py_Initialize() (до инициализации Python). Используйте новый Конфигурация инициализации Python API, чтобы получить Конфигурация пути Python. (Внесено Виктором Стиннером в bpo-42260).

  • Макросы PyList_SET_ITEM(), PyTuple_SET_ITEM() и PyCell_SET() больше не могут использоваться в качестве l-значения или r-значения. Например, x = PyList_SET_ITEM(a, b, c) и PyList_SET_ITEM(a, b, c) = x теперь завершаются с ошибкой компилятора. Это предотвращает ошибки, подобные проверке if (PyList_SET_ITEM (a, b, c) < 0) .... (Вклад Закери Спитца и Виктора Стиннера в bpo-30459).

  • Нелимитированные файлы API odictobject.h, parser_interface.h, picklebufobject.h, pyarena.h, pyctype.h, pydebug.h, pyfpe.h и pytime.h были перемещены в каталог Include/cpython. Эти файлы не должны быть включены напрямую, так как они уже включены в Python.h; см. Включить файлы. Если они были включены напрямую, подумайте о том, чтобы включить вместо них Python.h. (Внесено Николасом Симом в bpo-35134).

  • Используйте флаг типа Py_TPFLAGS_IMMUTABLETYPE для создания неизменяемых объектов типа. Не полагайтесь на Py_TPFLAGS_HEAPTYPE, чтобы решить, является ли объект типа мутабельным или нет; вместо этого проверьте, установлен ли Py_TPFLAGS_IMMUTABLETYPE. (Внесено Виктором Стиннером и Эрлендом Э. Аасланд в bpo-43908).

  • Недокументированная функция Py_FrozenMain была удалена из ограниченного API. Эта функция в основном полезна для пользовательских сборок Python. (Внесено Петром Викторином в bpo-26241).

Утратившие актуальность

  • Функция PyUnicode_InternImmortal() теперь устарела и будет удалена в Python 3.12: используйте вместо нее PyUnicode_InternInPlace(). (Внесено Виктором Стиннером в bpo-41692).

Удалено

  • Удалены функции Py_UNICODE_str*, манипулирующие строками Py_UNICODE*. (Внесено Инадой Наоки в bpo-41123).

  • Удалены PyUnicode_GetMax(). Пожалуйста, перейдите на новые (PEP 393) API. (Внесено Инадой Наоки в bpo-41103).

  • Удален PyLong_FromUnicode(). Пожалуйста, перейдите на PyLong_FromUnicodeObject(). (Внесено Инадой Наоки в bpo-41103).

  • Удален PyUnicode_AsUnicodeCopy(). Пожалуйста, используйте PyUnicode_AsUCS4Copy() или PyUnicode_AsWideCharString() (Внесено Инада Наоки в bpo-41103).

  • Удалена переменная _Py_CheckRecursionLimit: она была заменена на ceval.recursion_limit из структуры PyInterpreterState. (Внесено Виктором Стиннером в bpo-41834).

  • Удалены недокументированные макросы Py_ALLOW_RECURSION и Py_END_ALLOW_RECURSION, а также поле recursion_critical структуры PyInterpreterState. (Внесено Сергеем Сторчакой в bpo-41936).

  • Удалена недокументированная функция PyOS_InitInterrupts(). Инициализация Python уже неявно устанавливает обработчики сигналов: см. PyConfig.install_signal_handlers. (Внесено Виктором Стиннером в bpo-41713).

  • Удалите функцию PyAST_Validate(). Больше невозможно построить объект AST (тип``mod_ty``) с помощью публичного C API. Эта функция уже была исключена из ограниченного C API (PEP 384). (Внесено Виктором Стиннером в bpo-43244).

  • Удалите заголовочный файл symtable.h и недокументированные функции:

    • PyST_GetScope()

    • PySymtable_Build()

    • PySymtable_BuildObject()

    • PySymtable_Free()

    • Py_SymtableString()

    • Py_SymtableStringObject()

    Функция Py_SymtableString() по ошибке вошла в стабильный ABI, но ее нельзя было использовать, потому что заголовочный файл symtable.h был исключен из ограниченного API C.

    Вместо этого используйте модуль Python symtable. (Внесено Виктором Стиннером в bpo-43244).

  • Удалите PyOS_ReadlineFunctionPointer() из ограниченных заголовков C API и из python3.dll, библиотеки, обеспечивающей стабильный ABI в Windows. Поскольку функция принимает аргумент FILE*, стабильность ее ABI не может быть гарантирована. (Внесено Петром Викторином в bpo-43868).

  • Удалите заголовочные файлы ast.h, asdl.h и Python-ast.h. Эти функции были недокументированы и исключены из ограниченного API языка C. Большинство имен, определяемых этими заголовочными файлами, не имели префикса Py и поэтому могли создавать конфликты имен. Например, Python-ast.h определял макрос Yield, который конфликтовал с именем Yield, используемым в заголовке Windows <winbase.h>. Вместо этого используйте модуль Python ast. (Внесено Виктором Стиннером в bpo-43244).

  • Удалите функции компилятора и парсера, использующие тип struct _mod, поскольку публичный API AST C был удален:

    • PyAST_Compile()

    • PyAST_CompileEx()

    • PyAST_CompileObject()

    • PyFuture_FromAST()

    • PyFuture_FromASTObject()

    • PyParser_ASTFromFile()

    • PyParser_ASTFromFileObject()

    • PyParser_ASTFromFilename()

    • PyParser_ASTFromString()

    • PyParser_ASTFromStringObject()

    Эти функции были недокументированы и исключены из ограниченного API языка C. (Внесено Виктором Стиннером в bpo-43244).

  • Удалите заголовочный файл pyarena.h с функциями:

    • PyArena_New()

    • PyArena_Free()

    • PyArena_Malloc()

    • PyArena_AddPyObject()

    Эти функции были недокументированы, исключены из ограниченного API языка C и использовались только внутренним компилятором. (Внесено Виктором Стиннером в bpo-43244).

  • Член PyThreadState.use_tracing был удален для оптимизации Python. (Внесено Марком Шенноном в bpo-43760).

Примечательная функция безопасности в 3.10.7

Преобразование между int и str в основаниях, отличных от 2 (двоичное), 4, 8 (восьмеричное), 16 (шестнадцатеричное) или 32, таких как основание 10 (десятичное), теперь вызывает ошибку ValueError, если количество цифр в строковой форме превышает установленный предел, чтобы избежать потенциальных атак типа «отказ в обслуживании» из-за сложности алгоритма. Это смягчение последствий CVE-2020-10735. Это ограничение может быть настроено или отключено с помощью переменной окружения, флага командной строки или sys. API. См. документацию по integer string conversion length limitation. По умолчанию ограничение составляет 4300 цифр в строковой форме.

Примечательная функция безопасности в версии 3.10.8

Устаревший модуль mailcap теперь отказывается внедрять небезопасный текст (имена файлов, типы MIME, параметры) в команды оболочки. Вместо использования такого текста он будет предупреждать и действовать так, как если бы совпадение не было найдено (или для тестовых команд - как если бы тест не удался). (Внесено Петром Викторином в gh-98966).

Заметные изменения в версии 3.10.12

tarfile

  • Методы извлечения в tarfile и shutil.unpack_archive() имеют новый аргумент filter, который позволяет ограничить возможности tar, которые могут быть неожиданными или опасными, например создание файлов вне целевого каталога. Подробности см. в Фильтры для извлечения. В Python 3.12 использование без аргумента filter приводит к появлению DeprecationWarning. В Python 3.14 по умолчанию будет отображаться 'data'. (Внесено Петром Викториным в PEP 706).