diff options
-rw-r--r-- | coverage/backward.py | 5 | ||||
-rw-r--r-- | coverage/cmdline.py | 11 | ||||
-rw-r--r-- | coverage/collector.py | 21 | ||||
-rw-r--r-- | coverage/control.py | 3 | ||||
-rw-r--r-- | coverage/env.py | 21 | ||||
-rw-r--r-- | coverage/files.py | 5 | ||||
-rw-r--r-- | coverage/html.py | 8 | ||||
-rw-r--r-- | coverage/misc.py | 4 | ||||
-rw-r--r-- | coverage/phystokens.py | 4 | ||||
-rw-r--r-- | coverage/python.py | 7 | ||||
-rw-r--r-- | coverage/templite.py | 5 | ||||
-rw-r--r-- | tests/osinfo.py | 7 | ||||
-rw-r--r-- | tests/test_arcs.py | 11 | ||||
-rw-r--r-- | tests/test_concurrency.py | 12 | ||||
-rw-r--r-- | tests/test_config.py | 2 | ||||
-rw-r--r-- | tests/test_coverage.py | 5 | ||||
-rw-r--r-- | tests/test_html.py | 7 | ||||
-rw-r--r-- | tests/test_phystokens.py | 16 | ||||
-rw-r--r-- | tests/test_plugins.py | 14 | ||||
-rw-r--r-- | tests/test_process.py | 23 | ||||
-rw-r--r-- | tests/test_summary.py | 5 |
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't this great?�!" else: expected = "# Isn't this great?Ë!" 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. |