diff options
author | Mats Wichmann <mats@linux.com> | 2020-05-29 17:14:49 (GMT) |
---|---|---|
committer | Mats Wichmann <mats@linux.com> | 2020-05-29 17:14:49 (GMT) |
commit | 46810dae9a306c934f89ad6b3f37cc82eb2026a5 (patch) | |
tree | 425c5968063f587ee3b24b438a6402f65bb60d61 | |
parent | 47b761fa3f9e24419db48393ca9d6064f7b5d21c (diff) | |
download | SCons-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-x | CHANGES.txt | 2 | ||||
-rw-r--r-- | SCons/CacheDir.py | 7 | ||||
-rw-r--r-- | SCons/Debug.py | 34 | ||||
-rw-r--r-- | SCons/SConf.py | 10 | ||||
-rw-r--r-- | SCons/Script/Main.py | 5 |
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) |