[gobject-introspection: 1/2] Add utils.rmtree() which waits and tries again if a file is still in use
- From: Christoph Reiter <creiter src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gobject-introspection: 1/2] Add utils.rmtree() which waits and tries again if a file is still in use
- Date: Wed, 20 Jun 2018 11:07:46 +0000 (UTC)
commit 7c6adf533001e214e63d284a1a00fa254b29d7b9
Author: Christoph Reiter <reiter christoph gmail com>
Date: Wed Jun 20 08:08:03 2018 +0200
Add utils.rmtree() which waits and tries again if a file is still in use
On Windows the dumper cleanup regularely fails because the created .exe
is still in use by some process and shutil.rmtree() fails with:
OSError: [WinError 145] The directory is not empty
I'm not 100% sure what's the cause for this, but searching for similar issues
suggests that it might be Windows Defender scanning the newly created .exe
file and because it's so short lifed the scanning and deleting conflict.
This adds a helper which tries a few times and waits a bit before giving up.
A similar patch has been in MSYS2 for some time:
https://github.com/Alexpux/MINGW-packages/blob/d0c39af02a669e45272c713e912ee63b0dd94157/mingw-w64-gobject-introspection/0025-more-tolerant-rmtreeing.patch
giscanner/dumper.py | 5 ++---
giscanner/gdumpparser.py | 3 +--
giscanner/utils.py | 25 +++++++++++++++++++++++++
3 files changed, 28 insertions(+), 5 deletions(-)
---
diff --git a/giscanner/dumper.py b/giscanner/dumper.py
index 06737188..d6956da2 100644
--- a/giscanner/dumper.py
+++ b/giscanner/dumper.py
@@ -28,7 +28,6 @@ import os
import sys
import shlex
import subprocess
-import shutil
import tempfile
from distutils.errors import LinkError
@@ -171,14 +170,14 @@ class DumpCompiler(object):
introspection_obj = self._compile(c_path)
except CompilerError as e:
if not utils.have_debug_flag('save-temps'):
- shutil.rmtree(tmpdir)
+ utils.rmtree(tmpdir)
raise SystemExit('compilation of temporary binary failed:' + str(e))
try:
self._link(bin_path, introspection_obj)
except LinkerError as e:
if not utils.have_debug_flag('save-temps'):
- shutil.rmtree(tmpdir)
+ utils.rmtree(tmpdir)
raise SystemExit('linking of temporary binary failed: ' + str(e))
return IntrospectionBinary([bin_path], tmpdir)
diff --git a/giscanner/gdumpparser.py b/giscanner/gdumpparser.py
index bd4d233a..cd9d94d2 100644
--- a/giscanner/gdumpparser.py
+++ b/giscanner/gdumpparser.py
@@ -26,7 +26,6 @@ from __future__ import unicode_literals
import os
import sys
import tempfile
-import shutil
import subprocess
from xml.etree.cElementTree import parse
@@ -181,7 +180,7 @@ blob containing data gleaned from GObject's primitive introspection."""
return parse(out_path)
finally:
if not utils.have_debug_flag('save-temps'):
- shutil.rmtree(self._binary.tmpdir)
+ utils.rmtree(self._binary.tmpdir)
# Parser
diff --git a/giscanner/utils.py b/giscanner/utils.py
index 09132b2d..f6cd0b4f 100644
--- a/giscanner/utils.py
+++ b/giscanner/utils.py
@@ -27,6 +27,8 @@ import re
import os
import subprocess
import platform
+import shutil
+import time
_debugflags = None
@@ -291,3 +293,26 @@ def get_system_data_dirs():
xdg_data_dirs.append('/usr/share')
return xdg_data_dirs
+
+
+def rmtree(*args, **kwargs):
+ '''
+ A variant of shutil.rmtree() which waits and tries again in case one of
+ the files in the directory tree can't be deleted.
+
+ This can be the case if a file is still in use by some process,
+ for example a Virus scanner on Windows scanning .exe files when they are
+ created.
+ '''
+
+ tries = 3
+ for i in range(1, tries + 1):
+ try:
+ shutil.rmtree(*args, **kwargs)
+ except OSError:
+ if i == tries:
+ raise
+ time.sleep(i)
+ continue
+ else:
+ return
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]