On Thu, Nov 25, 2021, 6:06 AM Eyal Gruss <eyalgruss@gmail.com> wrote:
hi

first post here :)
i have a recurring use pattern where i want to save to file everything i print to the screen. i have used the standard logging module and found it too cumbersome for my simple use case, and i find myself changing all my print()'s to custom myprint()'s. i am interested in suggesting several additions to the standard libraries, as i feel this use case is common enough, important enough, and currently painful enough to justify such changes, and that all four of the following suggestions could be useful in a complementary fashion.

I'm not sure this is actually so common. How do you know it is? Also, it's not very painful to do, just occasionally annoying. If you want, you could write`_print = print` and then redefine print() as you want. I doubt that's good practice, but it works.

1. allow the print() "file" argument to take a list of streams (currently it can take only a single stream). e.g:

with open('output.txt', 'w') as f:
   print('hello', file=[sys.stdout, f])

this seems like the quickest and least resistant path for the user. need to decide how multiple streams will work with the flush argument.

This could very possibly be backwards-incompatible.

2. modify contextlib.redirect_stdout() to take an additional boolean argument which we can call tee/replicate/duplicate/clone etc. when True it will duplicate instead of just redirecting:

with open('output.txt', 'w') as f:
    with redirect_stdout(f, tee=True):  # will duplicate instead of redirecting
        print('hello')

or we could add a new context manager contextlib.copy_stdout() 

3. allow the contextlib.redirect_stdout() "new_target" argument to take a list of streams, or allow specifying multiple arguments for multiple streams. e.g:

with open('output.txt', 'w') as f:
    with redirect_stdout(sys.stdout, f):  # or redirect_stdout([sys.stdout, f])
        print('hello')

this has the benefit over the tee argument of allowing more than one additional stream, but you need to explicitly specify stdout. so would be nice to have both modifications.

4. add to the standard io library a new class which gives you the write interface of a single stream, but is a wrapper that will write to multiple streams:

with open('output.txt', 'w') as f:
   multi = io.OutputStreamCollection(sys.stdout, f)
   multi.write('hello\n')
   # or:  print('hello', file=multi)

Is this necessary if the other ideas are implemented?

this is similar to: https://stackoverflow.com/questions/9130755/wrapper-to-write-to-multiple-streams, and we need to decide about the rest of the stream methods.

eyal.
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-leave@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/7I55RDLFAV6A3K762TE3BW42WTTUE4ET/
Code of Conduct: http://python.org/psf/codeofconduct/


--
Finn (Mobile)