Вы можете легко просто передать os.getenv
в качестве первого аргумента, а затем проанализировать его в менеджере контекста намного проще, чем ast
, code
и т. Д. И т. Д.
>>> os.getenv.__name__
'getenv'
>>> os.getenv.__module__
'os'
После этого для использования в достаточно общих целях вы можете получить возвращаемый объект результата или сопоставление аргументов (возможно, их кортежей) с результатами.Диспетчер контекста faker
также может опционально принять вызываемый элемент, который будет использоваться для подделки.
Например, с максимальной простотой:
import sys
def faker(original, fakefun):
original = os.getenv
themod = sys.modules[original.__module__]
thename = original.__name__
def dummy(*a, **k):
try: return fakefun(*a, **k)
except BaseException: return original(*a, **k)
setattr(themod, thename, dummy)
yield
setattr(themod, thename, original)
Ваш конкретный пример может стать:
with faker(os.getenv, dict(HOME='here').__getitem__):
...
Конечно, немного больше сложностей может быть оправдано, если, например, вы хотите распространять определенные исключения, а не выполнять указание на исходную функцию, или сокращать некоторые распространенные случаи, когда предоставление фальшивого вызываемого вызова затруднительно, и так далее.Но нет никакой причины, по которой такой универсальный мошенник должен быть намного более сложным, чем ваш конкретный.