summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMats Wichmann <mats@linux.com>2020-05-29 17:14:49 (GMT)
committerMats Wichmann <mats@linux.com>2020-05-29 17:14:49 (GMT)
commit46810dae9a306c934f89ad6b3f37cc82eb2026a5 (patch)
tree425c5968063f587ee3b24b438a6402f65bb60d61
parent47b761fa3f9e24419db48393ca9d6064f7b5d21c (diff)
downloadSCons-46810dae9a306c934f89ad6b3f37cc82eb2026a5.zip
SCons-46810dae9a306c934f89ad6b3f37cc82eb2026a5.tar.gz
SCons-46810dae9a306c934f89ad6b3f37cc82eb2026a5.tar.bz2
Close scons logfiles on completion
Files written to in logging operations could remain unclosed: more modern Pythons grumble about this; given the type of Python build, could emit ResourceWarning messages which cause tests to fail. Close by registering calls with atexit. Affects Trace, cache debug, taskmastertrace, configure. Signed-off-by: Mats Wichmann <mats@linux.com>
-rwxr-xr-xCHANGES.txt2
-rw-r--r--SCons/CacheDir.py7
-rw-r--r--SCons/Debug.py34
-rw-r--r--SCons/SConf.py10
-rw-r--r--SCons/Script/Main.py5
5 files changed, 47 insertions, 11 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index ecf3255..88b8d6f 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -150,6 +150,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
- ParseFlags should not modify the user's passed in dict in case it's
a compound data structure (e.g. values are lists) (issue #3665)
- In Py3 classes no longer need to be listed as deriving from object.
+ - Close various logfiles (trace, cache, taskmastertrace, configure)
+ when done using atexit calls.
diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py
index 5ecbc6f..3bb6671 100644
--- a/SCons/CacheDir.py
+++ b/SCons/CacheDir.py
@@ -27,13 +27,14 @@ __doc__ = """
CacheDir support
"""
+import atexit
import json
import os
import stat
import sys
-import SCons
import SCons.Action
+import SCons.Errors
import SCons.Warnings
cache_enabled = True
@@ -202,7 +203,11 @@ class CacheDir:
if cache_debug == '-':
self.debugFP = sys.stdout
elif cache_debug:
+ def debug_cleanup(debugFP):
+ debugFP.close()
+
self.debugFP = open(cache_debug, 'w')
+ atexit.register(debug_cleanup, self.debugFP)
else:
self.debugFP = None
self.current_cache_debug = cache_debug
diff --git a/SCons/Debug.py b/SCons/Debug.py
index 706b4c4..10cd2f5 100644
--- a/SCons/Debug.py
+++ b/SCons/Debug.py
@@ -33,6 +33,7 @@ caller_trace()
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import atexit
import os
import sys
import time
@@ -66,7 +67,7 @@ def string_to_classes(s):
def fetchLoggedInstances(classes="*"):
classnames = string_to_classes(classes)
return [(cn, len(tracked_classes[cn])) for cn in classnames]
-
+
def countLoggedInstances(classes, file=sys.stdout):
for classname in string_to_classes(classes):
file.write("%s: %d\n" % (classname, len(tracked_classes[classname])))
@@ -201,22 +202,39 @@ if sys.platform == 'win32':
TraceDefault = 'con'
else:
TraceDefault = '/dev/tty'
-
-TimeStampDefault = None
+TimeStampDefault = False
StartTime = time.time()
PreviousTime = StartTime
-def Trace(msg, file=None, mode='w', tstamp=None):
- """Write a trace message to a file. Whenever a file is specified,
- it becomes the default for the next call to Trace()."""
+def Trace(msg, filename=None, mode='w', tstamp=False):
+ """Write a trace message.
+
+ Write messages when debugging which do not interfere with stdout.
+ Useful in tests, which monitor stdout and would break with
+ unexpected output. Trace messages can go to the console (which is
+ opened as a file), or to a disk file; the file argument persists
+ across calls unless overridden.
+
+ Args:
+ filename: file to write trace message to. If omitted,
+ write to the previous trace file (default: console).
+ mode: file open mode (default: 'w')
+ tstamp: write relative timestamps with trace. Outputs time since
+ scons was started, and time since last trace (default: False)
+
+ """
global TraceDefault
global TimeStampDefault
global PreviousTime
+
+ def traace_cleanup(traceFP):
+ traceFP.close()
+
if file is None:
file = TraceDefault
else:
TraceDefault = file
- if tstamp is None:
+ if not tstamp:
tstamp = TimeStampDefault
else:
TimeStampDefault = tstamp
@@ -225,6 +243,7 @@ def Trace(msg, file=None, mode='w', tstamp=None):
except KeyError:
try:
fp = TraceFP[file] = open(file, mode)
+ atexit.register(trace_cleanup, fp)
except TypeError:
# Assume we were passed an open file pointer.
fp = file
@@ -234,7 +253,6 @@ def Trace(msg, file=None, mode='w', tstamp=None):
PreviousTime = now
fp.write(msg)
fp.flush()
- fp.close()
# Local Variables:
# tab-width:4
diff --git a/SCons/SConf.py b/SCons/SConf.py
index 42bfa8c..efa9e5b 100644
--- a/SCons/SConf.py
+++ b/SCons/SConf.py
@@ -37,6 +37,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.compat
+import atexit
import io
import os
import re
@@ -750,11 +751,16 @@ class SConfBase:
_ac_config_logs[self.logfile] = None
log_mode = "w"
fp = open(str(self.logfile), log_mode)
+
+ def conflog_cleanup(logf):
+ logf.close()
+
+ atexit.register(conflog_cleanup, fp)
self.logstream = SCons.Util.Unbuffered(fp)
# logfile may stay in a build directory, so we tell
- # the build system not to override it with a eventually
+ # the build system not to override it with an eventually
# existing file with the same name in the source directory
- self.logfile.dir.add_ignore( [self.logfile] )
+ self.logfile.dir.add_ignore([self.logfile])
tb = traceback.extract_stack()[-3-self.depth]
old_fs_dir = SConfFS.getcwd()
diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py
index ac29712..d7b07a2 100644
--- a/SCons/Script/Main.py
+++ b/SCons/Script/Main.py
@@ -40,6 +40,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.compat
+import atexit
import importlib.util
import os
import re
@@ -1262,10 +1263,14 @@ def _build_targets(fs, options, targets, target_top):
"""Leave the order of dependencies alone."""
return dependencies
+ def tmtrace_cleanup(tfile):
+ tfile.close()
+
if options.taskmastertrace_file == '-':
tmtrace = sys.stdout
elif options.taskmastertrace_file:
tmtrace = open(options.taskmastertrace_file, 'w')
+ atexit.register(tmtrace_cleanup, tmtrace)
else:
tmtrace = None
taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, order, tmtrace)