diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | allkits.cmd | 8 | ||||
-rw-r--r-- | alltests.cmd | 8 | ||||
-rw-r--r-- | coverage/backward.py | 77 | ||||
-rw-r--r-- | coverage/cmdline.py | 8 | ||||
-rw-r--r-- | coverage/codeunit.py | 5 | ||||
-rw-r--r-- | coverage/control.py | 5 | ||||
-rw-r--r-- | coverage/data.py | 5 | ||||
-rw-r--r-- | coverage/execfile.py | 5 | ||||
-rw-r--r-- | coverage/files.py | 2 | ||||
-rw-r--r-- | coverage/parser.py | 18 | ||||
-rw-r--r-- | coverage/templite.py | 2 | ||||
-rw-r--r-- | mock.py | 2 | ||||
-rw-r--r-- | setup.py | 6 | ||||
-rw-r--r-- | test/backtest.py | 54 | ||||
-rw-r--r-- | test/coveragetest.py | 9 | ||||
-rw-r--r-- | test/farm/run/src/chdir.py | 4 | ||||
-rw-r--r-- | test/farm/run/src/showtrace.py | 13 | ||||
-rw-r--r-- | test/test_api.py | 4 | ||||
-rw-r--r-- | test/test_cmdline.py | 4 | ||||
-rw-r--r-- | test/test_codeunit.py | 2 | ||||
-rw-r--r-- | test/test_coverage.py | 5 | ||||
-rw-r--r-- | test/test_data.py | 6 | ||||
-rw-r--r-- | test/test_execfile.py | 4 | ||||
-rw-r--r-- | test/test_farm.py | 8 | ||||
-rw-r--r-- | three.cmd | 22 |
26 files changed, 171 insertions, 117 deletions
@@ -7,7 +7,7 @@ TEST_ZIP = test/zipmods.zip clean: python test/test_farm.py clean - -rm -rf build coverage.egg-info dist htmlcov three + -rm -rf build coverage.egg-info dist htmlcov -rm -f *.pyd */*.pyd -rm -f *.pyc */*.pyc */*/*.pyc */*/*/*.pyc */*/*/*/*.pyc */*/*/*/*/*.pyc -rm -f *.pyo */*.pyo */*/*.pyo */*/*/*.pyo */*/*/*/*.pyo */*/*/*/*/*.pyo diff --git a/allkits.cmd b/allkits.cmd index a83cac7b..fa75988e 100644 --- a/allkits.cmd +++ b/allkits.cmd @@ -13,13 +13,5 @@ python setup.py sdist --formats=gztar set TAR_OPTIONS=
@REM Py3k
-cd three
call \ned\bin\switchpy 31
python setup.py bdist_wininst
-
-set TAR_OPTIONS=--group=100
-python setup.py sdist --formats=gztar
-set TAR_OPTIONS=
-
-cd ..
-copy three\dist\*.* dist
diff --git a/alltests.cmd b/alltests.cmd index 9be4f4b3..c1d9e24b 100644 --- a/alltests.cmd +++ b/alltests.cmd @@ -29,3 +29,11 @@ nosetests %1 del coverage\tracer.pyd
set COVERAGE_TEST_TRACER=py
nosetests %1
+
+call \ned\bin\switchpy 31
+python setup.py -q install
+set COVERAGE_TEST_TRACER=c
+python \python31\Scripts\nosetests3 %1
+del \python31\lib\site-packages\coverage\tracer.pyd
+set COVERAGE_TEST_TRACER=py
+python \python31\Scripts\nosetests3 %1
diff --git a/coverage/backward.py b/coverage/backward.py index 94abdd8c..d21e6a87 100644 --- a/coverage/backward.py +++ b/coverage/backward.py @@ -1,8 +1,10 @@ """Add things to old Pythons so I can pretend they are newer.""" -# pylint: disable-msg=W0622 -# (Redefining built-in blah) -# The whole point of this file is to redefine built-ins, so shut up about it. +# This file does lots of tricky stuff, so disable a bunch of lintisms. +# pylint: disable-msg=F0401,W0611,W0622 +# F0401: Unable to import blah +# W0611: Unused import blah +# W0622: Redefining built-in blah import os, sys @@ -23,41 +25,40 @@ except NameError: lst.sort() return lst -# Py2k and 3k don't agree on how to run commands in a subprocess. +# Pythons 2 and 3 differ on where to get StringIO + try: - import subprocess + from cStringIO import StringIO except ImportError: - def run_command(cmd): - """Run a command in a subprocess. - - Returns the exit code and the combined stdout and stderr. - - """ - _, stdouterr = os.popen4(cmd) - return 0, stdouterr.read() + from io import StringIO + +# What's a string called? + +try: + string_class = basestring +except NameError: + string_class = str + +# Where do pickles come from? + +try: + import cPickle as pickle +except ImportError: + import pickle + +# Exec is a statement in Py2, a function in Py3 + +if sys.hexversion > 0x03000000: + def exec_function(source, filename, global_map): + """A wrapper around exec().""" + exec(compile(source, filename, "exec"), global_map) else: - def run_command(cmd): - """Run a command in a subprocess. - - Returns the exit code and the combined stdout and stderr. - - """ - - if sys.hexversion > 0x03000000 and cmd.startswith("coverage "): - # We don't have a coverage command on 3.x, so fix it up to call the - # script. Eventually we won't need this. - cmd = "python " + sys.prefix + os.sep + "Scripts" + os.sep + cmd - - proc = subprocess.Popen(cmd, shell=True, - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.STDOUT - ) - retcode = proc.wait() - - # Get the output, and canonicalize it to strings with newlines. - output = proc.stdout.read() - if not isinstance(output, str): - output = output.decode('utf-8') - output = output.replace('\r', '') - - return retcode, output + # OK, this is pretty gross. In Py2, exec was a statement, but that will + # be a syntax error if we try to put it in a Py3 file, even if it is never + # executed. So hide it inside an evaluated string literal instead. + eval(compile("""\ +def exec_function(source, filename, global_map): + exec compile(source, filename, "exec") in global_map +""", + "<exec_function>", "exec" + )) diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 1348a743..587fac51 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -279,17 +279,17 @@ class CoverageScript: """Display an error message, or the named topic.""" assert error or topic or parser if error: - print error - print "Use 'coverage help' for help." + print(error) + print("Use 'coverage help' for help.") elif parser: - print parser.format_help(), + print(parser.format_help().strip()) else: # Parse out the topic we want from HELP_TOPICS import re topic_list = re.split("(?m)^=+ (\w+) =+$", HELP_TOPICS) topics = dict(zip(topic_list[1::2], topic_list[2::2])) help_msg = topics[topic].strip() - print help_msg % self.covpkg.__dict__ + print(help_msg % self.covpkg.__dict__) def command_line(self, argv): """The bulk of the command line interface to Coverage. diff --git a/coverage/codeunit.py b/coverage/codeunit.py index 7f4ed966..53c98fc7 100644 --- a/coverage/codeunit.py +++ b/coverage/codeunit.py @@ -2,6 +2,9 @@ import glob, os +from coverage.backward import string_class + + def code_unit_factory(morfs, file_locator, omit_prefixes=None): """Construct a list of CodeUnits from polymorphic inputs. @@ -21,7 +24,7 @@ def code_unit_factory(morfs, file_locator, omit_prefixes=None): # On Windows, the shell doesn't expand wildcards. Do it here. globbed = [] for morf in morfs: - if isinstance(morf, basestring) and ('?' in morf or '*' in morf): + if isinstance(morf, string_class) and ('?' in morf or '*' in morf): globbed.extend(glob.glob(morf)) else: globbed.append(morf) diff --git a/coverage/control.py b/coverage/control.py index 19675cf6..4cf97d40 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -3,6 +3,7 @@ import os, socket from coverage.annotate import AnnotateReporter +from coverage.backward import string_class from coverage.codeunit import code_unit_factory from coverage.collector import Collector from coverage.data import CoverageData @@ -68,7 +69,7 @@ class coverage: # Create the data file. if data_suffix: - if not isinstance(data_suffix, basestring): + if not isinstance(data_suffix, string_class): # if data_suffix=True, use .machinename.pid data_suffix = ".%s.%s" % (socket.gethostname(), os.getpid()) else: @@ -136,7 +137,7 @@ class coverage: def _should_trace(self, filename, frame): # pylint: disable-msg=E0102 """A logging decorator around the real _should_trace function.""" ret = self._real_should_trace(filename, frame) - print "should_trace: %r -> %r" % (filename, ret) + print("should_trace: %r -> %r" % (filename, ret)) return ret def use_cache(self, usecache): diff --git a/coverage/data.py b/coverage/data.py index 2fb635ee..4d368f55 100644 --- a/coverage/data.py +++ b/coverage/data.py @@ -1,9 +1,8 @@ """Coverage data for Coverage.""" import os -import cPickle as pickle -from coverage.backward import sorted # pylint: disable-msg=W0622 +from coverage.backward import pickle, sorted # pylint: disable-msg=W0622 class CoverageData: @@ -154,7 +153,7 @@ class CoverageData: def executed_files(self): """A list of all files that had been measured as executed.""" - return self.lines.keys() + return list(self.lines.keys()) def executed_lines(self, filename): """A map containing all the line numbers executed in `filename`. diff --git a/coverage/execfile.py b/coverage/execfile.py index a345c767..cf8e1ec2 100644 --- a/coverage/execfile.py +++ b/coverage/execfile.py @@ -2,6 +2,9 @@ import imp, os, sys +from coverage.backward import exec_function + + try: # In Py 2.x, the builtins were in __builtin__ BUILTINS = sys.modules['__builtin__'] @@ -33,7 +36,7 @@ def run_python_file(filename, args): try: source = open(filename, 'rU').read() - exec compile(source, filename, "exec") in main_mod.__dict__ + exec_function(source, filename, main_mod.__dict__) finally: # Restore the old __main__ sys.modules['__main__'] = old_main_mod diff --git a/coverage/files.py b/coverage/files.py index f3fafdfb..c16f113d 100644 --- a/coverage/files.py +++ b/coverage/files.py @@ -31,7 +31,7 @@ class FileLocator: An absolute path with no redundant components and normalized case. """ - if not self.canonical_filename_cache.has_key(filename): + if filename not in self.canonical_filename_cache: f = filename if os.path.isabs(f) and not os.path.exists(f): if not self.get_zip_data(f): diff --git a/coverage/parser.py b/coverage/parser.py index 4ec9c3c5..75910428 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -1,10 +1,9 @@ """Code parsing for Coverage.""" import re, sys, token, tokenize, types -import cStringIO as StringIO from coverage.misc import nice_pair, CoverageException -from coverage.backward import set # pylint: disable-msg=W0622 +from coverage.backward import set, StringIO # pylint: disable-msg=W0622 @@ -107,13 +106,13 @@ class CodeParser: prev_toktype = token.INDENT first_line = None - tokgen = tokenize.generate_tokens(StringIO.StringIO(text).readline) + tokgen = tokenize.generate_tokens(StringIO(text).readline) for toktype, ttext, (slineno, _), (elineno, _), ltext in tokgen: if self.show_tokens: - print "%10s %5s %-20r %r" % ( + print("%10s %5s %-20r %r" % ( tokenize.tok_name.get(toktype, toktype), nice_pair((slineno, elineno)), ttext, ltext - ) + )) if toktype == token.INDENT: indent += 1 elif toktype == token.DEDENT: @@ -128,7 +127,7 @@ class CodeParser: elif toktype == token.STRING and prev_toktype == token.INDENT: # Strings that are first on an indented line are docstrings. # (a trick from trace.py in the stdlib.) - for i in xrange(slineno, elineno+1): + for i in range(slineno, elineno+1): self.docstrings.add(i) elif toktype == token.NEWLINE: if first_line is not None and elineno != first_line: @@ -136,7 +135,7 @@ class CodeParser: # different line than the first line of the statement, # so record a multi-line range. rng = (first_line, elineno) - for l in xrange(first_line, elineno+1): + for l in range(first_line, elineno+1): self.multiline[l] = rng first_line = None @@ -161,7 +160,8 @@ class CodeParser: # text ends nicely for them. text += '\n' code = compile(text, filename, "exec") - except SyntaxError, synerr: + except SyntaxError: + _, synerr, _ = sys.exc_info() raise CoverageException( "Couldn't parse '%s' as Python source: '%s' at line %d" % (filename, synerr.msg, synerr.lineno) @@ -225,7 +225,7 @@ class CodeParser: m1 = '"' if lineno in self.excluded: m2 = 'x' - print "%4d %s%s%s %s" % (lineno, m0, m1, m2, ltext) + print("%4d %s%s%s %s" % (lineno, m0, m1, m2, ltext)) if __name__ == '__main__': diff --git a/coverage/templite.py b/coverage/templite.py index 75fce6d6..23c805b1 100644 --- a/coverage/templite.py +++ b/coverage/templite.py @@ -106,7 +106,7 @@ class _ContextAccess(object): value = getattr(value, dot) except AttributeError: value = value[dot] - if callable(value): + if hasattr(value, '__call__'): value = value() else: value = self.context[key] @@ -80,7 +80,7 @@ class Mock(object): self.call_count = 0
self.call_args_list = []
self.method_calls = []
- for child in self._children.itervalues():
+ for child in self._children.values():
child.reset_mock()
if isinstance(self._return_value, Mock):
self._return_value.reset_mock()
@@ -34,8 +34,6 @@ if sys.hexversion < 0x03000000: from setuptools import setup from distutils.core import Extension - package_name = 'coverage' - more_setup_args = dict( entry_points = { 'console_scripts': [ @@ -50,8 +48,6 @@ else: # No setuptools yet for Py 3.x, so do without. from distutils.core import setup, Extension - package_name = 'coverage3k' - more_setup_args = dict( scripts = [ 'scripts/coverage', @@ -78,7 +74,7 @@ classifier_list.append("Development Status :: " + devstat) # Set it up! setup( - name = package_name, + name = 'coverage', version = __version__, packages = [ diff --git a/test/backtest.py b/test/backtest.py new file mode 100644 index 00000000..21a14d6d --- /dev/null +++ b/test/backtest.py @@ -0,0 +1,54 @@ +"""Add things to old Pythons so I can pretend they are newer, for tests.""" + +# pylint: disable-msg=W0622 +# (Redefining built-in blah) +# The whole point of this file is to redefine built-ins, so shut up about it. + +import os, sys + +# Py2k and 3k don't agree on how to run commands in a subprocess. +try: + import subprocess +except ImportError: + def run_command(cmd): + """Run a command in a subprocess. + + Returns the exit code and the combined stdout and stderr. + + """ + _, stdouterr = os.popen4(cmd) + return 0, stdouterr.read() +else: + def run_command(cmd): + """Run a command in a subprocess. + + Returns the exit code and the combined stdout and stderr. + + """ + + if sys.hexversion > 0x03000000 and cmd.startswith("coverage "): + # We don't have a coverage command on 3.x, so fix it up to call the + # script. Eventually we won't need this. + cmd = "python " + sys.prefix + os.sep + "Scripts" + os.sep + cmd + + proc = subprocess.Popen(cmd, shell=True, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.STDOUT + ) + retcode = proc.wait() + + # Get the output, and canonicalize it to strings with newlines. + output = proc.stdout.read() + if not isinstance(output, str): + output = output.decode('utf-8') + output = output.replace('\r', '') + + return retcode, output + +# No more execfile in Py3k +try: + execfile = execfile +except NameError: + def execfile(filename, globs): + """A Python 3 implementation of execfile.""" + exec(compile(open(filename).read(), filename, 'exec'), globs) diff --git a/test/coveragetest.py b/test/coveragetest.py index 1502770d..638c10d6 100644 --- a/test/coveragetest.py +++ b/test/coveragetest.py @@ -1,10 +1,10 @@ """Base test case class for coverage testing.""" import imp, os, random, shutil, sys, tempfile, textwrap, unittest -from cStringIO import StringIO import coverage -from coverage.backward import set, run_command # pylint: disable-msg=W0622 +from coverage.backward import set, StringIO # pylint: disable-msg=W0622 +from backtest import run_command class Tee(object): @@ -168,7 +168,8 @@ class CoverageTest(unittest.TestCase): """ try: callableObj(*args, **kwargs) - except excClass, exc: + except excClass: + _, exc, _ = sys.exc_info() excMsg = str(exc) if not msg: # No message provided: it passes. @@ -214,7 +215,7 @@ class CoverageTest(unittest.TestCase): os.environ['PYTHONPATH'] = pypath _, output = run_command(cmd) - print output + print(output) return output def assert_equal_sets(self, s1, s2): diff --git a/test/farm/run/src/chdir.py b/test/farm/run/src/chdir.py index 23c5afa8..d8287ed7 100644 --- a/test/farm/run/src/chdir.py +++ b/test/farm/run/src/chdir.py @@ -1,5 +1,5 @@ import os -print "Line One" +print("Line One") os.chdir("subdir") -print "Line Two" +print("Line Two") diff --git a/test/farm/run/src/showtrace.py b/test/farm/run/src/showtrace.py index 3708ac08..c3b4356c 100644 --- a/test/farm/run/src/showtrace.py +++ b/test/farm/run/src/showtrace.py @@ -3,13 +3,16 @@ import sys -# Print the argument as a label for the output. -print sys.argv[1], - # Show what the trace function is. If a C-based function is used, then f_trace # is None. trace_fn = sys._getframe(0).f_trace if trace_fn is None: - print "None" + trace_name = "None" else: - print trace_fn.im_class.__name__ + # Get the name of the tracer class. Py3k has a different way to get it. + try: + trace_name = trace_fn.im_class.__name__ + except AttributeError: + trace_name = trace_fn.__self__.__class__.__name__ + +print("%s %s" % (sys.argv[1], trace_name)) diff --git a/test/test_api.py b/test/test_api.py index f19099e1..460c5b36 100644 --- a/test/test_api.py +++ b/test/test_api.py @@ -1,9 +1,11 @@ """Tests for Coverage's api.""" import os, re, sys, textwrap -from cStringIO import StringIO import coverage +from coverage.backward import StringIO + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest diff --git a/test/test_cmdline.py b/test/test_cmdline.py index f06e9158..0c262108 100644 --- a/test/test_cmdline.py +++ b/test/test_cmdline.py @@ -1,8 +1,10 @@ """Test cmdline.py for coverage.""" -import re, shlex, textwrap, unittest +import os, re, shlex, sys, textwrap, unittest import mock import coverage + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest diff --git a/test/test_codeunit.py b/test/test_codeunit.py index 46853b76..36ca1fcd 100644 --- a/test/test_codeunit.py +++ b/test/test_codeunit.py @@ -4,6 +4,8 @@ import os, sys from coverage.codeunit import code_unit_factory from coverage.files import FileLocator + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest # pylint: disable-msg=F0401 diff --git a/test/test_coverage.py b/test/test_coverage.py index b364d312..f70b67e3 100644 --- a/test/test_coverage.py +++ b/test/test_coverage.py @@ -3,11 +3,12 @@ # http://nedbatchelder.com/code/coverage import os, sys, unittest -from cStringIO import StringIO import coverage +from coverage.backward import StringIO coverage.use_cache(0) +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest @@ -1891,7 +1892,7 @@ class ExceptionTest(CoverageTest): if __name__ == '__main__': - print "Testing under Python version: %s" % sys.version + print("Testing under Python version: %s" % sys.version) unittest.main() diff --git a/test/test_data.py b/test/test_data.py index 44c123fe..a2557a91 100644 --- a/test/test_data.py +++ b/test/test_data.py @@ -1,7 +1,11 @@ """Tests for coverage.data""" -import cPickle as pickle +import os, sys + +from coverage.backward import pickle from coverage.data import CoverageData + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest diff --git a/test/test_execfile.py b/test/test_execfile.py index aee4eeb3..d4fe2245 100644 --- a/test/test_execfile.py +++ b/test/test_execfile.py @@ -1,8 +1,10 @@ """Tests for coverage.execfile""" -import os +import os, sys from coverage.execfile import run_python_file + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k from coveragetest import CoverageTest here = os.path.dirname(__file__) diff --git a/test/test_farm.py b/test/test_farm.py index 6e8f3467..6200611d 100644 --- a/test/test_farm.py +++ b/test/test_farm.py @@ -1,7 +1,9 @@ """Run tests in the farm subdirectory. Designed for nose.""" import filecmp, fnmatch, glob, os, shutil, sys -from coverage.backward import run_command + +sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k +from backtest import run_command, execfile # pylint: disable-msg=W0622 def test_farm(clean_only=False): @@ -133,7 +135,7 @@ class FarmTestCase(object): if not cmd: continue retcode, output = run_command(cmd) - print output, + print(output.rstrip()) if outfile: open(outfile, "a+").write(output) if retcode: @@ -278,7 +280,7 @@ def main(): for test in test_farm(clean_only=True): test[0].run_fully() else: - print "Need an operation: run, out, clean" + print("Need an operation: run, out, clean") # So that we can run just one farm run.py at a time. if __name__ == '__main__': diff --git a/three.cmd b/three.cmd deleted file mode 100644 index aab61f20..00000000 --- a/three.cmd +++ /dev/null @@ -1,22 +0,0 @@ -@REM Copy the sources, convert to Py3k, and run the tests.
-
-rmdir /s/q three ..\three
-xcopy /s/h/i/e /exclude:notsource.txt . ..\three
-move ..\three .
-cd three
-call switchpy 31
-python \python31\Tools\Scripts\2to3.py --write --nobackups --no-diffs coverage test mock.py
-
-make clean
-make testdata
-
-python setup.py install
-
-@REM Run both modes of tracer
-set COVERAGE_TEST_TRACER=c
-python \python31\Scripts\nosetests3 %1
-del \python31\lib\site-packages\coverage\tracer.pyd
-set COVERAGE_TEST_TRACER=py
-python \python31\Scripts\nosetests3 %1
-
-cd ..
|