I'm sorry, I clearly haven't explained myself well as otherwise you would not have wasted a huge amount of text tying yourself in knots based clearly on a mistaken apprehension of what I was saying.
For clarity I reproduce the original function you gave and then I present what the change I am suggesting is
def cool_function(x):
for i in range(x):
print(i)
My change
def cool_function(x, output_stream=sys.stdout):
for i in range(x):
print(i, file=output_stream)
Does it now become clear what I am suggesting? My new function can be used as a 1-for-1 replacement for the old function, no code of the system needs changed as the default value provided to the new variable ensures semantically identical operation without changing any further code. Yet it is now unit testable
But now we can write a unit test like
def test_output():
output = io.StringIO()
cool_function(1, output)
contents = output.getvalue()
assert contents=="1\n"
So I've made the code unit testable, kept semantics completely identical and not had to worrty about any weird IO concerns that you have. No monkey patching, no weird file IO, no bizarelly re-implemnting list(range(x)).
For clarity I reproduce the original function you gave and then I present what the change I am suggesting is
My change Does it now become clear what I am suggesting? My new function can be used as a 1-for-1 replacement for the old function, no code of the system needs changed as the default value provided to the new variable ensures semantically identical operation without changing any further code. Yet it is now unit testableBut now we can write a unit test like
So I've made the code unit testable, kept semantics completely identical and not had to worrty about any weird IO concerns that you have. No monkey patching, no weird file IO, no bizarelly re-implemnting list(range(x)).