Skip to content

Commit

Permalink
Merge pull request #454 from k-bu/master
Browse files Browse the repository at this point in the history
fix #295: temporary egg files are created as read only and can't be deleted with shutil on Windows.
  • Loading branch information
reinout committed Jun 19, 2018
2 parents 722dfc1 + b96efa4 commit f564ad7
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
15 changes: 8 additions & 7 deletions src/zc/buildout/easy_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import sys
import tempfile
import zc.buildout
import zc.buildout.rmtree
import warnings

try:
Expand Down Expand Up @@ -453,7 +454,7 @@ def _call_easy_install(self, spec, dest, dist):
return result

finally:
shutil.rmtree(tmp)
zc.buildout.rmtree.rmtree(tmp)

def _obtain(self, requirement, source=None):
# initialize out index for this project:
Expand Down Expand Up @@ -574,7 +575,7 @@ def _get_dist(self, requirement, ws):

finally:
if tmp != self._download_cache:
shutil.rmtree(tmp)
zc.buildout.rmtree.rmtree(tmp)

self._env_rescan_dest()
dist = self._env.best_match(requirement, ws)
Expand Down Expand Up @@ -804,11 +805,11 @@ def build(self, spec, build_ext):

return [dist.location for dist in dists]
finally:
shutil.rmtree(build_tmp)
zc.buildout.rmtree.rmtree(build_tmp)

finally:
if tmp != self._download_cache:
shutil.rmtree(tmp)
zc.buildout.rmtree.rmtree(tmp)

def _fix_file_links(self, links):
for link in links:
Expand Down Expand Up @@ -945,7 +946,7 @@ def build(spec, dest, build_ext,
def _rm(*paths):
for path in paths:
if os.path.isdir(path):
shutil.rmtree(path)
zc.buildout.rmtree.rmtree(path)
elif os.path.exists(path):
os.remove(path)

Expand Down Expand Up @@ -1051,7 +1052,7 @@ def restore_old_setup():
)).encode())

tmp3 = tempfile.mkdtemp('build', dir=dest)
undo.append(lambda : shutil.rmtree(tmp3))
undo.append(lambda : zc.buildout.rmtree.rmtree(tmp3))

args = [executable, tsetup, '-q', 'develop', '-mN', '-d', tmp3]

Expand Down Expand Up @@ -1738,5 +1739,5 @@ def _move_to_eggs_dir_and_compile(dist, dest):
assert newdist is not None # newloc above is missing our dist?!
finally:
# Remember that temporary directories must be removed
shutil.rmtree(tmp_dest)
zc.buildout.rmtree.rmtree(tmp_dest)
return newdist
19 changes: 15 additions & 4 deletions src/zc/buildout/rmtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
import shutil
import os
import doctest
import time

def rmtree (path):
"""
A variant of shutil.rmtree which tries hard to be successful
A variant of shutil.rmtree which tries hard to be successful.
On windows shutil.rmtree aborts when it tries to delete a
read only file.
This tries to chmod the file to writeable and retries before giving up.
read only file or a file which is still handled by another
process (e.g. antivirus scanner). This tries to chmod the
file to writeable and retries 10 times before giving up.
>>> from tempfile import mkdtemp
Expand Down Expand Up @@ -55,7 +57,16 @@ def rmtree (path):
"""
def retry_writeable (func, path, exc):
os.chmod (path, 384) # 0600
func (path)
for i in range(10):
try:
func (path)
break
except OSError:
time.sleep(0.1)
else:
# tried 10 times without success, thus
# finally rethrow the last exception
raise

shutil.rmtree (path, onerror = retry_writeable)

Expand Down

0 comments on commit f564ad7

Please sign in to comment.