NewlineTransformer splits process output on os.EOL (index.ts line 89):
const lines = data.split(newline); // newline = os.EOL
On Windows os.EOL is \r\n. Any Python output that uses bare \n line endings is never split into lines: the chunk is held in _lastLineData and only emitted on _flush, which runs after the stream's end handler has already resolved the run()/end() callback. The result is that the output is silently lost.
Normal print() happens to work because Python's text-mode stdout translates \n to \r\n on Windows, but bare \n (for example sys.stdout.buffer.write(b'...\n'), reconfigured stdout, or messages with embedded newlines) is dropped.
Reproduction (Windows):
const { NewlineTransformer } = require('python-shell');
const t = new NewlineTransformer();
t.setEncoding('utf8');
const out = [];
t.on('data', c => out.push(c.toString()));
t.on('end', () => console.log(out)); // ['hello\nworld\n'] instead of ['hello', 'world']
t.write(Buffer.from('hello\nworld\n'));
t.end();
Fix: split on /\r?\n/ so both \n and \r\n are handled. PR follows.
NewlineTransformersplits process output onos.EOL(index.tsline 89):On Windows
os.EOLis\r\n. Any Python output that uses bare\nline endings is never split into lines: the chunk is held in_lastLineDataand only emitted on_flush, which runs after the stream'sendhandler has already resolved therun()/end()callback. The result is that the output is silently lost.Normal
print()happens to work because Python's text-mode stdout translates\nto\r\non Windows, but bare\n(for examplesys.stdout.buffer.write(b'...\n'), reconfigured stdout, or messages with embedded newlines) is dropped.Reproduction (Windows):
Fix: split on
/\r?\n/so both\nand\r\nare handled. PR follows.