summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2011-02-04 23:20:13 -0500
committerNed Batchelder <ned@nedbatchelder.com>2011-02-04 23:20:13 -0500
commit460265da2e04bf22363a245c0fb44c2b6634d065 (patch)
tree6c2929594098df80e0f774905338afa9b6ad658f
parent291fdfb6f18ef3c06c2e04cdcf18fb4b9166aa2f (diff)
parente349d6bc861910456ec9d74ad51d3a147b09a112 (diff)
downloadpython-coveragepy-460265da2e04bf22363a245c0fb44c2b6634d065.tar.gz
Automated merge with ssh://bitbucket.org/ned/coveragepy
-rw-r--r--.hgignore1
-rw-r--r--.pylintrc7
-rw-r--r--.treerc1
-rw-r--r--AUTHORS.txt1
-rw-r--r--CHANGES.txt9
-rw-r--r--Makefile5
-rwxr-xr-xalltests.sh8
-rw-r--r--coverage/backward.py12
-rw-r--r--coverage/cmdline.py2
-rw-r--r--coverage/codeunit.py4
-rw-r--r--coverage/config.py2
-rw-r--r--coverage/control.py4
-rw-r--r--coverage/data.py2
-rw-r--r--coverage/execfile.py9
-rw-r--r--coverage/html.py29
-rw-r--r--coverage/parser.py20
-rw-r--r--coverage/phystokens.py2
-rw-r--r--coverage/results.py4
-rw-r--r--coverage/xmlreport.py2
-rw-r--r--setup.py2
-rw-r--r--test/backtest.py2
-rw-r--r--test/backunittest.py2
-rw-r--r--test/coveragetest.py17
-rw-r--r--test/meta_coverage.py2
-rw-r--r--test/osinfo.py6
-rw-r--r--test/test_api.py2
-rw-r--r--test/test_cmdline.py2
-rw-r--r--test/test_codeunit.py2
-rw-r--r--test/test_execfile.py6
-rw-r--r--test/test_farm.py2
-rw-r--r--test/test_files.py2
-rw-r--r--test/test_parser.py40
-rw-r--r--test/test_summary.py2
-rw-r--r--test/test_templite.py2
-rw-r--r--test/test_testing.py14
35 files changed, 165 insertions, 64 deletions
diff --git a/.hgignore b/.hgignore
index 89982cc..7ac0b5d 100644
--- a/.hgignore
+++ b/.hgignore
@@ -9,6 +9,7 @@ syntax: glob
*.bak
.coverage
.coverage.*
+*.swp
# Stuff in the root.
build
diff --git a/.pylintrc b/.pylintrc
index e3ef288..aa2d07e 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -53,7 +53,7 @@ load-plugins=
#enable-msg=
# Disable the message(s) with the given id(s).
-disable-msg=
+disable=
# Messages that are just silly:
# I0011:106: Locally disabling E1101
# W0122: 30:run_python_file: Use of the exec statement
@@ -64,7 +64,6 @@ disable-msg=
# W0603: 28:call_singleton_method: Using the global statement
# W0703:133:CoverageData._read_file: Catch "Exception"
I0011,W0122,W0142,W0232,C0323,C0324,W0603,W0703,
-
# Messages that may be silly:
# R0201: 42:Tracer.stop: Method could be a function
# C0321: 80:CodeUnit.__lt__: More than one statement on a single line
@@ -72,10 +71,10 @@ disable-msg=
# W0403: 4: Relative import 'coveragetest'
# E1103: 26:RunTests.test_run_python_file: Instance of 'file' has no 'getvalue' member (but some types could not be inferred)
R0201,C0321,R0401,W0403,E1103,
-
# Messages that are noisy for now, eventually maybe we'll turn them on:
# C0103:256:coverage.morf_filename: Invalid name "f" (should match [a-z_][a-z0-9_]{2,30}$)
- C0103
+# W0404: 22:run_tests_with_coverage: Reimport 'coverage' (imported line 18)
+ C0103,W0404
[REPORTS]
diff --git a/.treerc b/.treerc
index 7b671ef..3c75f69 100644
--- a/.treerc
+++ b/.treerc
@@ -7,3 +7,4 @@ ignore =
distribute_setup.py ez_setup.py mock.py
*.min.js
sample_html
+ *.so *.pyd
diff --git a/AUTHORS.txt b/AUTHORS.txt
index ee09073..77bbcbc 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -6,6 +6,7 @@ Other contributions have been made by:
Chris Adams
Geoff Bache
Titus Brown
+Brett Cannon
Guillaume Chazarain
David Christian
Danek Duvall
diff --git a/CHANGES.txt b/CHANGES.txt
index a3a739a..d338e15 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -19,7 +19,16 @@ Version 3.5
coverage.py will issue a warning, at least alerting you to the problem.
Closes `issue 93`_. Thanks to Marius Gedminas for the idea.
+- Source files are now opened with Python 3.2's ``tokenize.open()`` where
+ possible, to get the best handling of Python source files with encodings.
+ Closes `issue 107`, thanks, Brett Cannon.
+
+- Internally, files are now closed explicitly, fixing `issue 104`. Thanks,
+ Brett Cannon.
+
.. _issue 93: http://bitbucket.org/ned/coveragepy/issue/93/copying-a-mock-object-breaks-coverage
+.. _issue 104: https://bitbucket.org/ned/coveragepy/issue/104/explicitly-close-files
+.. _issue 107: https://bitbucket.org/ned/coveragepy/issue/107/codeparser-not-opening-source-files-with
Version 3.4 --- 19 September 2010
diff --git a/Makefile b/Makefile
index 0cacacc..1c7a446 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,7 @@ clean:
python test/test_farm.py clean
-rm -rf build coverage.egg-info dist htmlcov
-rm -f *.pyd */*.pyd
+ -rm -f *.so */*.so
-rm -f *.pyc */*.pyc */*/*.pyc */*/*/*.pyc */*/*/*/*.pyc */*/*/*/*/*.pyc
-rm -f *.pyo */*.pyo */*/*.pyo */*/*/*.pyo */*/*/*/*.pyo */*/*/*/*/*.pyo
-rm -f *.bak */*.bak */*/*.bak */*/*/*.bak */*/*/*/*.bak */*/*/*/*/*.bak
@@ -26,8 +27,8 @@ clean:
LINTABLE = coverage setup.py test
lint:
- -python -x /Python25/Scripts/pylint.bat --rcfile=.pylintrc $(LINTABLE)
- python /Python25/Lib/tabnanny.py $(LINTABLE)
+ -pylint --rcfile=.pylintrc $(LINTABLE)
+ python -m tabnanny $(LINTABLE)
python checkeol.py
pep8:
diff --git a/alltests.sh b/alltests.sh
index 7c8b050..3371021 100755
--- a/alltests.sh
+++ b/alltests.sh
@@ -9,14 +9,14 @@
source ../ve/26/bin/activate
make --quiet testdata
-for v in 24 25 26 27 # 23 31 32
+for v in 24 25 26 27 31 32 # 23
do
source ../ve/$v/bin/activate
python setup.py -q develop
- echo "=== $v c ==="
+ python -c "import platform; print('=== Python %s with C tracer ===' % platform.python_version())"
COVERAGE_TEST_TRACER=c nosetests $@
- echo "=== $v py ==="
- rm coverage/tracer.so
+ python -c "import platform; print('=== Python %s with Python tracer ===' % platform.python_version())"
+ rm coverage/tracer*.so
COVERAGE_TEST_TRACER=py nosetests $@
done
diff --git a/coverage/backward.py b/coverage/backward.py
index 425bcc6..c363f21 100644
--- a/coverage/backward.py
+++ b/coverage/backward.py
@@ -1,7 +1,7 @@
"""Add things to old Pythons so I can pretend they are newer."""
# This file does lots of tricky stuff, so disable a bunch of lintisms.
-# pylint: disable-msg=F0401,W0611,W0622
+# pylint: disable=F0401,W0611,W0622
# F0401: Unable to import blah
# W0611: Unused import blah
# W0622: Redefining built-in blah
@@ -71,3 +71,13 @@ try:
import configparser
except ImportError:
import ConfigParser as configparser
+
+# Python 3.2 provides `tokenize.open`, the best way to open source files.
+try:
+ import tokenize
+ open_source = tokenize.open # pylint: disable=E1101
+except AttributeError:
+ def open_source(fname):
+ """Open a source file the best way."""
+ return open(fname, "rU")
+
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index e5d6bb8..18715b7 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -2,7 +2,7 @@
import optparse, re, sys, traceback
-from coverage.backward import sorted # pylint: disable-msg=W0622
+from coverage.backward import sorted # pylint: disable=W0622
from coverage.execfile import run_python_file
from coverage.misc import CoverageException, ExceptionDuringRun
diff --git a/coverage/codeunit.py b/coverage/codeunit.py
index dfc4560..55f44a2 100644
--- a/coverage/codeunit.py
+++ b/coverage/codeunit.py
@@ -2,7 +2,7 @@
import glob, os
-from coverage.backward import string_class, StringIO
+from coverage.backward import open_source, string_class, StringIO
from coverage.misc import CoverageException
@@ -104,7 +104,7 @@ class CodeUnit(object):
"""Return an open file for reading the source of the code unit."""
if os.path.exists(self.filename):
# A regular text file: open it.
- return open(self.filename)
+ return open_source(self.filename)
# Maybe it's in a zip file?
source = self.file_locator.get_zip_data(self.filename)
diff --git a/coverage/config.py b/coverage/config.py
index 1f6a879..eda3c1c 100644
--- a/coverage/config.py
+++ b/coverage/config.py
@@ -1,7 +1,7 @@
"""Config file for coverage.py"""
import os
-from coverage.backward import configparser # pylint: disable-msg=W0622
+from coverage.backward import configparser # pylint: disable=W0622
class CoverageConfig(object):
diff --git a/coverage/control.py b/coverage/control.py
index 4fae198..8961a3c 100644
--- a/coverage/control.py
+++ b/coverage/control.py
@@ -269,7 +269,7 @@ class coverage(object):
# To log what should_trace returns, change this to "if 1:"
if 0:
_real_should_trace = _should_trace
- def _should_trace(self, filename, frame): # pylint: disable-msg=E0102
+ def _should_trace(self, filename, frame): # pylint: disable=E0102
"""A logging decorator around the real _should_trace function."""
ret = self._real_should_trace(filename, frame)
print("should_trace: %r -> %r" % (filename, ret))
@@ -496,7 +496,7 @@ class coverage(object):
return Analysis(self, it)
def report(self, morfs=None, show_missing=True, ignore_errors=None,
- file=None, # pylint: disable-msg=W0622
+ file=None, # pylint: disable=W0622
omit=None, include=None
):
"""Write a summary report to `file`.
diff --git a/coverage/data.py b/coverage/data.py
index 3d750c4..5d482ea 100644
--- a/coverage/data.py
+++ b/coverage/data.py
@@ -2,7 +2,7 @@
import os
-from coverage.backward import pickle, sorted # pylint: disable-msg=W0622
+from coverage.backward import pickle, sorted # pylint: disable=W0622
class CoverageData(object):
diff --git a/coverage/execfile.py b/coverage/execfile.py
index 333163f..c61556a 100644
--- a/coverage/execfile.py
+++ b/coverage/execfile.py
@@ -2,7 +2,7 @@
import imp, os, sys
-from coverage.backward import exec_code_object
+from coverage.backward import exec_code_object, open_source
from coverage.misc import NoSource, ExceptionDuringRun
@@ -38,10 +38,15 @@ def run_python_file(filename, args):
try:
# Open the source file.
try:
- source = open(filename, 'rU').read()
+ source_file = open_source(filename)
except IOError:
raise NoSource("No file to run: %r" % filename)
+ try:
+ source = source_file.read()
+ finally:
+ source_file.close()
+
# We have the source. `compile` still needs the last line to be clean,
# so make sure it is, then compile a code object from it.
if source[-1] != '\n':
diff --git a/coverage/html.py b/coverage/html.py
index 76e2890..87edad4 100644
--- a/coverage/html.py
+++ b/coverage/html.py
@@ -2,7 +2,7 @@
import os, re, shutil
-from coverage import __url__, __version__ # pylint: disable-msg=W0611
+from coverage import __url__, __version__ # pylint: disable=W0611
from coverage.misc import CoverageException
from coverage.phystokens import source_token_lines
from coverage.report import Reporter
@@ -10,7 +10,7 @@ from coverage.templite import Templite
# Disable pylint msg W0612, because a bunch of variables look unused, but
# they're accessed in a Templite context via locals().
-# pylint: disable-msg=W0612
+# pylint: disable=W0612
def data_filename(fname):
"""Return the path to a data file of ours."""
@@ -18,7 +18,11 @@ def data_filename(fname):
def data(fname):
"""Return the contents of a data file of ours."""
- return open(data_filename(fname)).read()
+ data_file = open(data_filename(fname))
+ try:
+ return data_file.read()
+ finally:
+ data_file.close()
class HtmlReporter(Reporter):
@@ -68,8 +72,11 @@ class HtmlReporter(Reporter):
def html_file(self, cu, analysis):
"""Generate an HTML file for one source file."""
-
- source = cu.source_file().read()
+ source_file = cu.source_file()
+ try:
+ source = source_file.read()
+ finally:
+ source_file.close()
nums = analysis.numbers
@@ -138,8 +145,10 @@ class HtmlReporter(Reporter):
html_path = os.path.join(self.directory, html_filename)
html = spaceless(self.source_tmpl.render(locals()))
fhtml = open(html_path, 'w')
- fhtml.write(html)
- fhtml.close()
+ try:
+ fhtml.write(html)
+ finally:
+ fhtml.close()
# Save this file's information for the index file.
self.files.append({
@@ -159,8 +168,10 @@ class HtmlReporter(Reporter):
totals = sum([f['nums'] for f in files])
fhtml = open(os.path.join(self.directory, "index.html"), "w")
- fhtml.write(index_tmpl.render(locals()))
- fhtml.close()
+ try:
+ fhtml.write(index_tmpl.render(locals()))
+ finally:
+ fhtml.close()
# Helpers for templates and generating HTML
diff --git a/coverage/parser.py b/coverage/parser.py
index ae618ce..8ad4e05 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -2,7 +2,8 @@
import glob, opcode, os, re, sys, token, tokenize
-from coverage.backward import set, sorted, StringIO # pylint: disable-msg=W0622
+from coverage.backward import set, sorted, StringIO # pylint: disable=W0622
+from coverage.backward import open_source
from coverage.bytecode import ByteCodes, CodeObjects
from coverage.misc import nice_pair, CoverageException, NoSource, expensive
@@ -22,15 +23,16 @@ class CodeParser(object):
self.text = text
if not self.text:
try:
- sourcef = open(self.filename, 'rU')
- self.text = sourcef.read()
- sourcef.close()
+ sourcef = open_source(self.filename)
+ try:
+ self.text = sourcef.read()
+ finally:
+ sourcef.close()
except IOError:
_, err, _ = sys.exc_info()
raise NoSource(
"No source for code: %r: %s" % (self.filename, err)
)
- self.text = self.text.replace('\r\n', '\n')
self.exclude = exclude
@@ -302,9 +304,11 @@ class ByteParser(object):
else:
if not text:
assert filename, "If no code or text, need a filename"
- sourcef = open(filename, 'rU')
- text = sourcef.read()
- sourcef.close()
+ sourcef = open_source(filename)
+ try:
+ text = sourcef.read()
+ finally:
+ sourcef.close()
try:
# Python 2.3 and 2.4 don't like partial last lines, so be sure
diff --git a/coverage/phystokens.py b/coverage/phystokens.py
index 60b8793..fc4f2c9 100644
--- a/coverage/phystokens.py
+++ b/coverage/phystokens.py
@@ -1,7 +1,7 @@
"""Better tokenizing for coverage.py."""
import keyword, re, token, tokenize
-from coverage.backward import StringIO # pylint: disable-msg=W0622
+from coverage.backward import StringIO # pylint: disable=W0622
def phys_tokens(toks):
"""Return all physical tokens, even line continuations.
diff --git a/coverage/results.py b/coverage/results.py
index 85071fe..a7ec0fd 100644
--- a/coverage/results.py
+++ b/coverage/results.py
@@ -2,7 +2,7 @@
import os
-from coverage.backward import set, sorted # pylint: disable-msg=W0622
+from coverage.backward import set, sorted # pylint: disable=W0622
from coverage.misc import format_lines, NoSource
from coverage.parser import CodeParser
@@ -230,4 +230,4 @@ class Numbers(object):
# Implementing 0+Numbers allows us to sum() a list of Numbers.
if other == 0:
return self
- raise NotImplemented
+ return NotImplemented
diff --git a/coverage/xmlreport.py b/coverage/xmlreport.py
index 5eabac7..5f6cc87 100644
--- a/coverage/xmlreport.py
+++ b/coverage/xmlreport.py
@@ -4,7 +4,7 @@ import os, sys, time
import xml.dom.minidom
from coverage import __url__, __version__
-from coverage.backward import sorted # pylint: disable-msg=W0622
+from coverage.backward import sorted # pylint: disable=W0622
from coverage.report import Reporter
def rate(hit, num):
diff --git a/setup.py b/setup.py
index fbdf071..f0e9268 100644
--- a/setup.py
+++ b/setup.py
@@ -46,7 +46,7 @@ else:
use_setuptools()
from setuptools import setup
-from distutils.core import Extension # pylint: disable-msg=E0611,F0401
+from distutils.core import Extension # pylint: disable=E0611,F0401
# Get or massage our metadata.
diff --git a/test/backtest.py b/test/backtest.py
index e8d8366..4576a86 100644
--- a/test/backtest.py
+++ b/test/backtest.py
@@ -1,6 +1,6 @@
"""Add things to old Pythons so I can pretend they are newer, for tests."""
-# pylint: disable-msg=W0622
+# pylint: disable=W0622
# (Redefining built-in blah)
# The whole point of this file is to redefine built-ins, so shut up about it.
diff --git a/test/backunittest.py b/test/backunittest.py
index f606185..c1685e0 100644
--- a/test/backunittest.py
+++ b/test/backunittest.py
@@ -2,7 +2,7 @@
import difflib, re, sys, unittest
-from coverage.backward import set # pylint: disable-msg=W0622
+from coverage.backward import set # pylint: disable=W0622
def _need(method):
diff --git a/test/coveragetest.py b/test/coveragetest.py
index 53f0ef0..ebff65a 100644
--- a/test/coveragetest.py
+++ b/test/coveragetest.py
@@ -3,7 +3,7 @@
import imp, os, random, shlex, shutil, sys, tempfile, textwrap
import coverage
-from coverage.backward import sorted, StringIO # pylint: disable-msg=W0622
+from coverage.backward import sorted, StringIO # pylint: disable=W0622
from backtest import run_command
from backunittest import TestCase
@@ -123,11 +123,12 @@ class CoverageTest(TestCase):
"""Return the data written to stderr during the test."""
return self.captured_stderr.getvalue()
- def make_file(self, filename, text=""):
+ def make_file(self, filename, text="", newline=None):
"""Create a temp file.
`filename` is the path to the file, including directories if desired,
- and `text` is the content.
+ and `text` is the content. If `newline` is provided, it is a string
+ that will be used as the line endings in the created file.
Returns the path to the file.
@@ -135,6 +136,8 @@ class CoverageTest(TestCase):
# Tests that call `make_file` should be run in a temp environment.
assert self.run_in_temp_dir
text = textwrap.dedent(text)
+ if newline:
+ text = text.replace("\n", newline)
# Make sure the directories are available.
dirs, _ = os.path.split(filename)
@@ -143,8 +146,10 @@ class CoverageTest(TestCase):
# Create the file.
f = open(filename, 'w')
- f.write(text)
- f.close()
+ try:
+ f.write(text)
+ finally:
+ f.close()
return filename
@@ -162,7 +167,7 @@ class CoverageTest(TestCase):
if suff[0] == '.py':
break
try:
- # pylint: disable-msg=W0631
+ # pylint: disable=W0631
# (Using possibly undefined loop variable 'suff')
mod = imp.load_module(modname, f, modfile, suff)
finally:
diff --git a/test/meta_coverage.py b/test/meta_coverage.py
index 1c71abf..ef0292a 100644
--- a/test/meta_coverage.py
+++ b/test/meta_coverage.py
@@ -45,7 +45,7 @@ def run_tests_with_coverage():
if hasattr(mod, '__file__') and mod.__file__.startswith(covdir):
covmods[name] = mod
del sys.modules[name]
- import coverage # don't warn about re-import: pylint: disable-msg=W0404
+ import coverage # don't warn about re-import: pylint: disable=W0404
#sys.modules.update(covmods)
# Run nosetests, with the arguments from our command line.
diff --git a/test/osinfo.py b/test/osinfo.py
index 04855fe..25c3a7c 100644
--- a/test/osinfo.py
+++ b/test/osinfo.py
@@ -45,8 +45,10 @@ elif sys.platform == 'linux2':
try:
# get pseudo file /proc/<pid>/status
t = open('/proc/%d/status' % os.getpid())
- v = t.read()
- t.close()
+ try:
+ v = t.read()
+ finally:
+ t.close()
except IOError:
return 0 # non-Linux?
# get VmKey line e.g. 'VmRSS: 9999 kB\n ...'
diff --git a/test/test_api.py b/test/test_api.py
index 5952dfe..aee0734 100644
--- a/test/test_api.py
+++ b/test/test_api.py
@@ -314,7 +314,7 @@ class SourceOmitIncludeTest(CoverageTest):
"""
cov = coverage.coverage(**kwargs)
cov.start()
- import usepkgs # pylint: disable-msg=F0401,W0612
+ import usepkgs # pylint: disable=F0401,W0612
cov.stop()
return cov.data.summary()
diff --git a/test/test_cmdline.py b/test/test_cmdline.py
index aa72b34..a9858d5 100644
--- a/test/test_cmdline.py
+++ b/test/test_cmdline.py
@@ -372,7 +372,7 @@ class FakeCoverageForDebugData(object):
"""Fake coverage().data.has_arcs()"""
return False
- def summary(self, fullpath): # pylint: disable-msg=W0613
+ def summary(self, fullpath): # pylint: disable=W0613
"""Fake coverage().data.summary()"""
return self._summary
diff --git a/test/test_codeunit.py b/test/test_codeunit.py
index 7903d15..b543949 100644
--- a/test/test_codeunit.py
+++ b/test/test_codeunit.py
@@ -8,7 +8,7 @@ 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
+# pylint: disable=F0401
# Unable to import 'aa' (No module named aa)
class CodeUnitTest(CoverageTest):
diff --git a/test/test_execfile.py b/test/test_execfile.py
index 2f28a06..f6e4dd7 100644
--- a/test/test_execfile.py
+++ b/test/test_execfile.py
@@ -55,8 +55,10 @@ class RunTest(CoverageTest):
pylines = """# try newlines|print('Hello, world!')|""".split('|')
for nl in ('\n', '\r\n', '\r'):
fpy = open('nl.py', 'wb')
- fpy.write(nl.join(pylines).encode('utf-8'))
- fpy.close()
+ try:
+ fpy.write(nl.join(pylines).encode('utf-8'))
+ finally:
+ fpy.close()
run_python_file('nl.py', ['nl.py'])
self.assertEqual(self.stdout(), "Hello, world!\n"*3)
diff --git a/test/test_farm.py b/test/test_farm.py
index 79b345a..7041531 100644
--- a/test/test_farm.py
+++ b/test/test_farm.py
@@ -3,7 +3,7 @@
import difflib, filecmp, fnmatch, glob, os, re, shutil, sys
sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k
-from backtest import run_command, execfile # pylint: disable-msg=W0622
+from backtest import run_command, execfile # pylint: disable=W0622
def test_farm(clean_only=False):
diff --git a/test/test_files.py b/test/test_files.py
index 4ffc6ca..9cbaf9c 100644
--- a/test/test_files.py
+++ b/test/test_files.py
@@ -4,7 +4,7 @@ import os, sys
from coverage.files import FileLocator, TreeMatcher, FnmatchMatcher
from coverage.files import find_python_files
-from coverage.backward import set # pylint: disable-msg=W0622
+from coverage.backward import set # pylint: disable=W0622
sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k
from coveragetest import CoverageTest
diff --git a/test/test_parser.py b/test/test_parser.py
index b398044..220db17 100644
--- a/test/test_parser.py
+++ b/test/test_parser.py
@@ -16,7 +16,7 @@ class ParserTest(CoverageTest):
def parse_source(self, text):
"""Parse `text` as source, and return the `CodeParser` used."""
text = textwrap.dedent(text)
- cp = CodeParser(text, exclude="nocover")
+ cp = CodeParser(text=text, exclude="nocover")
cp.parse_source()
return cp
@@ -94,3 +94,41 @@ class ParserTest(CoverageTest):
b = 6
""")
self.assertEqual(cp.exit_counts(), { 1:1, 2:1, 3:1, 6:1 })
+
+
+class ParserFileTest(CoverageTest):
+ """Tests for Coverage.py's code parsing from files."""
+
+ def parse_file(self, filename):
+ """Parse `text` as source, and return the `CodeParser` used."""
+ cp = CodeParser(filename=filename, exclude="nocover")
+ cp.parse_source()
+ return cp
+
+ def test_line_endings(self):
+ text = """\
+ # check some basic branch counting
+ class Foo:
+ def foo(self, a):
+ if a:
+ return 5
+ else:
+ return 7
+
+ class Bar:
+ pass
+ """
+ counts = { 2:1, 3:1, 4:2, 5:1, 7:1, 9:1, 10:1 }
+ name_endings = (("unix", "\n"), ("dos", "\r\n"), ("mac", "\r"))
+ for fname, newline in name_endings:
+ fname = fname + ".py"
+ self.make_file(fname, text, newline=newline)
+ cp = self.parse_file(fname)
+ self.assertEqual(cp.exit_counts(), counts)
+
+ def test_encoding(self):
+ self.make_file("encoded.py", """\
+ coverage = "\xe7\xf6v\xear\xe3g\xe9"
+ """)
+ cp = self.parse_file("encoded.py")
+ cp.exit_counts()
diff --git a/test/test_summary.py b/test/test_summary.py
index fcc2612..5a68912 100644
--- a/test/test_summary.py
+++ b/test/test_summary.py
@@ -143,7 +143,7 @@ class SummaryTest2(CoverageTest):
def test_empty_files(self):
cov = coverage.coverage()
cov.start()
- import usepkgs # pylint: disable-msg=F0401,W0612
+ import usepkgs # pylint: disable=F0401,W0612
cov.stop()
repout = StringIO()
diff --git a/test/test_templite.py b/test/test_templite.py
index 93e9183..0435c54 100644
--- a/test/test_templite.py
+++ b/test/test_templite.py
@@ -3,7 +3,7 @@
from coverage.templite import Templite
import unittest
-# pylint: disable-msg=W0612,E1101
+# pylint: disable=W0612,E1101
# Disable W0612 (Unused variable) and
# E1101 (Instance of 'foo' has no 'bar' member)
diff --git a/test/test_testing.py b/test/test_testing.py
index 1cae931..2461a08 100644
--- a/test/test_testing.py
+++ b/test/test_testing.py
@@ -5,7 +5,7 @@ sys.path.insert(0, os.path.split(__file__)[0]) # Force relative import for Py3k
from backunittest import TestCase
from coveragetest import CoverageTest
-from coverage.backward import set # pylint: disable-msg=W0622
+from coverage.backward import set # pylint: disable=W0622
class TestingTest(TestCase):
"""Tests of helper methods on `backunittest.TestCase`."""
@@ -96,6 +96,10 @@ class TestingTest(TestCase):
class CoverageTestTest(CoverageTest):
"""Test the methods in `CoverageTest`."""
+ def file_text(self, fname):
+ """Return the text read from a file."""
+ return open(fname, "rb").read().decode('ascii')
+
def test_make_file(self):
# A simple file.
self.make_file("fooey.boo", "Hello there")
@@ -109,3 +113,11 @@ class CoverageTestTest(CoverageTest):
# A deeper directory
self.make_file("sub/deeper/evenmore/third.txt")
self.assertEqual(open("sub/deeper/evenmore/third.txt").read(), "")
+
+ def test_make_file_newline(self):
+ self.make_file("unix.txt", "Hello\n")
+ self.assertEqual(self.file_text("unix.txt"), "Hello\n")
+ self.make_file("dos.txt", "Hello\n", newline="\r\n")
+ self.assertEqual(self.file_text("dos.txt"), "Hello\r\n")
+ self.make_file("mac.txt", "Hello\n", newline="\r")
+ self.assertEqual(self.file_text("mac.txt"), "Hello\r")