diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 13cb855403..97ff509668 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -22,7 +22,8 @@ from docutils.frontend import OptionParser
from docutils.readers.doctree import Reader as DoctreeReader
from sphinx import package_dir, __version__
-from sphinx.util import SEP, os_path, relative_uri, ensuredir, ustrftime
+from sphinx.util import SEP, os_path, relative_uri, ensuredir, \
+ movefile, ustrftime
from sphinx.search import js_index
from sphinx.builders import Builder, ENV_PICKLE_FILENAME
from sphinx.highlighting import PygmentsBridge
@@ -566,7 +567,7 @@ class StandaloneHTMLBuilder(Builder):
self.indexer.dump(f, self.indexer_format)
finally:
f.close()
- os.rename(searchindexfn + '.tmp', searchindexfn)
+ movefile(searchindexfn + '.tmp', searchindexfn)
self.info('done')
self.info(bold('dumping object inventory... '), nonl=True)
diff --git a/sphinx/environment.py b/sphinx/environment.py
index d280433262..57aef67466 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -43,8 +43,8 @@ from docutils.transforms import Transform
from docutils.transforms.parts import ContentsFilter
from sphinx import addnodes
-from sphinx.util import get_matching_docs, SEP, ustrftime, docname_join, \
- FilenameUniqDict
+from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
+ docname_join, FilenameUniqDict
from sphinx.directives import additional_xref_types
default_settings = {
@@ -219,7 +219,7 @@ class BuildEnvironment:
pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
finally:
picklefile.close()
- os.rename(filename + '.tmp', filename)
+ movefile(filename + '.tmp', filename)
# reset attributes
self.config.values = values
self.set_warnfunc(warnfunc)
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 4aacf67bdf..08e619ee9f 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -361,3 +361,12 @@ def force_decode(string, encoding):
# last resort -- can't fail
string = string.decode('latin1')
return string
+
+
+def movefile(source, dest):
+ # move a file, removing the destination if it exists
+ if os.path.exists(dest):
+ os.unlink(dest)
+ except OSError:
+ pass
+ os.rename(source, dest)