summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.rst9
-rw-r--r--coverage/phystokens.py2
-rw-r--r--tests/test_phystokens.py18
3 files changed, 23 insertions, 6 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 082fda6d..a599352a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -6,6 +6,15 @@ Change history for Coverage.py
==============================
+Version 4.0.2, in progress
+--------------------------
+
+- Fixed an unusual edge case of detecting source encodings, described in
+ `issue 443`_.
+
+.. _issue 443: https://bitbucket.org/ned/coveragepy/issues/443/coverage-gets-confused-when-encoding
+
+
Version 4.0.2 --- 4 November 2015
---------------------------------
diff --git a/coverage/phystokens.py b/coverage/phystokens.py
index f5bd0bc9..b34b1c3b 100644
--- a/coverage/phystokens.py
+++ b/coverage/phystokens.py
@@ -153,7 +153,7 @@ class CachedTokenizer(object):
generate_tokens = CachedTokenizer().generate_tokens
-COOKIE_RE = re.compile(r"^\s*#.*coding[:=]\s*([-\w.]+)", flags=re.MULTILINE)
+COOKIE_RE = re.compile(r"^[ \t]*#.*coding[:=][ \t]*([-\w.]+)", flags=re.MULTILINE)
@contract(source='bytes')
def _source_encoding_py2(source):
diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py
index 7bdece72..e28fb176 100644
--- a/tests/test_phystokens.py
+++ b/tests/test_phystokens.py
@@ -102,6 +102,7 @@ ENCODING_DECLARATION_SOURCES = [
b"#!/usr/bin/python\n# vim: set fileencoding=cp850:\n",
b"# This Python file uses this encoding: cp850\n",
b"# This file uses a different encoding:\n# coding: cp850\n",
+ b"\n# coding=cp850\n\n",
]
class SourceEncodingTest(CoverageTest):
@@ -126,11 +127,6 @@ class SourceEncodingTest(CoverageTest):
source = b'def parse(src, encoding=None):\n pass'
self.assertEqual(source_encoding(source), DEF_ENCODING)
- def test_detect_source_encoding_on_second_line(self):
- # A coding declaration should be found despite a first blank line.
- source = b"\n# coding=cp850\n\n"
- self.assertEqual(source_encoding(source), 'cp850')
-
def test_dont_detect_source_encoding_on_third_line(self):
# A coding declaration doesn't count on the third line.
source = b"\n\n# coding=cp850\n\n"
@@ -160,6 +156,18 @@ class NeuterEncodingDeclarationTest(CoverageTest):
for source in ENCODING_DECLARATION_SOURCES:
neutered = neuter_encoding_declaration(source.decode("ascii"))
neutered = neutered.encode("ascii")
+
+ # The neutered source should have the same number of lines.
+ source_lines = source.splitlines()
+ neutered_lines = neutered.splitlines()
+ self.assertEqual(len(source_lines), len(neutered_lines))
+
+ # Only one of the lines should be different.
+ lines_different = sum(
+ int(nline != sline) for nline, sline in zip(neutered_lines, source_lines)
+ )
+ self.assertEqual(lines_different, 1)
+
self.assertEqual(
source_encoding(neutered),
DEF_ENCODING,