diff options
-rw-r--r-- | coverage/codeunit.py | 5 | ||||
-rw-r--r-- | coverage/files.py | 11 | ||||
-rw-r--r-- | igor.py | 25 | ||||
-rw-r--r-- | tests/test_codeunit.py | 4 | ||||
-rw-r--r-- | tests/test_files.py | 26 |
5 files changed, 59 insertions, 12 deletions
diff --git a/coverage/codeunit.py b/coverage/codeunit.py index f34967e5..09b86fe6 100644 --- a/coverage/codeunit.py +++ b/coverage/codeunit.py @@ -4,7 +4,7 @@ import os import sys from coverage.backward import string_class, unicode_class -from coverage.files import get_python_source, get_zip_data +from coverage.files import get_python_source, get_zip_bytes from coverage.misc import CoverageException, NoSource from coverage.parser import PythonParser from coverage.phystokens import source_token_lines, source_encoding @@ -165,6 +165,7 @@ class PythonCodeUnit(CodeUnit): if sys.version_info < (3, 0): encoding = source_encoding(self._source) self._source = self._source.decode(encoding, "replace") + assert isinstance(self._source, unicode_class) return self._source def get_parser(self, exclude=None): @@ -206,7 +207,7 @@ class PythonCodeUnit(CodeUnit): try_filename = base + try_ext if os.path.exists(try_filename): return try_filename, None - source = get_zip_data(try_filename) + source = get_zip_bytes(try_filename) if source: return try_filename, source raise NoSource("No source for code: '%s'" % filename) diff --git a/coverage/files.py b/coverage/files.py index 1400b6eb..c2d7153d 100644 --- a/coverage/files.py +++ b/coverage/files.py @@ -3,7 +3,7 @@ import fnmatch, os, os.path, re, sys import ntpath, posixpath -from coverage.backward import to_string, open_python_source +from coverage.backward import open_python_source from coverage.misc import CoverageException, join_regex @@ -58,7 +58,7 @@ def get_python_source(filename): return f.read() # Maybe it's in a zip file? - source = get_zip_data(filename) + source = get_zip_bytes(filename) if source is not None: return source @@ -68,10 +68,10 @@ def get_python_source(filename): ) -def get_zip_data(filename): +def get_zip_bytes(filename): """Get data from `filename` if it is a zip file path. - Returns the string data read from the zip file, or None if no zip file + Returns the bytestring data read from the zip file, or None if no zip file could be found or `filename` isn't in it. The data returned will be an empty string if the file is empty. @@ -89,7 +89,8 @@ def get_zip_data(filename): data = zi.get_data(parts[1]) except IOError: continue - return to_string(data) + assert isinstance(data, bytes) + return data return None @@ -1,3 +1,4 @@ +# coding: utf8 """Helper for building, testing, and linting coverage.py. To get portability, all these operations are written in Python here instead @@ -12,6 +13,7 @@ import os import platform import socket import sys +import textwrap import warnings import zipfile @@ -138,7 +140,30 @@ def do_test_with_tracer(tracer, *noseargs): def do_zip_mods(): """Build the zipmods.zip file.""" zf = zipfile.ZipFile("tests/zipmods.zip", "w") + + # Take one file from disk. zf.write("tests/covmodzip1.py", "covmodzip1.py") + + # The others will be various encodings. + source = textwrap.dedent(u"""\ + # coding: {encoding} + text = u"{text}" + ords = {ords} + assert [ord(c) for c in text] == ords + print(u"All OK with {encoding}") + """) + details = [ + (u'utf8', u'ⓗⓔⓛⓛⓞ, ⓦⓞⓡⓛⓓ'), + (u'gb2312', u'你好,世界'), + (u'hebrew', u'שלום, עולם'), + (u'shift_jis', u'こんにちは世界'), + ] + for encoding, text in details: + filename = 'encoded_{0}.py'.format(encoding) + ords = [ord(c) for c in text] + source_text = source.format(encoding=encoding, text=text, ords=ords) + zf.writestr(filename, source_text.encode(encoding)) + zf.close() def do_install_egg(): diff --git a/tests/test_codeunit.py b/tests/test_codeunit.py index b5571d3a..b90ac2e8 100644 --- a/tests/test_codeunit.py +++ b/tests/test_codeunit.py @@ -109,5 +109,5 @@ class CodeUnitTest(CoverageTest): self.assert_doesnt_exist(egg1.__file__) cu = code_unit_factory([egg1, egg1.egg1], FileLocator()) - self.assertEqual(cu[0].source(), "") - self.assertEqual(cu[1].source().split("\n")[0], "# My egg file!") + self.assertEqual(cu[0].source(), u"") + self.assertEqual(cu[1].source().split("\n")[0], u"# My egg file!") diff --git a/tests/test_files.py b/tests/test_files.py index 00142ac2..62d3e320 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -1,11 +1,13 @@ """Tests for files.py""" -import os, os.path +import os +import os.path +import sys from coverage.files import ( - FileLocator, TreeMatcher, FnmatchMatcher, ModuleMatcher + FileLocator, TreeMatcher, FnmatchMatcher, ModuleMatcher, PathAliases, + find_python_files, abs_file, get_zip_bytes ) -from coverage.files import PathAliases, find_python_files, abs_file from coverage.misc import CoverageException from tests.coveragetest import CoverageTest @@ -247,3 +249,21 @@ class FindPythonFilesTest(CoverageTest): "sub/ssub/__init__.py", "sub/ssub/s.py", "sub/windows.pyw", ]) + + +class GetZipBytesTest(CoverageTest): + """Tests of `get_zip_bytes`.""" + + run_in_temp_dir = False + + def test_get_encoded_zip_files(self): + # See igor.py, do_zipmods, for the text of these files. + zip_file = "tests/zipmods.zip" + sys.path.append(zip_file) # So we can import the files. + for encoding in ["utf8", "gb2312", "hebrew", "shift_jis"]: + filename = zip_file + "/encoded_" + encoding + ".py" + zip_data = get_zip_bytes(filename) + zip_text = zip_data.decode(encoding) + self.assertIn('All OK', zip_text) + # Run the code to see that we really got it encoded properly. + __import__("encoded_"+encoding) |