[Spambayes-checkins] SF.net SVN: spambayes: [3165] trunk/spambayes/spambayes/storage.py
montanaro at users.sourceforge.net
montanaro at users.sourceforge.net
Mon Oct 22 04:42:47 CEST 2007
Revision: 3165
http://spambayes.svn.sourceforge.net/spambayes/?rev=3165&view=rev
Author: montanaro
Date: 2007-10-21 19:42:47 -0700 (Sun, 21 Oct 2007)
Log Message:
-----------
Isolate the code to safely write pickles so it can be used elsewhere in the
system. From Dave Abrahams (SF patch 1816240).
Modified Paths:
--------------
trunk/spambayes/spambayes/storage.py
Modified: trunk/spambayes/spambayes/storage.py
===================================================================
--- trunk/spambayes/spambayes/storage.py 2007-10-22 02:29:03 UTC (rev 3164)
+++ trunk/spambayes/spambayes/storage.py 2007-10-22 02:42:47 UTC (rev 3165)
@@ -85,6 +85,36 @@
NO_UPDATEPROBS = False # Probabilities will not be autoupdated with training
UPDATEPROBS = True # Probabilities will be autoupdated with training
+def safe_pickle(filename, value, protocol=0):
+ '''Store value as a pickle without creating corruption'''
+
+ # Be as defensive as possible. Always keep a safe copy.
+ tmp = filename + '.tmp'
+ fp = None
+ try:
+ fp = open(tmp, 'wb')
+ pickle.dump(value, fp, protocol)
+ fp.close()
+ except IOError, e:
+ if options["globals", "verbose"]:
+ print >> sys.stderr, 'Failed update: ' + str(e)
+ if fp is not None:
+ os.remove(tmp)
+ raise
+ try:
+ # With *nix we can just rename, and (as long as permissions
+ # are correct) the old file will vanish. With win32, this
+ # won't work - the Python help says that there may not be
+ # a way to do an atomic replace, so we rename the old one,
+ # put the new one there, and then delete the old one. If
+ # something goes wrong, there is at least a copy of the old
+ # one.
+ os.rename(tmp, filename)
+ except OSError:
+ os.rename(filename, filename + '.bak')
+ os.rename(tmp, filename)
+ os.remove(filename + '.bak')
+
class PickledClassifier(classifier.Classifier):
'''Classifier object persisted in a pickle'''
@@ -141,31 +171,7 @@
if options["globals", "verbose"]:
print >> sys.stderr, 'Persisting',self.db_name,'as a pickle'
- # Be as defensive as possible; keep always a safe copy.
- tmp = self.db_name + '.tmp'
- try:
- fp = open(tmp, 'wb')
- pickle.dump(self, fp, PICKLE_TYPE)
- fp.close()
- except IOError, e:
- if options["globals", "verbose"]:
- print >> sys.stderr, 'Failed update: ' + str(e)
- if fp is not None:
- os.remove(tmp)
- raise
- try:
- # With *nix we can just rename, and (as long as permissions
- # are correct) the old file will vanish. With win32, this
- # won't work - the Python help says that there may not be
- # a way to do an atomic replace, so we rename the old one,
- # put the new one there, and then delete the old one. If
- # something goes wrong, there is at least a copy of the old
- # one.
- os.rename(tmp, self.db_name)
- except OSError:
- os.rename(self.db_name, self.db_name + '.bak')
- os.rename(tmp, self.db_name)
- os.remove(self.db_name + '.bak')
+ safe_pickle(self.db_name, self, PICKLE_TYPE)
def close(self):
# we keep no resources open - nothing to do
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Spambayes-checkins
mailing list