Index: Lib/trace.py =================================================================== --- Lib/trace.py (revision 86303) +++ Lib/trace.py (working copy) @@ -328,10 +328,13 @@ else: 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,35 +419,46 @@ line that contains only a string or a part of a triple-quoted string. """ + with open(filename, encoding=encoding) as f: + return find_docstrings(f) + +def find_docstrings(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 io.FileIO(filename, 'r') as file: - encoding, lines = tokenize.detect_encoding(file.readline) - with open(filename, "r", encoding=encoding) as f: - prog = f.read() - except IOError 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_docstrings(io.StringIO(source)) + else: + try: + with io.FileIO(filename, 'r') as file: + encoding, lines = tokenize.detect_encoding(file.readline) + with open(filename, "r", encoding=encoding) as f: + prog = f.read() + except IOError 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: