On Windows, if you pass an existing file object in append mode to a subprocess, the subprocess does not really append to the file:
- A file object with
Hello World
content is passed to the subprocess - The content is erased
- The subprocess writes to the file
- The expected output does not contain
Hello World
Demo:
import subprocess, time, pathlib, sys
print(f'Caller {sys.platform=} {sys.version=}')
pathlib.Path('sub.py').write_text("""import sys, time
time.sleep(1)
print(f'Callee {sys.stdout.buffer.mode=}')""")
file = pathlib.Path('dummy.txt')
file.write_text('Hello World')
popen = subprocess.Popen([sys.executable, 'sub.py'], stdout=file.open(mode='a'))
file.write_text('')
time.sleep(2)
print(file.read_text())
I get the expected output
Caller sys.platform='linux' sys.version='3.8.6'
Callee sys.stdout.buffer.mode='wb'
and the unexpected bad output
Caller sys.platform='win32' sys.version='3.8.6'
NULNULNULNULNULNULNULNULNULNULNULCallee sys.stdout.buffer.mode='wb'
Is this a Python bug, and how can I make this work on Windows?
Note that the expected output is given on Windows if the file is opened in the subprocess via sys.stdout = open('dummy.txt', 'a')
. So it is definitely a subprocess thing.
There is a question and another question on SO hinting at the problem without a solution for me.