summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/phystokens.py4
-rw-r--r--tests/coveragetest.py11
-rw-r--r--tests/test_collector.py1
-rw-r--r--tests/test_phystokens.py2
-rw-r--r--tests/test_testing.py29
5 files changed, 40 insertions, 7 deletions
diff --git a/coverage/phystokens.py b/coverage/phystokens.py
index 9281a447..2a91882d 100644
--- a/coverage/phystokens.py
+++ b/coverage/phystokens.py
@@ -177,7 +177,9 @@ def source_encoding(source):
raise SyntaxError("unknown encoding: " + encoding)
if bom_found:
- if codec.name != 'utf-8':
+ # codecs in 2.3 were raw tuples of functions, assume the best.
+ codec_name = getattr(codec, 'name', encoding)
+ if codec_name != 'utf-8':
# This behaviour mimics the Python interpreter
raise SyntaxError('encoding problem: utf-8')
encoding += '-sig'
diff --git a/tests/coveragetest.py b/tests/coveragetest.py
index 61df1259..1cefb6e3 100644
--- a/tests/coveragetest.py
+++ b/tests/coveragetest.py
@@ -1,7 +1,7 @@
"""Base test case class for coverage testing."""
import glob, imp, os, random, shlex, shutil, sys, tempfile, textwrap
-import atexit, collections
+import atexit
import coverage
from coverage.backward import sorted, StringIO # pylint: disable=W0622
@@ -499,9 +499,8 @@ class CoverageTest(TestCase):
self.test_method_made_any_files = False
# Map from class to info about how it ran.
- class_behaviors = collections.defaultdict(ClassBehavior)
+ class_behaviors = {}
- @classmethod
def report_on_class_behavior(cls):
"""Called at process exit to report on class behavior."""
for test_class, behavior in cls.class_behaviors.items():
@@ -526,10 +525,14 @@ class CoverageTest(TestCase):
where,
)
)
+ report_on_class_behavior = classmethod(report_on_class_behavior)
def class_behavior(self):
"""Get the ClassBehavior instance for this test."""
- return self.class_behaviors[self.__class__]
+ cls = self.__class__
+ if cls not in self.class_behaviors:
+ self.class_behaviors[cls] = self.ClassBehavior()
+ return self.class_behaviors[cls]
# When the process ends, find out about bad classes.
diff --git a/tests/test_collector.py b/tests/test_collector.py
index af3814f3..2714398a 100644
--- a/tests/test_collector.py
+++ b/tests/test_collector.py
@@ -4,6 +4,7 @@ import re
import coverage
from coverage.backward import StringIO
+from coverage.backward import set # pylint: disable=W0622
from tests.coveragetest import CoverageTest
diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py
index 261a2dbd..c1e51f1c 100644
--- a/tests/test_phystokens.py
+++ b/tests/test_phystokens.py
@@ -89,7 +89,7 @@ if sys.version_info < (3, 0):
if sys.version_info >= (2,4):
default_encoding = 'ascii'
else:
- default_encoding = 'iso8859-1'
+ default_encoding = 'iso-8859-1'
def test_detect_source_encoding(self):
# Various forms from http://www.python.org/dev/peps/pep-0263/
diff --git a/tests/test_testing.py b/tests/test_testing.py
index 06f2eb01..c56d8110 100644
--- a/tests/test_testing.py
+++ b/tests/test_testing.py
@@ -186,7 +186,34 @@ class CoverageTestTest(CoverageTest):
# "environment: COV_FOOBAR = XYZZY" or "COV_FOOBAR = XYZZY"
executable = [l for l in out if "executable:" in l][0]
executable = executable.split(":", 1)[1].strip()
- self.assertEqual(executable, sys.executable)
+ self.assertTrue(same_python_executable(executable, sys.executable))
environ = [l for l in out if "COV_FOOBAR" in l][0]
_, _, environ = rpartition(environ, ":")
self.assertEqual(environ.strip(), "COV_FOOBAR = XYZZY")
+
+
+def same_python_executable(e1, e2):
+ """Determine if `e1` and `e2` refer to the same Python executable.
+
+ Either path could include symbolic links. The two paths might not refer
+ to the exact same file, but if they are in the same directory and their
+ numeric suffixes aren't different, they are the same executable.
+
+ """
+ e1 = os.path.abspath(os.path.realpath(e1))
+ e2 = os.path.abspath(os.path.realpath(e2))
+
+ if os.path.dirname(e1) != os.path.dirname(e2):
+ return False
+
+ e1 = os.path.basename(e1)
+ e2 = os.path.basename(e2)
+
+ if e1 == "python" or e2 == "python" or e1 == e2:
+ # python and python2.3: ok
+ # python2.3 and python: ok
+ # python and python: ok
+ # python2.3 and python2.3: ok
+ return True
+
+ return False