Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File editing in python

Tags:

python

svn

I wrote a little python program as a personal utility to help me with some refactoring. It's similar to unix replace, except it supports regular expressions and operates on all files in a directory and (optionally) all subdirectories.

The problem is I'm not replacing in place. I'm opening files, passing the contents into memory, and then overwriting the file, like so:

file = open('path/to/file','r')
in_string = file.read()
file.close()
# ...
#Processing logic
# ...
file = open('path/to/file','w')
file.write(out_string)
file.close()

Besides the obvious performance/memory concerns, which are legitimate, but not so much a problem for my use, there's another drawback to this method. SVN freaks out. I can do some copy and paste workarounds after the fact to fix the checksum error that svn throws on a commit, but it makes the utility pointless.

Is there a better way to do this? I'm guessing that if I were editing the file in place there wouldn't be any sort of problem. How do I go about that?

like image 914
David Berger Avatar asked Dec 09 '25 12:12

David Berger


2 Answers

I suspect the problem is that you are in fact editing wrong files. Subversion should never raise any errors about check sums when you are just modifying your tracked files -- independently of how you are modifying them.

Maybe you are accidentally editing files in the .svn directory? In .svn/text-base, Subversion stores copies of your files using the same name plus the extension .svn-base, make sure that you are not editing those!

like image 128
Ferdinand Beyer Avatar answered Dec 11 '25 01:12

Ferdinand Beyer


What do you mean by "SVN freaks out"?

Anyway, the way vi/emacs/etc works is as follows:

f = open("/path/to/.file.tmp", "w")
f.write(out_string)
f.close()
os.rename("/path/to/.file.tmp", "/path/to/file")

(ok, there's actually an "fsync" in there... But I don't know off hand how to do that in Python)

The reason it does that copy is to ensure that, if the system dies half way through writing the new file, the old one is still there... And the 'rename' operation is defined as being atomic, so it will either work (you get 100% of the new file) or not work (you get 100% of the old file) -- you'll never be left with a half-file.

like image 40
David Wolever Avatar answered Dec 11 '25 01:12

David Wolever



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!