Commit f4f2b5ac authored by Stefan Behnel's avatar Stefan Behnel

error reporting: fix resource warning for unclosed file (in Py3.2+), cache...

error reporting: fix resource warning for unclosed file (in Py3.2+), cache source lines when we read them more than once
parent 7919aad8
...@@ -20,7 +20,7 @@ def context(position): ...@@ -20,7 +20,7 @@ def context(position):
assert not (isinstance(source, unicode) or isinstance(source, str)), ( assert not (isinstance(source, unicode) or isinstance(source, str)), (
"Please replace filename strings with Scanning.FileSourceDescriptor instances %r" % source) "Please replace filename strings with Scanning.FileSourceDescriptor instances %r" % source)
try: try:
F = list(source.get_lines()) F = source.get_lines()
except UnicodeDecodeError: except UnicodeDecodeError:
# file has an encoding problem # file has an encoding problem
s = u"[unprintable code]\n" s = u"[unprintable code]\n"
......
...@@ -172,13 +172,34 @@ class FileSourceDescriptor(SourceDescriptor): ...@@ -172,13 +172,34 @@ class FileSourceDescriptor(SourceDescriptor):
self.filename = filename self.filename = filename
self.set_file_type_from_name(filename) self.set_file_type_from_name(filename)
self._cmp_name = filename self._cmp_name = filename
self._lines = {}
def get_lines(self, encoding=None, error_handling=None): def get_lines(self, encoding=None, error_handling=None):
return Utils.open_source_file( # we cache the lines only the second time this is called, in
# order to save memory when they are only used once
key = (encoding, error_handling)
try:
lines = self._lines[key]
if lines is not None:
return lines
except KeyError:
pass
f = Utils.open_source_file(
self.filename, encoding=encoding, self.filename, encoding=encoding,
error_handling=error_handling, error_handling=error_handling,
# newline normalisation is costly before Py2.6 # newline normalisation is costly before Py2.6
require_normalised_newlines=False) require_normalised_newlines=False)
try:
lines = list(f)
finally:
f.close()
if key in self._lines:
self._lines[key] = lines
else:
# do not cache the first access, but remember that we
# already read it once
self._lines[key] = None
return lines
def get_description(self): def get_description(self):
return self.path_description return self.path_description
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment