Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Various fixes intended to ensure that opened files are closed explict…
Browse files Browse the repository at this point in the history
…ly where

necessary in order to avoid ResourceWarnings.
  • Loading branch information
embray committed Mar 7, 2018
1 parent 3750eaa commit af86e5c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
17 changes: 13 additions & 4 deletions src/sage/doctest/control.py
Expand Up @@ -366,20 +366,29 @@ def __init__(self, options, args):
# write to the actual standard output, regardless of
# redirections.
if options.serial:
real_stdout = os.fdopen(os.dup(sys.stdout.fileno()), "a")
self._real_stdout = os.fdopen(os.dup(sys.stdout.fileno()), "w")
self._close_stdout = True
else:
# Parallel mode: no special tricks needed
real_stdout = sys.stdout
self._real_stdout = sys.stdout
self._close_stdout = False

if self.logfile is None:
self.logger = real_stdout
self.logger = self._real_stdout
else:
self.logger = Logger(real_stdout, self.logfile)
self.logger = Logger(self._real_stdout, self.logfile)

self.stats = {}
self.load_stats(options.stats_path)
self._init_warn_long()

def __del__(self):
if getattr(self, 'logfile', None) is not None:
self.logfile.close()

if getattr(self, '_close_stdout', False):
self._real_stdout.close()

def _init_warn_long(self):
"""
Pick a suitable default for the ``--warn-long`` option if not specified.
Expand Down
24 changes: 22 additions & 2 deletions src/sage/doctest/forker.py
Expand Up @@ -249,16 +249,20 @@ def __init__(self, outfile=None, infile=None):
"""
if infile is None:
self.infile = open(os.devnull)
self._close_infile = True
else:
self.infile = infile
self._close_infile = False
if outfile is None:
self.outfile = tempfile.TemporaryFile()
self._close_outfile = True
else:
self.outfile = outfile
self._close_outfile = False
self.spoofing = False
self.real_stdin = os.fdopen(os.dup(sys.stdin.fileno()), "r")
self.real_stdout = os.fdopen(os.dup(sys.stdout.fileno()), "a")
self.real_stderr = os.fdopen(os.dup(sys.stderr.fileno()), "a")
self.real_stdout = os.fdopen(os.dup(sys.stdout.fileno()), "w")
self.real_stderr = os.fdopen(os.dup(sys.stderr.fileno()), "w")
self.position = 0

def __del__(self):
Expand All @@ -276,6 +280,12 @@ def __del__(self):
Not spoofed!
"""
self.stop_spoofing()
if self._close_infile:
self.infile.close()
if self._close_outfile:
self.outfile.close()
for stream in ('stdin', 'stdout', 'stderr'):
getattr(self, 'real_' + stream).close()

def start_spoofing(self):
r"""
Expand Down Expand Up @@ -1974,6 +1984,10 @@ def run(self):
task(self.options, self.outtmpfile, msgpipe, self.result_queue)
finally:
msgpipe.close()
# Note: This closes the tempfile in the child process, but in the
# parent process self.outtmpfile will not be closed yet, and can
# still be accessed in save_result_output
self.outtmpfile.close()

def start(self):
"""
Expand Down Expand Up @@ -2072,6 +2086,11 @@ def save_result_output(self):
['cputime', 'err', 'failures', 'optionals', 'walltime']
sage: len(W.output) > 0
True
.. NOTE::
This method is called from the parent process, not from the
subprocess.
"""
from six.moves.queue import Empty
try:
Expand Down Expand Up @@ -2135,6 +2154,7 @@ def kill(self):
sage: W.is_alive()
False
"""

if self.rmessages is not None:
os.close(self.rmessages)
self.rmessages = None
Expand Down

0 comments on commit af86e5c

Please sign in to comment.