Сообщить об ошибке.

Улучшения сообщений об ошибках в Python 3.11

При печати трассировки интерпретатор теперь будет указывать точное выражение, вызвавшее ошибку, а не только строку.

Например:

Traceback (most recent call last):
  File "distance.py", line 11, in <module>
    print(manhattan_distance(p1, p2))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                           ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'

Предыдущие версии интерпретатора, при возникновении ошибки указывали только строку, что делало неясным, какой объект был None. Эти расширенные ошибки также могут быть полезны при работе с глубоко вложенными объектами словарей dict и вызовами нескольких функций:

Traceback (most recent call last):
  File "query.py", line 37, in <module>
    magic_arithmetic('foo')
  File "query.py", line 18, in magic_arithmetic
    return add_counts(x) / 25
           ^^^^^^^^^^^^^
  File "query.py", line 24, in add_counts
    return 25 + query_user(user1) + query_user(user2)
                ^^^^^^^^^^^^^^^^^
  File "query.py", line 32, in query_user
    return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                               ~~~~~~~~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable

А также сложные арифметические выражения:

Traceback (most recent call last):
  File "calculation.py", line 54, in <module>
    result = (x / y / z) * (a / b / c)
              ~~~~~~^~~
ZeroDivisionError: division by zero

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

Codeobject.co_positions():

Возвращает итерацию по позициям исходного кода каждой инструкции байт-кода в объекте кода Codeobject.

Итератор возвращает кортежи, содержащие (start_line, end_line, start_column, end_column). i-й кортеж соответствует позиции исходного кода, скомпилированного в i-ю инструкцию. Информация столбца представляет собой 0-индексированные смещения байтов utf-8 в данной исходной строке.

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

  • Запуск интерпретатора с параметром -X no_debug_ranges.
  • Загрузка файла .pyc, скомпилированного с использованием -X no_debug_ranges.
  • Если возвращаются кортежи, соответствующие искусственным инструкциям.
  • Есть номера строк и столбцов, которые не могут быть представлены из-за ограничений реализации.

Когда это происходит, некоторые или все элементы возвращаемого кортежа могут иметь значение None.

Примечание. Функция codeobject.co_positions() требует сохранения позиций столбцов в объектах кода, что может привести к небольшому увеличению использования памяти интерпретатором и использования диска для скомпилированных файлов Python. Чтобы избежать сохранения дополнительной информации и деактивировать печать дополнительной информации о трассировке, необходимо использовать параметр командной строки -X no_debug_ranges или переменную среды PYTHONNODEBUGRANGES.

Codeobject - объект кода который представляют собой байт-компилированный исполняемый код Python или байт-код. Разница между объектом кода и объектом функции заключается в том, что объект функции содержит явную ссылку на глобальные переменные функции (модуль, в котором он был определен), в то время как объект кода не содержит контекста; также значения аргументов по умолчанию хранятся в объекте функции, а не в объекте кода (поскольку они представляют собой значения, вычисляемые во время выполнения). В отличие от объектов функций, объекты кода неизменяемы и не содержат ссылок (прямых или косвенных) на изменяемые объекты.