Using a library that when I call a certain function that I will call foo()
, I am prompted for input as such:
def foo():
if input("Proceed?") == 'yes':
take_action()
I am required to pass in an answer to continue.
But I would like to be able to loop over foo()
with a default value to feed the prompt.
The problem is the developers did not provide an option to supply a default value for the prompt.
Ideally they would have written foo()
like this:
def foo(default_response=None):
if default_response == 'yes':
take_action()
elif input("Proceed?") == 'yes':
take_action()
Given that they did not supply an option for a default response, is there a way for me to loop over foo()
and provide the input automatically without changing the source code?
CodePudding user response:
One solution is to monkey patch the library to temporarily replace the input
function. For example, if I have module foo.py
that looks like this:
def take_action():
print("doing something")
def foo():
if input("Proceed? ") == "yes":
take_action()
I can write bar.py
like this:
import foo
from unittest import mock
def fake_input(default_response=None):
'''Creates a replacement for the `input` function that will
return a default response if one was provided.'''
def _input(prompt):
return default_response if default_response else input(prompt)
return _input
with mock.patch("foo.input", new=fake_input("yes")):
foo.foo()
foo.foo()
If you run this code, you'll see that the first call to foo.foo()
uses a default input, and proceeds without prompting. The second call
to foo.foo()
will prompt normally.