Динамическая генерация кода для обработки Exception (метапрограммирование)

Подбирая варианты решений к этому вопросу, хотела использовать модуль pdb.
С помощью модуля pdb можно изменять переменные и выполнять функции,
вводя в консоль соответствующие команды.
Но не могу понять как можно программно отправлять команды в консоль отладки.
Перехват с помощью sys.stdout приводит к конфликту с консолью отладки pdb.
(пробовала перехваченный out добавлять в асинхронную очередь и обрабатывать в другом потоке, но пока не получилось.)

Сейчас пробую через менеджер контекста.
Вот код:

import re
import sys
import pdb
import traceback
from contextlib import contextmanager

from rich import print, inspect

# Динамическое создание функций
def create_function(name):
    def func(param):
        print(f'{param}("{name}")')
    return func

# Класс для перехвата вывода
class StreamInterceptor:
    def __init__(self):
        self.original_stdout = sys.stdout

    def write(self, message):
        # Перехватываем вывод и обрабатываем его
        print(f"Перехваченный вывод: {message.strip()}")

    def flush(self):
        pass  # Нужно для совместимости

    def __enter__(self):
        sys.stdout = self
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        sys.stdout = self.original_stdout

# Обработчик исключений
def my_except_hook(exctype, value, tb):
    if exctype is not SystemExit:
        tb_str = ''.join(traceback.format_exception(exctype, value, tb))
        print(f"Обрабатываем исключение:\n{tb_str}")
        # Извлечение имени функции из traceback
        func_name = value.name

        globals()[func_name] = create_function(func_name)
        print(f'Создана функция: {func_name}')
        inspect(globals()[func_name])

# Установка обработчика исключений
sys.excepthook = my_except_hook

# Используем контекстный менеджер для перехвата вывода
with StreamInterceptor():
    # Устанавливаем точку останова перед вызовом функции
    # pdb.set_trace()

    Hello_world("print")
    Hello_world("print")
    It_is_not_print("print")

Функция my_except_hook отрабатывает без ошибок, динамически создается функция Hello_world и в консоль выводится строка: print("Hello_world").
В коде выше строчка: pdb.set_trace() пока закомментирована, но использование pdb необходимо, так как исключение даже обработанное приводит к закрытию контекстного менеджера.
см. output:

Обрабатываем исключение:
Traceback (most recent call last):
  File "c:\KWORK\not_print.py", line 73, in <module>
    Hello_world("print")
    ^^^^^^^^^^^
NameError: name 'Hello_world' is not defined

Создана функция: Hello_world
╭─ <function create_function.<locals>.func at 0x00000162AFEC9120> ─╮
│ def create_function.<locals>.func(param):                        │
│                                                                  │
│ 38 attribute(s) not shown. Run inspect(inspect) for options.     │
╰──────────────────────────────────────────────────────────────────╯
print("Hello_world")

Надо чтоб код продолжил выполнение, т.е. lines: 72, 73, 74 должны выполнятся,
именно для этого и нужна breakpoint().


Информации по затронутым темам в сети существенно меньше, чем по Django (например).

Вопрос:

1. Как можно используя модуль pdb, команды вводить программно, а не в консоль (ручками)?

Как реализовать протекцию всего кода?
Например при метапрограммировании, чтоб не приходилось оборачивать в try-except каждую строчку, и не расставлять в таких местах запись в f.log!?
P.S. Глобальная протекция ошибок может решить и такой вопрос.


Ответы (1 шт):

Автор решения: AnnaBazueva

Я поняла, как можно "из кода" выполнять команды pdbфайл .pdbrc,
но это вряд ли может быть глобальной протекцией кода.

А ещё я нашла этот вопрос и ответ на него,
если кто-нибудь задастся целью и даже реализует это —
то практической пользы в этом не будет,
т.к. в сумме эти манипуляции будут очень затратными.


Не делай это, только потому что можешь.

→ Ссылка