diff -r 10cf594ace4b Lib/trace.py --- a/Lib/trace.py Sun Jun 29 17:44:05 2014 -0400 +++ b/Lib/trace.py Sun Jun 29 20:58:21 2014 -0400 @@ -58,6 +58,7 @@ import gc import dis import pickle +import io from warnings import warn as _warn try: from time import monotonic as _time @@ -327,10 +328,13 @@ else: lnotab = {} if lnotab: - source = linecache.getlines(filename) + source = linecache.getlines(filename, sys.modules[modulename].__dict__) coverpath = os.path.join(dir, modulename + ".cover") - with open(filename, 'rb') as fp: - encoding, _ = tokenize.detect_encoding(fp.readline) + try: + with open(filename, 'rb') as fp: + encoding, _ = tokenize.detect_encoding(fp.readline) + except IOError: + encoding = None n_hits, n_lines = self.write_results_file(coverpath, source, lnotab, count, encoding) if summary and n_lines: @@ -416,34 +420,45 @@ line that contains only a string or a part of a triple-quoted string. """ + with open(filename, encoding=encoding) as f: + return _find_strings_stream(f) + +def _find_strings_stream(stream): d = {} # If the first token is a string, then it's the module docstring. # Add this special case so that the test in the loop passes. prev_ttype = token.INDENT - with open(filename, encoding=encoding) as f: - tok = tokenize.generate_tokens(f.readline) - for ttype, tstr, start, end, line in tok: - if ttype == token.STRING: - if prev_ttype == token.INDENT: - sline, scol = start - eline, ecol = end - for i in range(sline, eline + 1): - d[i] = 1 - prev_ttype = ttype + tok = tokenize.generate_tokens(stream.readline) + for ttype, tstr, start, end, line in tok: + if ttype == token.STRING: + if prev_ttype == token.INDENT: + sline, scol = start + eline, ecol = end + for i in range(sline, eline + 1): + d[i] = 1 + prev_ttype = ttype return d def _find_executable_linenos(filename): """Return dict where keys are line numbers in the line number table.""" - try: - with tokenize.open(filename) as f: - prog = f.read() - encoding = f.encoding - except OSError as err: - print(("Not printing coverage data for %r: %s" - % (filename, err)), file=sys.stderr) - return {} - code = compile(prog, filename, "exec") - strs = _find_strings(filename, encoding) + modulename = fullmodname(filename) + module = sys.modules[modulename] + loader = getattr(module, '__loader__', None) + if loader: + code = loader.get_code(modulename) + source = loader.get_source(modulename) + strs = _find_strings_stream(io.StringIO(source)) + else: + try: + with tokenize.open(filename) as f: + prog = f.read() + encoding = f.encoding + except OSError as err: + print(("Not printing coverage data for %r: %s" + % (filename, err)), file=sys.stderr) + return {} + code = compile(prog, filename, "exec") + strs = _find_strings(filename, encoding) return _find_lines(code, strs) class Trace: