Допустим, у меня есть два скрипта Python A.py
и B.py
. Я ищу способ запустить B изнутри A таким образом, чтобы:
- B считает, что это
__main__
(так что код в блокеif __name__=="__main__"
в B будет работать) - B на самом деле не
__main__
(чтобы, например, он не перезаписывал запись"__main__"
в sys.modules) - Исключения, возникающие в B, распространяются на A (т. е. могут быть перехвачены предложением
except
в A). - Эти исключения, если они не перехвачены, генерируют правильную трассировку, ссылающуюся на номера строк в B.
Я пробовал разные методы, но ни один из них не удовлетворяет всем моим требованиям.
- использование инструментов из модуля подпроцесса означает, что исключения в B не распространяются на A.
execfile("B.py", {})
запускает B, но не считает его основным.execfile("B.py", {'__name__': '__main__'})
заставляет B.py думать, что он главный, но он также, похоже, искажает печать обратной трассировки исключений, так что обратные трассировки ссылаются на строки внутри A (т.е. настоящий__main__
).- использование
imp.load_source
с__main__
в качестве имени почти работает, за исключением того, что оно фактически изменяет sys.modules, тем самым топча существующее значение__main__
Есть ли способ получить то, что я хочу?
(Причина, по которой я это делаю, заключается в том, что я выполняю некоторую очистку существующей библиотеки. В этой библиотеке нет реального набора тестов, просто набор «примеров» сценариев, которые производят определенный вывод. Я пытаюсь использовать их как тесты, чтобы гарантировать, что моя очистка не повлияет на способность библиотеки выполнять эти примеры, поэтому я хочу запускать каждый пример сценария из своего набора тестов. Я хотел бы иметь возможность видеть исключения из этих сценариев в тестовом сценарии, поэтому тестовый сценарий может сообщать о типе сбоя, а не просто сообщать об общей ошибке SubprocessError всякий раз, когда пример сценария вызывает какое-либо исключение.)