How to deduplicate printing when redirected to file?

I use the end='\r' parameter in print to progressively print a process :

#process_printing.py
from time import perf_counter, sleep

print('Performing a long operation', end='\r')
start = perf_counter()
sleep(2)
stop = perf_counter()
elapsed_time = stop - start
print('Performing a long operation\t', f'[Done]  [{elapsed_time:.2f} s]')

It works as intended when stdout is the terminal:

$ python process_printing.py
Performing a long operation      [Done]  [2.00 s]

but the \r seems to have no effect when the output is redirected to a file:

$ python process_printing.py > log.txt

The content of log.txt is

Performing a long operation
Performing a long operation	 [Done]  [2.00 s]

I would like to get rid of the first line.
Can you explain what is happening and what alternative I could use that works both in the terminal and when redirected to a file?
Thank you

The usual solutiuon is to detect that stdout is not a tty and not do the progressing printing.

Only do the progressive printing when stdout is a tty.

You can do this with sys.stdout.isatty().

Note for this example you can use end='' so that the next print is appended to the output:

print('Performing a long operation', end='')
...
print(f'\t[Done]  [{elapsed_time:.2f} s]')

Thanks, that is a valid point. It avoids the repetition. But then you must flush the output in the first print:

print('Performing a long operation', end='', flush=True)

Alternatively, you can create a file with the desired output which does not have to be the same as what the script is sending to STDOUT/STDERR.

I thought of that, but it has drawbacks: I need an additional implementation for the file output, and I have to detect whether the output is being redirected to a file (cf How to deduplicate printing when rediredted to file? - #2 by barry-scott).

But that would not work if the code was updating more then once, for example with a progress percentage that is updating many times.

Fortunately, I I have to update pnce the process has finished.

Doing ‘this’ requires that the ‘tty’ terminal interpret ‘\r’ as ‘return to the beginning of the current line’ rather than ‘print a representation of’ \r’ or ignore it and also that the terminal either be in replace mode rather than insert (or non-erase overwrite) mode or that ‘\r’ erase rather than just move the cursor. ‘stream.isatty’ returns whether the stream is interactive. I interpret this as meaning that it is reasonable to print to an output stream and wait for a response on the corresponding input stream. The original paper and ink ttys returned and overwrote without erasing. IDLE currently does not return, though this could change.