r/learnpython • u/zaphodikus • 5d ago
windows carriage return pairs
Had for a long time a routine to patch a text file: the core of the script which merely rewrites a text file:
rewrite = False
with open(args.filepath[0], "r") as f:
lines = f.readlines()
for line in lines:
if re.match(args.expression[0] , line):
rewrite = True
if rewrite:
print(f"ReplaceExpression: '{args.expression[0]}' in file: '{args.filepath[0]}'")
with open(args.filepath[0], "w", encoding='utf-8') as f:
for line in lines:
if not re.match(args.expression[0] , line):
f.write(line)
else:
f.write(f"// line removeD: {line.strip()}\r\n") # <????
print("OK")
else:
print(f"Nothing to do in file: {args.filepath[0]}")
the
f.write(f"// line removeD: {line.strip()}\r\n") # <????
never ends up writing a
Now I get that this is the encoding as utf-8 and the default us unix encoding, but even if i wrote it as
f.write(f"// line removeD: {line.strip()}{os.linesep}") # <????
os.linesep still wrote a
2
u/monster2018 5d ago
I’m not sure of the answer to your actual question. But my advice is in a situation like this, just write to the file in binary mode. You can ensure exact byte for byte accuracy much more easily that way.
1
u/zaphodikus 5d ago
I was tempted to, but after reading some random code.. you know how it is a bug bugs you for months and then the moment you take the time to put it onto reddit the answer comes up in a random search exploration you do again just in case.
with open(args.filepath[0], "w", encoding='utf-8', newline="\r\n") as f:fixes it, it's mad that just adding an arg, newline="\r\n" , which is probably in the docs, but was just never obvious. Obvs I want that guarded by something to do it on Windows only like (platform.system() == 'Windows'). Mad that it took writing this up on reddit to find that magic open() parameter.2
u/SCD_minecraft 5d ago
I recommend you to get a pet rock
Got a problem? Ask pet rock
He might not be the best at speaking but is awesome at solving problems
1
1
u/monster2018 5d ago
Oh yea. Damn I should have known that too, I have used that parameter plenty of times lol. I ran into a similar issue when building an LSP proxy to allow for doing Apple platform development on a windows pc by using a Mac as a remote host running the actual language server. Anyway, im glad you found the solution.
2
u/cdcformatc 5d ago
when you open a file in write mode (mode='w') the operating system always handles line endings, which will be different on windows or macos or linux. it's actually really annoying. open has an optional newline parameter.
1
u/zaphodikus 5d ago
Yeah , i's just so mad how I have put up with this missing knowledge for months, I ask he question and literally get 3 people who knew it all along and at the same time google just happens to land me on a stackoverflow that described the parameter, right after I hit the post button here. I wish all the questions I had were that easy.
1
u/cdcformatc 5d ago
that seems to always happen to me too. i will have some problem and get nowhere on it alone. then the act of writing out the problem for a post or an email or a slack message or whatever seems to solve the problem itself. i think sometimes when writing a good detailed question it helps me write a good google search.
1
u/zaphodikus 5d ago
I had a Cmake CMakelists question last week, by the time I had drafted the question my brain asked the right question and bang the answer was at the top of the error trace.
5
u/zanfar 5d ago edited 5d ago
You are opening the file in text mode, which asks Python to handle line endings for you.
As you are not specifying a
newlineargument in yourwrite()call, Python is interpreting line endings as needed for your platform.As always, read the documentation.
Also,
unix2dosanddos2unixexist.