diff options
Diffstat (limited to 'coverage/codeunit.py')
-rw-r--r-- | coverage/codeunit.py | 44 |
1 files changed, 17 insertions, 27 deletions
diff --git a/coverage/codeunit.py b/coverage/codeunit.py index 207383e0..f34967e5 100644 --- a/coverage/codeunit.py +++ b/coverage/codeunit.py @@ -1,10 +1,12 @@ """Code unit (module) handling for Coverage.""" import os +import sys -from coverage.backward import open_python_source, string_class +from coverage.backward import string_class, unicode_class +from coverage.files import get_python_source, get_zip_data from coverage.misc import CoverageException, NoSource -from coverage.parser import CodeParser, PythonParser +from coverage.parser import PythonParser from coverage.phystokens import source_token_lines, source_encoding @@ -85,7 +87,7 @@ class CodeUnit(object): self._source = None def __repr__(self): - return "<CodeUnit name=%r filename=%r>" % (self.name, self.filename) + return "<{self.__class__.__name__} name={self.name!r} filename={self.filename!r}>".format(self=self) def _adjust_filename(self, f): # TODO: This shouldn't be in the base class, right? @@ -124,29 +126,12 @@ class CodeUnit(object): return root.replace('\\', '_').replace('/', '_').replace('.', '_') def source(self): - if self._source is None: - self._source = self.get_source() - return self._source - - def get_source(self): - """Return the source code, as a string.""" - if os.path.exists(self.filename): - # A regular text file: open it. - with open_python_source(self.filename) as f: - return f.read() - - # Maybe it's in a zip file? - source = self.file_locator.get_zip_data(self.filename) - if source is not None: - return source - - # Couldn't find source. - raise CoverageException( - "No source for code '%s'." % self.filename - ) + """Return the source for the code, a Unicode string.""" + return unicode_class("???") def source_token_lines(self): """Return the 'tokenized' text for the code.""" + # A generic implementation, each line is one "txt" token. for line in self.source().splitlines(): yield [('txt', line)] @@ -174,6 +159,14 @@ class PythonCodeUnit(CodeUnit): fname = fname[:-9] + ".py" return fname + def source(self): + if self._source is None: + self._source = get_python_source(self.filename) + if sys.version_info < (3, 0): + encoding = source_encoding(self._source) + self._source = self._source.decode(encoding, "replace") + return self._source + def get_parser(self, exclude=None): actual_filename, source = self._find_source(self.filename) return PythonParser( @@ -213,7 +206,7 @@ class PythonCodeUnit(CodeUnit): try_filename = base + try_ext if os.path.exists(try_filename): return try_filename, None - source = self.file_locator.get_zip_data(try_filename) + source = get_zip_data(try_filename) if source: return try_filename, source raise NoSource("No source for code: '%s'" % filename) @@ -240,6 +233,3 @@ class PythonCodeUnit(CodeUnit): def source_token_lines(self): return source_token_lines(self.source()) - - def source_encoding(self): - return source_encoding(self.source()) |