В настоящее время я работаю над расширением базы стороннего кода. К сожалению, эта база кода тесно связывает get_args со всеми остальными функциями. get_args — это, по сути, просто метод получения глобального объекта _ARGS. Теперь я хотел бы изменить аргументы для одного вызова функции, не изменяя при этом сам глобальный объект.
С этой целью я использовал unittest.mock.patch, чтобы исправьте функцию get_args, и хотя она успешно исправляется в моей целевой функции f, она не преобразуется в функции, вызываемые f, если они находятся в других модулях. Причина, конечно, в том, что я патчю get_args только в модуле с вызываемой функцией f.
Можно ли издеваться над каждым< /em> последующий вызов get_args внутри моего блока with?
Мой текущий подход, возможно, не лучший для решения этой проблемы, поэтому я также открыт для альтернативных решений этой проблемы.
Минимальный воспроизводимый пример:
Мой код main.py:
from argparse import Namespace
import traceback
import unittest.mock
from mod0 import get_args
from mod1 import f1
class _MockCnt:
def __init__(self):
self._args = Namespace(**{
**get_args().__dict__,
'a': 'a',
})
def new_get_args(self):
print("new_get_args was called")
traceback.print_stack()
return self._args
def main():
with unittest.mock.patch('mod1.get_args', new=_MockCnt().new_get_args):
f1()
main()
Модуль mod0:
from argparse import Namespace
_ARGS = None
def get_args():
global _ARGS
if _ARGS is None:
_ARGS = Namespace(a=1, b=2)
return _ARGS
Модуль mod1:
from mod0 import get_args
from mod2 import f2
def f1():
args = get_args()
args.c = 3
print(f"[f1] Args: {args} (id {id(args)})")
f2()
Модуль mod2:
from mod0 import get_args
def f2():
args = get_args()
print(f"[f2] Args: {args} (id {id(args)})")
Результат:
new get_args was called
File "/tmp/main.py", line 26, in
main()
File "/tmp/main.py", line 24, in main
f1()
File "/tmp/mod1.py", line 6, in f1
args = get_args()
File "/tmp/main.py", line 19, in new_get_args
traceback.print_stack()
[f1] Args: Namespace(a='a', b=2, c=3) (id 281472856422576)
[f2] Args: Namespace(a=1, b=2) (id 281472856399392)
Что мне нужно (следы стека не учитывать):
new get_args was called
[f1] Args: Namespace(a='a', b=2, c=3) (id 281472856422576)
new get_args was called
[f2] Args: Namespace(a='a', b=2, c=3) (id 281472856422576)
Подробнее здесь: https://stackoverflow.com/questions/782 ... le-modules