summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/backward.py5
-rw-r--r--coverage/cmdline.py11
-rw-r--r--coverage/collector.py21
-rw-r--r--coverage/control.py3
-rw-r--r--coverage/env.py21
-rw-r--r--coverage/files.py5
-rw-r--r--coverage/html.py8
-rw-r--r--coverage/misc.py4
-rw-r--r--coverage/phystokens.py4
-rw-r--r--coverage/python.py7
-rw-r--r--coverage/templite.py5
-rw-r--r--tests/osinfo.py7
-rw-r--r--tests/test_arcs.py11
-rw-r--r--tests/test_concurrency.py12
-rw-r--r--tests/test_config.py2
-rw-r--r--tests/test_coverage.py5
-rw-r--r--tests/test_html.py7
-rw-r--r--tests/test_phystokens.py16
-rw-r--r--tests/test_plugins.py14
-rw-r--r--tests/test_process.py23
-rw-r--r--tests/test_summary.py5
21 files changed, 114 insertions, 82 deletions
diff --git a/coverage/backward.py b/coverage/backward.py
index 9a3c9f7c..5a323659 100644
--- a/coverage/backward.py
+++ b/coverage/backward.py
@@ -7,6 +7,9 @@
import sys
+from coverage import env
+
+
# Pythons 2 and 3 differ on where to get StringIO.
try:
from cStringIO import StringIO
@@ -63,7 +66,7 @@ else:
# Python 3.x is picky about bytes and strings, so provide methods to
# get them right, and make them no-ops in 2.x
-if sys.version_info >= (3, 0):
+if env.PY3:
def to_bytes(s):
"""Convert string `s` to bytes."""
return s.encode('utf8')
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index 816c5455..f0160845 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -1,7 +1,12 @@
"""Command-line support for Coverage."""
-import glob, optparse, os, sys, traceback
+import glob
+import optparse
+import os
+import sys
+import traceback
+from coverage import env
from coverage.execfile import run_python_file, run_python_module
from coverage.misc import CoverageException, ExceptionDuringRun, NoSource
from coverage.debug import info_formatter
@@ -597,7 +602,7 @@ def unshell_list(s):
"""Turn a command-line argument into a list."""
if not s:
return None
- if sys.platform == 'win32':
+ if env.WINDOWS:
# When running coverage as coverage.exe, some of the behavior
# of the shell is emulated: wildcards are expanded into a list of
# filenames. So you have to single-quote patterns on the command
@@ -609,7 +614,7 @@ def unshell_list(s):
def unglob_args(args):
"""Interpret shell wildcards for platforms that need it."""
- if sys.platform == 'win32':
+ if env.WINDOWS:
globbed = []
for arg in args:
if '?' in arg or '*' in arg:
diff --git a/coverage/collector.py b/coverage/collector.py
index 39acd7bd..ded6d920 100644
--- a/coverage/collector.py
+++ b/coverage/collector.py
@@ -2,6 +2,7 @@
import os, sys
+from coverage import env
from coverage.misc import CoverageException
from coverage.pytracer import PyTracer
@@ -11,23 +12,18 @@ try:
except ImportError:
# Couldn't import the C extension, maybe it isn't built.
if os.getenv('COVERAGE_TEST_TRACER') == 'c':
- # During testing, we use the COVERAGE_TEST_TRACER env var to indicate
- # that we've fiddled with the environment to test this fallback code.
- # If we thought we had a C tracer, but couldn't import it, then exit
- # quickly and clearly instead of dribbling confusing errors. I'm using
- # sys.exit here instead of an exception because an exception here
- # causes all sorts of other noise in unittest.
+ # During testing, we use the COVERAGE_TEST_TRACER environment variable
+ # to indicate that we've fiddled with the environment to test this
+ # fallback code. If we thought we had a C tracer, but couldn't import
+ # it, then exit quickly and clearly instead of dribbling confusing
+ # errors. I'm using sys.exit here instead of an exception because an
+ # exception here causes all sorts of other noise in unittest.
sys.stderr.write(
"*** COVERAGE_TEST_TRACER is 'c' but can't import CTracer!\n"
)
sys.exit(1)
CTracer = None
-try:
- import __pypy__
-except ImportError:
- __pypy__ = None
-
class Collector(object):
"""Collects trace data.
@@ -141,7 +137,8 @@ class Collector(object):
# A cache of the results from should_trace, the decision about whether
# to trace execution in a file. A dict of filename to (filename or
# None).
- if __pypy__ is not None:
+ if env.PYPY:
+ import __pypy__ # pylint: disable=import-error
# Alex Gaynor said:
# should_trace_cache is a strictly growing key: once a key is in
# it, it never changes. Further, the keys used to access it are
diff --git a/coverage/control.py b/coverage/control.py
index 16a92971..36687fe5 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -8,6 +8,7 @@ import random
import socket
import sys
+from coverage import env
from coverage.annotate import AnnotateReporter
from coverage.backward import string_class, iitems
from coverage.collector import Collector
@@ -323,7 +324,7 @@ class Coverage(object):
if os.path.exists(py_filename):
# Found a .py file, use that.
return py_filename
- if sys.platform == "win32":
+ if env.WINDOWS:
# On Windows, it could be a .pyw file.
pyw_filename = py_filename + "w"
if os.path.exists(pyw_filename):
diff --git a/coverage/env.py b/coverage/env.py
new file mode 100644
index 00000000..85ffa5ff
--- /dev/null
+++ b/coverage/env.py
@@ -0,0 +1,21 @@
+"""Determine facts about the environment."""
+
+import os
+import sys
+
+# Operating systems.
+WINDOWS = sys.platform == "win32"
+LINUX = sys.platform == "linux2"
+
+# Python implementations.
+PYPY = '__pypy__' in sys.builtin_module_names
+
+# Python versions.
+PY2 = sys.version_info < (3, 0)
+PY3 = sys.version_info >= (3, 0)
+
+# Coverage.py specifics.
+# Are we using the C-implemented trace function?
+C_TRACER = os.getenv('COVERAGE_TEST_TRACER', 'c') == 'c'
+# Are we coverage-measuring ourselves?
+METACOV = os.getenv('COVERAGE_COVERAGE', '') != ''
diff --git a/coverage/files.py b/coverage/files.py
index 15ccabce..f7fc9693 100644
--- a/coverage/files.py
+++ b/coverage/files.py
@@ -8,6 +8,7 @@ import posixpath
import re
import sys
+from coverage import env
from coverage.misc import CoverageException, join_regex
@@ -54,7 +55,7 @@ class FileLocator(object):
return self.canonical_filename_cache[filename]
-if sys.platform == 'win32':
+if env.WINDOWS:
def actual_path(path):
"""Get the actual path of `path`, including the correct case."""
@@ -188,7 +189,7 @@ class FnmatchMatcher(object):
# take care of that ourselves.
fnpats = (fnmatch.translate(p) for p in pats)
fnpats = (p.replace(r"\/", r"[\\/]") for p in fnpats)
- if sys.platform == 'win32':
+ if env.WINDOWS:
# Windows is also case-insensitive. BTW: the regex docs say that
# flags like (?i) have to be at the beginning, but fnmatch puts
# them at the end, and having two there seems to work fine.
diff --git a/coverage/html.py b/coverage/html.py
index ec151b42..2a9e0d11 100644
--- a/coverage/html.py
+++ b/coverage/html.py
@@ -2,9 +2,13 @@
from __future__ import unicode_literals
-import json, os, re, shutil, sys
+import json
+import os
+import re
+import shutil
import coverage
+from coverage import env
from coverage.backward import iitems
from coverage.misc import CoverageException, Hasher
from coverage.report import Reporter
@@ -68,7 +72,7 @@ class HtmlReporter(Reporter):
super(HtmlReporter, self).__init__(cov, config)
self.directory = None
title = self.config.html_title
- if sys.version_info < (3, 0):
+ if env.PY2:
title = title.decode("utf8")
self.template_globals = {
'escape': escape,
diff --git a/coverage/misc.py b/coverage/misc.py
index 924199ef..875d904a 100644
--- a/coverage/misc.py
+++ b/coverage/misc.py
@@ -4,8 +4,8 @@ import errno
import hashlib
import inspect
import os
-import sys
+from coverage import env
from coverage.backward import string_class, to_bytes
@@ -154,7 +154,7 @@ def overrides(obj, method_name, base_class):
# Python 2/3 compatibility: Python 2 returns an instancemethod object, the
# function is the .im_func attribute. Python 3 returns a plain function
# object already.
- if sys.version_info < (3, 0):
+ if env.PY2:
klass_func = klass_func.im_func
base_func = base_func.im_func
diff --git a/coverage/phystokens.py b/coverage/phystokens.py
index c52e28ae..b3b08704 100644
--- a/coverage/phystokens.py
+++ b/coverage/phystokens.py
@@ -3,10 +3,10 @@
import codecs
import keyword
import re
-import sys
import token
import tokenize
+from coverage import env
from coverage.backward import iternext
@@ -258,7 +258,7 @@ def _source_encoding_py3(source):
return tokenize.detect_encoding(readline)[0]
-if sys.version_info >= (3, 0):
+if env.PY3:
source_encoding = _source_encoding_py3
else:
source_encoding = _source_encoding_py2
diff --git a/coverage/python.py b/coverage/python.py
index 977497a7..53da5615 100644
--- a/coverage/python.py
+++ b/coverage/python.py
@@ -5,6 +5,7 @@ import sys
import tokenize
import zipimport
+from coverage import env
from coverage.backward import unicode_class
from coverage.codeunit import CodeUnit
from coverage.misc import NoSource, join_regex
@@ -31,7 +32,7 @@ def read_python_source(filename):
def get_python_source(filename):
"""Return the source code, as a str."""
base, ext = os.path.splitext(filename)
- if ext == ".py" and sys.platform == "win32":
+ if ext == ".py" and env.WINDOWS:
exts = [".py", ".pyw"]
else:
exts = [ext]
@@ -46,7 +47,7 @@ def get_python_source(filename):
# Maybe it's in a zip file?
source = get_zip_bytes(try_filename)
if source is not None:
- if sys.version_info >= (3, 0):
+ if env.PY3:
source = source.decode(source_encoding(source))
break
else:
@@ -148,7 +149,7 @@ class PythonCodeUnit(CodeUnit):
def source(self):
if self._source is None:
self._source = get_python_source(self.filename)
- if sys.version_info < (3, 0):
+ if env.PY2:
encoding = source_encoding(self._source)
self._source = self._source.decode(encoding, "replace")
assert isinstance(self._source, unicode_class)
diff --git a/coverage/templite.py b/coverage/templite.py
index c42e380c..20b0e504 100644
--- a/coverage/templite.py
+++ b/coverage/templite.py
@@ -3,7 +3,8 @@
# Coincidentally named the same as http://code.activestate.com/recipes/496702/
import re
-import sys
+
+from coverage import env
class TempliteSyntaxError(ValueError):
@@ -122,7 +123,7 @@ class Templite(object):
code.add_line("result = []")
code.add_line("append_result = result.append")
code.add_line("extend_result = result.extend")
- if sys.version_info < (3, 0):
+ if env.PY2:
code.add_line("to_str = unicode")
else:
code.add_line("to_str = str")
diff --git a/tests/osinfo.py b/tests/osinfo.py
index a123123c..0b86ef54 100644
--- a/tests/osinfo.py
+++ b/tests/osinfo.py
@@ -1,8 +1,9 @@
"""OS information for testing."""
-import sys
+from coverage import env
-if sys.platform == 'win32':
+
+if env.WINDOWS:
# Windows implementation
def process_ram():
"""How much RAM is this process using? (Windows)"""
@@ -34,7 +35,7 @@ if sys.platform == 'win32':
return 0
return mem_struct.PrivateUsage
-elif sys.platform == 'linux2':
+elif env.LINUX:
# Linux implementation
import os
diff --git a/tests/test_arcs.py b/tests/test_arcs.py
index 3856a2cf..92dac5de 100644
--- a/tests/test_arcs.py
+++ b/tests/test_arcs.py
@@ -1,8 +1,9 @@
"""Tests for Coverage.py's arc measurement."""
-import sys
from tests.coveragetest import CoverageTest
+from coverage import env
+
class SimpleArcTest(CoverageTest):
"""Tests for Coverage.py's arc measurement."""
@@ -247,7 +248,7 @@ class LoopArcTest(CoverageTest):
)
# With "while True", 2.x thinks it's computation, 3.x thinks it's
# constant.
- if sys.version_info >= (3, 0):
+ if env.PY3:
arcz = ".1 12 23 34 45 36 63 57 7."
else:
arcz = ".1 12 23 27 34 45 36 62 57 7."
@@ -306,7 +307,7 @@ class LoopArcTest(CoverageTest):
)
def test_confusing_for_loop_bug_175(self):
- if sys.version_info >= (3, 0):
+ if env.PY3:
# Py3 counts the list comp as a separate code object.
arcz = ".1 .2 2-2 12 23 34 45 53 3."
else:
@@ -319,7 +320,7 @@ class LoopArcTest(CoverageTest):
y = tup[1]
""",
arcz=arcz, arcz_missing="", arcz_unpredicted="")
- if sys.version_info >= (3, 0):
+ if env.PY3:
arcz = ".1 12 .2 2-2 23 34 42 2."
else:
arcz = ".1 12 23 34 42 2."
@@ -504,7 +505,7 @@ class ExceptionArcTest(CoverageTest):
# Run this test only on Py2 for now. I hope to fix it on Py3
# eventually...
- if sys.version_info < (3, 0):
+ if env.PY2:
# "except Exception as e" is crucial here.
def test_bug_212(self):
self.check_coverage("""\
diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py
index 02163d2f..77b8c0ec 100644
--- a/tests/test_concurrency.py
+++ b/tests/test_concurrency.py
@@ -1,8 +1,11 @@
"""Tests for concurrency libraries."""
-import os, os.path, sys, threading
+import os
+import os.path
+import threading
import coverage
+from coverage import env
from tests.coveragetest import CoverageTest
@@ -24,9 +27,6 @@ try:
except ImportError:
greenlet = None
-# Are we running with the C tracer or not?
-C_TRACER = os.getenv('COVERAGE_TEST_TRACER', 'c') == 'c'
-
def line_count(s):
"""How many non-blank non-comment lines are in `s`?"""
@@ -78,7 +78,7 @@ class ConcurrencyTest(CoverageTest):
""".format(LIMIT=LIMIT)
# Import the things to use threads.
- if sys.version_info < (3, 0):
+ if env.PY2:
THREAD = """\
import threading
import Queue as queue
@@ -135,7 +135,7 @@ class ConcurrencyTest(CoverageTest):
"the module isn't installed.\n" % concurrency
)
self.assertEqual(out, expected_out)
- elif C_TRACER or concurrency == "thread":
+ elif env.C_TRACER or concurrency == "thread":
# We can fully measure the code if we are using the C tracer, which
# can support all the concurrency, or if we are using threads.
if expected_out is None:
diff --git a/tests/test_config.py b/tests/test_config.py
index 65586846..450c94fc 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -86,7 +86,7 @@ class ConfigTest(CoverageTest):
self.set_environ("COVERAGE_FILE", "fromenv.dat")
cov = coverage.coverage()
self.assertEqual(cov.config.data_file, "fromenv.dat")
- # But the constructor args override the env var.
+ # But the constructor arguments override the environment variable.
cov = coverage.coverage(data_file="fromarg.dat")
self.assertEqual(cov.config.data_file, "fromarg.dat")
diff --git a/tests/test_coverage.py b/tests/test_coverage.py
index b69fd986..21f9154f 100644
--- a/tests/test_coverage.py
+++ b/tests/test_coverage.py
@@ -1,9 +1,10 @@
"""Tests for Coverage."""
# http://nedbatchelder.com/code/coverage
-import sys
import coverage
+from coverage import env
from coverage.misc import CoverageException
+
from tests.coveragetest import CoverageTest
@@ -305,7 +306,7 @@ class SimpleStatementTest(CoverageTest):
""",
[1,2,3,6,9], "")
- if sys.version_info < (3, 0): # Print statement is gone in Py3k.
+ if env.PY2: # Print statement is gone in Py3k.
def test_print(self):
self.check_coverage("""\
print "hello, world!"
diff --git a/tests/test_html.py b/tests/test_html.py
index b0cb839e..b4189af2 100644
--- a/tests/test_html.py
+++ b/tests/test_html.py
@@ -1,8 +1,11 @@
# -*- coding: utf-8 -*-
"""Tests that HTML generation is awesome."""
-import os.path, re, sys
+import os.path
+import re
+
import coverage
+from coverage import env
import coverage.html
from coverage.misc import CoverageException, NotPython, NoSource
@@ -303,7 +306,7 @@ class HtmlWithUnparsableFilesTest(HtmlTestHelpers, CoverageTest):
cov.html_report()
html_report = self.get_html_report_content("sub/not_ascii.py")
- if sys.version_info < (3, 0):
+ if env.PY2:
expected = "# Isn&#39;t this great?&#65533;!"
else:
expected = "# Isn&#39;t this great?&#203;!"
diff --git a/tests/test_phystokens.py b/tests/test_phystokens.py
index bbd956ea..b8986a80 100644
--- a/tests/test_phystokens.py
+++ b/tests/test_phystokens.py
@@ -2,13 +2,14 @@
import os
import re
-import sys
from nose.plugins.skip import SkipTest
-from tests.coveragetest import CoverageTest
+from coverage import env
from coverage.phystokens import source_token_lines, source_encoding
+from tests.coveragetest import CoverageTest
+
SIMPLE = """\
# yay!
@@ -87,7 +88,7 @@ class PhysTokensTest(CoverageTest):
# The default encoding is different in Python 2 and Python 3.
-if sys.version_info >= (3, 0):
+if env.PY3:
DEF_ENCODING = "utf-8"
else:
DEF_ENCODING = "ascii"
@@ -110,11 +111,10 @@ class SourceEncodingTest(CoverageTest):
self.assertEqual(source_encoding(source), 'utf-8')
def test_detect_source_encoding_not_in_comment(self):
- if '__pypy__' in sys.builtin_module_names:
- if sys.version_info > (3, 0):
- # PyPy3 gets this case wrong. Not sure what I can do about it,
- # so skip the test.
- raise SkipTest
+ if env.PYPY and env.PY3:
+ # PyPy3 gets this case wrong. Not sure what I can do about it,
+ # so skip the test.
+ raise SkipTest
# Should not detect anything here
source = b'def parse(src, encoding=None):\n pass'
self.assertEqual(source_encoding(source), DEF_ENCODING)
diff --git a/tests/test_plugins.py b/tests/test_plugins.py
index a1710c5f..f3b8d580 100644
--- a/tests/test_plugins.py
+++ b/tests/test_plugins.py
@@ -1,20 +1,13 @@
"""Tests for plugins."""
-import os
-import sys
-
-from nose.plugins.skip import SkipTest
-
import coverage
+from coverage import env
from coverage.control import Plugins
import coverage.plugin
from tests.coveragetest import CoverageTest
-# Are we running with the C tracer or not?
-C_TRACER = os.getenv('COVERAGE_TEST_TRACER', 'c') == 'c'
-
class FakeConfig(object):
"""A fake config for use in tests."""
@@ -142,14 +135,11 @@ class PluginTest(CoverageTest):
cov.stop()
-if not C_TRACER:
+if not env.C_TRACER:
class FileTracerTest(CoverageTest):
"""Tests of plugins that implement file_tracer."""
def test_plugin1(self):
- if sys.platform == 'win32':
- raise SkipTest("Plugin stuff is jank on windows.. fixing soon...")
-
self.make_file("simple.py", """\
import try_xyz
a = 1
diff --git a/tests/test_process.py b/tests/test_process.py
index 569618ee..aa179c68 100644
--- a/tests/test_process.py
+++ b/tests/test_process.py
@@ -1,18 +1,19 @@
"""Tests for process behavior of coverage.py."""
-import glob, os, sys, textwrap
+import glob
+import os
+import sys
+import textwrap
+
from nose.plugins.skip import SkipTest
+
import coverage
+from coverage import env
from tests.coveragetest import CoverageTest
here = os.path.dirname(__file__)
-# Determine what kind of tests we are running, because some of these tests don't
-# work in certain situations.
-C_TRACER = os.getenv('COVERAGE_TEST_TRACER', 'c') == 'c'
-METACOV = os.getenv('COVERAGE_COVERAGE', '') != ''
-
class ProcessTest(CoverageTest):
"""Tests of the per-process behavior of coverage.py."""
@@ -273,7 +274,7 @@ class ProcessTest(CoverageTest):
# same traceback.
status, out = self.run_command_status("coverage run throw.py")
out2 = self.run_command("python throw.py")
- if '__pypy__' in sys.builtin_module_names:
+ if env.PYPY:
# Pypy has an extra frame in the traceback for some reason
lines2 = out2.splitlines()
out2 = "".join(l+"\n" for l in lines2 if "toplevel" not in l)
@@ -528,9 +529,9 @@ class ProcessTest(CoverageTest):
self.assertIn("Trace function changed", out)
- if sys.version_info >= (3, 0): # This only works on 3.x for now.
+ if env.PY3: # This only works on 3.x for now.
# It only works with the C tracer, and if we aren't measuring ourselves.
- if C_TRACER and not METACOV: # pragma: not covered
+ if env.C_TRACER and not env.METACOV: # pragma: not covered
def test_fullcoverage(self):
# fullcoverage is a trick to get stdlib modules measured from
# the very beginning of the process. Here we import os and
@@ -716,7 +717,7 @@ class ProcessStartupTest(ProcessCoverageMixin, CoverageTest):
"""Test that we can measure coverage in sub-processes."""
def test_subprocess_with_pth_files(self): # pragma: not covered
- if METACOV:
+ if env.METACOV:
raise SkipTest(
"Can't test sub-process pth file suppport during metacoverage"
)
@@ -766,7 +767,7 @@ class ProcessStartupWithSourceTest(ProcessCoverageMixin, CoverageTest):
def assert_pth_and_source_work_together(
self, dashm, package, source
): # pragma: not covered
- if METACOV:
+ if env.METACOV:
raise SkipTest(
"Can't test sub-process pth file suppport during metacoverage"
)
diff --git a/tests/test_summary.py b/tests/test_summary.py
index 77381186..f603a979 100644
--- a/tests/test_summary.py
+++ b/tests/test_summary.py
@@ -9,6 +9,7 @@ import sys
from nose.plugins.skip import SkipTest
import coverage
+from coverage import env
from coverage.backward import StringIO
from tests.coveragetest import CoverageTest
@@ -423,7 +424,7 @@ class SummaryTest(CoverageTest):
self.assertIn("TheCode", report)
self.assertNotIn("thecode", report)
- if sys.platform == 'win32':
+ if env.WINDOWS:
def test_pyw_files(self):
# https://bitbucket.org/ned/coveragepy/issue/261
self.make_file("start.pyw", """\
@@ -463,7 +464,7 @@ class SummaryTest(CoverageTest):
def test_missing_py_file_during_run(self):
# PyPy2 doesn't run bare .pyc files.
- if '__pypy__' in sys.builtin_module_names and sys.version_info < (3,):
+ if env.PYPY and env.PY2:
raise SkipTest("PyPy2 doesn't run bare .pyc files")
# Create two Python files.