##// END OF EJS Templates
atomictempfile: make close() consistent with other file-like objects....
Greg Ward -
r15057:774da712 default
parent child Browse files
Show More
@@ -1492,7 +1492,7 b' class queue(object):'
1492 1492 n = repo.commit(message, user, ph.date, match=match,
1493 1493 force=True)
1494 1494 # only write patch after a successful commit
1495 patchf.rename()
1495 patchf.close()
1496 1496 self.applied.append(statusentry(n, patchfn))
1497 1497 except:
1498 1498 ctx = repo[cparents[0]]
@@ -195,7 +195,7 b' class fileit(object):'
195 195 return
196 196 f = self.opener(name, "w", atomictemp=True)
197 197 f.write(data)
198 f.rename()
198 f.close()
199 199 destfile = os.path.join(self.basedir, name)
200 200 os.chmod(destfile, mode)
201 201
@@ -90,7 +90,7 b' def write(repo):'
90 90 file = repo.opener('bookmarks', 'w', atomictemp=True)
91 91 for refspec, node in refs.iteritems():
92 92 file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
93 file.rename()
93 file.close()
94 94
95 95 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
96 96 try:
@@ -121,7 +121,7 b' def setcurrent(repo, mark):'
121 121 try:
122 122 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
123 123 file.write(encoding.fromlocal(mark))
124 file.rename()
124 file.close()
125 125 finally:
126 126 wlock.release()
127 127 repo._bookmarkcurrent = mark
@@ -453,7 +453,7 b' class dirstate(object):'
453 453 write(e)
454 454 write(f)
455 455 st.write(cs.getvalue())
456 st.rename()
456 st.close()
457 457 self._lastnormaltime = None
458 458 self._dirty = self._dirtypl = False
459 459
@@ -150,7 +150,7 b' def save_state(repo, state):'
150 150 for kind in state:
151 151 for node in state[kind]:
152 152 f.write("%s %s\n" % (kind, hex(node)))
153 f.rename()
153 f.close()
154 154 finally:
155 155 wlock.release()
156 156
@@ -521,7 +521,7 b' class localrepository(repo.repository):'
521 521 for label, nodes in branches.iteritems():
522 522 for node in nodes:
523 523 f.write("%s %s\n" % (hex(node), encoding.fromlocal(label)))
524 f.rename()
524 f.close()
525 525 except (IOError, OSError):
526 526 pass
527 527
@@ -946,9 +946,9 b' class revlog(object):'
946 946 e = self._io.packentry(self.index[i], self.node, self.version, i)
947 947 fp.write(e)
948 948
949 # if we don't call rename, the temp file will never replace the
949 # if we don't call close, the temp file will never replace the
950 950 # real index
951 fp.rename()
951 fp.close()
952 952
953 953 tr.replace(self.indexfile, trindex * self._io.size)
954 954 self._chunkclear()
@@ -445,7 +445,7 b' def simplemerge(ui, local, base, other, '
445 445 out.write(line)
446 446
447 447 if not opts.get('print'):
448 out.rename()
448 out.close()
449 449
450 450 if m3.conflicts:
451 451 if not opts.get('quiet'):
@@ -345,7 +345,7 b' class fncache(object):'
345 345 fp = self.opener('fncache', mode='wb', atomictemp=True)
346 346 for p in self.entries:
347 347 fp.write(encodedir(p) + '\n')
348 fp.rename()
348 fp.close()
349 349 self._dirty = False
350 350
351 351 def add(self, fn):
@@ -287,6 +287,6 b' def _writetagcache(ui, repo, heads, tagf'
287 287 cachefile.write("%s %s\n" % (hex(node), name))
288 288
289 289 try:
290 cachefile.rename()
290 cachefile.close()
291 291 except (OSError, IOError):
292 292 pass
@@ -745,11 +745,10 b' class atomictempfile(object):'
745 745 '''writeable file object that atomically updates a file
746 746
747 747 All writes will go to a temporary copy of the original file. Call
748 rename() when you are done writing, and atomictempfile will rename
749 the temporary copy to the original name, making the changes visible.
750
751 Unlike other file-like objects, close() discards your writes by
752 simply deleting the temporary file.
748 close() when you are done writing, and atomictempfile will rename
749 the temporary copy to the original name, making the changes
750 visible. If the object is destroyed without being closed, all your
751 writes are discarded.
753 752 '''
754 753 def __init__(self, name, mode='w+b', createmode=None):
755 754 self.__name = name # permanent name
@@ -761,12 +760,12 b' class atomictempfile(object):'
761 760 self.write = self._fp.write
762 761 self.fileno = self._fp.fileno
763 762
764 def rename(self):
763 def close(self):
765 764 if not self._fp.closed:
766 765 self._fp.close()
767 766 rename(self._tempname, localpath(self.__name))
768 767
769 def close(self):
768 def discard(self):
770 769 if not self._fp.closed:
771 770 try:
772 771 os.unlink(self._tempname)
@@ -776,7 +775,7 b' class atomictempfile(object):'
776 775
777 776 def __del__(self):
778 777 if safehasattr(self, '_fp'): # constructor actually did something
779 self.close()
778 self.discard()
780 779
781 780 def makedirs(name, mode=None):
782 781 """recursive directory creation with parent mode inheritance"""
@@ -12,22 +12,21 b' def test1_simple():'
12 12 assert basename in glob.glob('.foo-*')
13 13
14 14 file.write('argh\n')
15 file.rename()
15 file.close()
16 16
17 17 assert os.path.isfile('foo')
18 18 assert basename not in glob.glob('.foo-*')
19 19 print 'OK'
20 20
21 # close() removes the temp file but does not make the write
22 # permanent -- essentially discards your work (WTF?!)
23 def test2_close():
21 # discard() removes the temp file without making the write permanent
22 def test2_discard():
24 23 if os.path.exists('foo'):
25 24 os.remove('foo')
26 25 file = atomictempfile('foo')
27 26 (dir, basename) = os.path.split(file._tempname)
28 27
29 28 file.write('yo\n')
30 file.close()
29 file.discard()
31 30
32 31 assert not os.path.isfile('foo')
33 32 assert basename not in os.listdir('.')
@@ -45,5 +44,5 b' def test3_oops():'
45 44
46 45 if __name__ == '__main__':
47 46 test1_simple()
48 test2_close()
47 test2_discard()
49 48 test3_oops()
@@ -59,7 +59,7 b' def basic(repo):'
59 59 # because of inode change
60 60 f = scmutil.opener('.')('x', 'w', atomictemp=True)
61 61 f.write('b')
62 f.rename()
62 f.close()
63 63
64 64 repo.invalidate()
65 65 repo.cached
General Comments 0
You need to be logged in to leave comments. Login now