Как воспроизвести tp_deallo c во время разматывания стека? - PullRequest
0 голосов
/ 28 апреля 2020

Документация Python C API сообщает мне, что tp_dealloc может быть вызван с ошибкой, и в качестве примера дает разматывание стека из-за исключения:

Одним из важных требований функции deallocator является то, что она оставляет все ожидающие исключения в покое. Это важно, поскольку деаллокаторы часто вызываются, поскольку интерпретатор раскручивает стек Python; когда стек разматывается из-за исключения (а не из-за нормальных возвратов), ничего не делается, чтобы защитить освобождающие блоки от просмотра того, что исключение уже установлено. Любые действия, которые выполняет освобождение, которые могут вызвать выполнение дополнительного кода Python, могут обнаружить, что установлено исключение. Это может привести к вводящим в заблуждение ошибкам интерпретатора.

Однако мне кажется, что я не могу воспроизвести это поведение в CPython 3.6 на Ubuntu:

import sys

def raise_error():
    raise ValueError("Boom!")

def try_me():
    obj = sys.Custom()
    raise_error()

def run():
    try:
        try_me()
    except ValueError as e:
        print('VE')
        print(e)
        return

run()
print('42')

В этом примере obj не освобождается до тех пор, пока не завершится run (на хосте C создается тип Custom с пользовательским tp_dealloc, который печатает «err» или «no err» в зависимости от значения, возвращаемого PyErr_Occurred).

Вот что он печатает:

VE

Boom!

no err

42

Является ли этот пункт документации устаревшим? Если нет, как я могу воспроизвести упомянутый там сценарий (например, когда tp_dealloc вызывается с установленной ошибкой)?

...