mbarkhau / bumpver

BumpVer: Automatic Versioning
https://github.com/mbarkhau/bumpver
MIT License
199 stars 36 forks source link

disable universal newlines #227

Closed melbaa closed 11 months ago

melbaa commented 1 year ago

Hello,

On windows, bumpver ends up always rewriting files with '\r\n' endings due to universal newlines in text mode. The PR disables this.

In more detail, universal newline text mode always returns '\n' to the code, but ends up translating it to '\r\n' on write. This causes bumpver to fail to preserve the original newlines.

mbarkhau commented 1 year ago

I would have expected the behaviour to be that the line endings are preserved as is in the file, so this is surprising to me. I'm not sure why this would be OS specific.

Do you have time to add a test case for this?

melbaa commented 1 year ago

No clue about the test, but I know how to show the newline translation from opening files in text mode with universal newlines.

Note how in both cases .read() returns '\n'.

import platform
assert platform.system() == 'Windows'
assert platform.python_version() == '3.10.1'

# only shows newlines being translated
import io
buffer = io.BytesIO(b'\r\n')
txt = io.TextIOWrapper(buffer)
assert txt.read() == '\n'
txt.write('\n')
txt.flush()
assert buffer.getvalue() == b'\r\n\r\n'

# this is similar to what happens in practice. a '\n' ends up a '\r\n' in the new file
import io
input_buffer = io.BytesIO(b'\n')
txt = io.TextIOWrapper(input_buffer)
assert txt.read() == '\n'

output_buffer = io.BytesIO()
txt = io.TextIOWrapper(output_buffer)
txt.write('\n')
txt.flush()
assert output_buffer.getvalue() == b'\r\n'

https://docs.python.org/3/glossary.html#term-universal-newlines https://docs.python.org/3/library/functions.html?highlight=newline#open

mbarkhau commented 11 months ago

I finally had some time to look at this and it appears you are correct.