summaryrefslogtreecommitdiff
path: root/coverage/files.py
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2014-12-28 10:09:09 -0500
committerNed Batchelder <ned@nedbatchelder.com>2014-12-28 10:09:09 -0500
commit93561c76f281656169e5c062d93bc30da95d8c94 (patch)
treeac5a824337730c134d9e822bc63aa2a4ce98414c /coverage/files.py
parent98a7b99ed97af0f5dfc6fc7f5219ad4b026a6dfc (diff)
downloadpython-coveragepy-git-93561c76f281656169e5c062d93bc30da95d8c94.tar.gz
Further consolidation of code reading Python source.
Diffstat (limited to 'coverage/files.py')
-rw-r--r--coverage/files.py38
1 files changed, 31 insertions, 7 deletions
diff --git a/coverage/files.py b/coverage/files.py
index 7f2431d3..8fa8067f 100644
--- a/coverage/files.py
+++ b/coverage/files.py
@@ -1,15 +1,16 @@
"""File wrangling."""
import fnmatch
+import ntpath
import os
import os.path
+import posixpath
import re
import sys
-import ntpath
-import posixpath
+import tokenize
from coverage.misc import CoverageException, NoSource, join_regex
-from coverage.phystokens import read_python_source, source_encoding
+from coverage.phystokens import source_encoding
class FileLocator(object):
@@ -55,6 +56,22 @@ class FileLocator(object):
return self.canonical_filename_cache[filename]
+def read_python_source(filename):
+ """Read the Python source text from `filename`.
+
+ Returns a str: unicode on Python 3, bytes on Python 2.
+
+ """
+ # Python 3.2 provides `tokenize.open`, the best way to open source files.
+ if sys.version_info >= (3, 2):
+ f = tokenize.open(filename)
+ else:
+ f = open(filename, "rU")
+
+ with f:
+ return f.read()
+
+
def get_python_source(filename):
"""Return the source code, as a str."""
base, ext = os.path.splitext(filename)
@@ -67,17 +84,24 @@ def get_python_source(filename):
try_filename = base + ext
if os.path.exists(try_filename):
# A regular text file: open it.
- return read_python_source(try_filename)
+ source = read_python_source(try_filename)
+ break
# Maybe it's in a zip file?
source = get_zip_bytes(try_filename)
if source is not None:
if sys.version_info >= (3, 0):
source = source.decode(source_encoding(source))
- return source
+ break
+ else:
+ # Couldn't find source.
+ raise NoSource("No source for code: %r." % filename)
+
+ # Python code should always end with a line with a newline.
+ if source and source[-1] != '\n':
+ source += '\n'
- # Couldn't find source.
- raise NoSource("No source for code: %r." % filename)
+ return source
def get_zip_bytes(filename):