summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/codeunit.py5
-rw-r--r--coverage/files.py11
-rw-r--r--igor.py25
-rw-r--r--tests/test_codeunit.py4
-rw-r--r--tests/test_files.py26
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
diff --git a/igor.py b/igor.py
index 6a42df59..cf52ea4d 100644
--- a/igor.py
+++ b/igor.py
@@ -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)