summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/__init__.py5
-rw-r--r--coverage/cmdline.py5
-rw-r--r--coverage/debug.py12
-rw-r--r--coverage/misc.py9
-rw-r--r--coverage/results.py4
-rw-r--r--coverage/sqldata.py6
-rw-r--r--doc/cmd.rst11
-rw-r--r--doc/trouble.rst15
-rw-r--r--howto.txt2
-rw-r--r--pylintrc7
-rw-r--r--setup.py8
-rw-r--r--tests/conftest.py3
-rw-r--r--tests/coveragetest.py5
-rw-r--r--tests/test_cmdline.py2
14 files changed, 38 insertions, 56 deletions
diff --git a/coverage/__init__.py b/coverage/__init__.py
index 5edb7524..331b304b 100644
--- a/coverage/__init__.py
+++ b/coverage/__init__.py
@@ -8,6 +8,8 @@ https://nedbatchelder.com/code/coverage
"""
+import sys
+
from coverage.version import __version__, __url__, version_info
from coverage.control import Coverage, process_startup
@@ -22,13 +24,12 @@ coverage = Coverage
# On Windows, we encode and decode deep enough that something goes wrong and
# the encodings.utf_8 module is loaded and then unloaded, I don't know why.
# Adding a reference here prevents it from being unloaded. Yuk.
-import encodings.utf_8
+import encodings.utf_8 # pylint: disable=wrong-import-position, wrong-import-order
# Because of the "from coverage.control import fooey" lines at the top of the
# file, there's an entry for coverage.coverage in sys.modules, mapped to None.
# This makes some inspection tools (like pydoc) unable to find the class
# coverage.coverage. So remove that entry.
-import sys
try:
del sys.modules['coverage.coverage']
except KeyError:
diff --git a/coverage/cmdline.py b/coverage/cmdline.py
index 99b155b2..7137852d 100644
--- a/coverage/cmdline.py
+++ b/coverage/cmdline.py
@@ -621,7 +621,7 @@ class CoverageScript(object):
# they will be None if they have not been specified.
if getattr(options, opt_name) is not None:
self.help_fn(
- "Options affecting multiprocessing must be specified "
+ "Options affecting multiprocessing must only be specified "
"in a configuration file."
)
return ERR
@@ -636,8 +636,7 @@ class CoverageScript(object):
if options.module:
self.run_python_module(args[0], args)
else:
- filename = args[0]
- self.run_python_file(filename, args)
+ self.run_python_file(args[0], args)
except NoSource:
code_ran = False
raise
diff --git a/coverage/debug.py b/coverage/debug.py
index 7cbda792..9077a3af 100644
--- a/coverage/debug.py
+++ b/coverage/debug.py
@@ -29,7 +29,7 @@ FORCED_DEBUG = []
class DebugControl(object):
"""Control and output for debugging."""
- show_repr_attr = False # For SimpleRepr
+ show_repr_attr = False # For SimpleReprMixin
def __init__(self, options, output):
"""Configure the options and output file for debugging."""
@@ -171,7 +171,7 @@ def add_pid_and_tid(text):
return text
-class SimpleRepr(object):
+class SimpleReprMixin(object):
"""A mixin implementing a simple __repr__."""
def __repr__(self):
show_attrs = (
@@ -303,12 +303,12 @@ def decorate_methods(decorator, butnot=()): # pragma: debugging
def break_in_pudb(func): # pragma: debugging
"""A function decorator to stop in the debugger for each call."""
@functools.wraps(func)
- def wrapper(*args, **kwargs):
+ def _wrapper(*args, **kwargs):
import pudb # pylint: disable=import-error
sys.stdout = sys.__stdout__
pudb.set_trace()
return func(*args, **kwargs)
- return wrapper
+ return _wrapper
OBJ_IDS = itertools.count()
@@ -319,7 +319,7 @@ def show_calls(show_args=True, show_stack=False): # pragma: debugging
"""A method decorator to debug-log each call to the function."""
def _decorator(func):
@functools.wraps(func)
- def wrapper(self, *args, **kwargs):
+ def _wrapper(self, *args, **kwargs):
oid = getattr(self, OBJ_ID_ATTR, None)
if oid is None:
oid = "{:08d} {:04d}".format(os.getpid(), next(OBJ_IDS))
@@ -340,7 +340,7 @@ def show_calls(show_args=True, show_stack=False): # pragma: debugging
msg = "{} {:04d} {}{}\n".format(oid, next(CALLS), func.__name__, extra)
DebugOutputFile.get_one().write(msg)
return func(self, *args, **kwargs)
- return wrapper
+ return _wrapper
return _decorator
diff --git a/coverage/misc.py b/coverage/misc.py
index 7b8fbb93..a923829d 100644
--- a/coverage/misc.py
+++ b/coverage/misc.py
@@ -70,11 +70,11 @@ if env.TESTING:
"""Ensure that only one of the argnames is non-None."""
def _decorator(func):
argnameset = set(name.strip() for name in argnames.split(","))
- def _wrapped(*args, **kwargs):
+ def _wrapper(*args, **kwargs):
vals = [kwargs.get(name) for name in argnameset]
assert sum(val is not None for val in vals) == 1
return func(*args, **kwargs)
- return _wrapped
+ return _wrapper
return _decorator
else: # pragma: not testing
# We aren't using real PyContracts, so just define our decorators as
@@ -149,13 +149,12 @@ def expensive(fn):
if env.TESTING:
attr = "_once_" + fn.__name__
- def _wrapped(self):
- """Inner function that checks the cache."""
+ def _wrapper(self):
if hasattr(self, attr):
raise AssertionError("Shouldn't have called %s more than once" % fn.__name__)
setattr(self, attr, True)
return fn(self)
- return _wrapped
+ return _wrapper
else:
return fn # pragma: not testing
diff --git a/coverage/results.py b/coverage/results.py
index fb919c9b..cab8796e 100644
--- a/coverage/results.py
+++ b/coverage/results.py
@@ -6,7 +6,7 @@
import collections
from coverage.backward import iitems
-from coverage.debug import SimpleRepr
+from coverage.debug import SimpleReprMixin
from coverage.misc import contract, format_lines
@@ -158,7 +158,7 @@ class Analysis(object):
return stats
-class Numbers(SimpleRepr):
+class Numbers(SimpleReprMixin):
"""The numerical results of measuring coverage.
This holds the basic statistics from `Analysis`, and is used to roll
diff --git a/coverage/sqldata.py b/coverage/sqldata.py
index e644ec16..fb2279c9 100644
--- a/coverage/sqldata.py
+++ b/coverage/sqldata.py
@@ -18,7 +18,7 @@ import sqlite3
from coverage.backward import iitems
from coverage.data import filename_suffix
-from coverage.debug import SimpleRepr
+from coverage.debug import SimpleReprMixin
from coverage.files import PathAliases
from coverage.misc import CoverageException, file_be_gone
@@ -73,7 +73,7 @@ create table tracer (
"""
-class CoverageSqliteData(SimpleRepr):
+class CoverageSqliteData(SimpleReprMixin):
def __init__(self, basename=None, suffix=None, warn=None, debug=None):
self._basename = os.path.abspath(basename or ".coverage")
self._suffix = suffix
@@ -474,7 +474,7 @@ class CoverageSqliteData(SimpleRepr):
return [] # TODO
-class Sqlite(SimpleRepr):
+class Sqlite(SimpleReprMixin):
def __init__(self, filename, debug):
self.debug = debug if (debug and debug.should('sql')) else None
if self.debug:
diff --git a/doc/cmd.rst b/doc/cmd.rst
index 0d1a05b5..86a858e4 100644
--- a/doc/cmd.rst
+++ b/doc/cmd.rst
@@ -118,6 +118,10 @@ configuration file for all options.
.. _gevent: http://www.gevent.org/
.. _eventlet: http://eventlet.net/
+If you are measuring coverage in a multi-process program, or across a number of
+machines, you'll want the ``--parallel-mode`` switch to keep the data separate
+during measurement. See :ref:`cmd_combining` below.
+
You can specify a :ref:`static context <contexts>` for a coverage run with
``--context``. This can be any label you want, and will be recorded with the
data. See :ref:`contexts` for more information.
@@ -128,12 +132,7 @@ code as well as your own, add the ``-L`` (or ``--pylib``) flag.
If your coverage results seem to be overlooking code that you know has been
executed, try running coverage.py again with the ``--timid`` flag. This uses a
-simpler but slower trace method. Projects that use DecoratorTools, including
-TurboGears, will need to use ``--timid`` to get correct results.
-
-If you are measuring coverage in a multi-process program, or across a number of
-machines, you'll want the ``--parallel-mode`` switch to keep the data separate
-during measurement. See :ref:`cmd_combining` below.
+simpler but slower trace method, and might be needed in rare cases.
.. _cmd_warnings:
diff --git a/doc/trouble.rst b/doc/trouble.rst
index 8f260604..16483bb2 100644
--- a/doc/trouble.rst
+++ b/doc/trouble.rst
@@ -53,21 +53,6 @@ coverage.py from working properly:
.. _issue 43: https://bitbucket.org/ned/coveragepy/issues/43/coverage-measurement-fails-on-code
-Things that require --timid
----------------------------
-
-Some packages interfere with coverage measurement, but you might be able to
-make it work by using the ``--timid`` command-line switch, or the ``[run]
-timid=True`` configuration option.
-
-* `DecoratorTools`_, or any package which uses it, notably `TurboGears`_.
- DecoratorTools fiddles with the trace function. You will need to use
- ``--timid``.
-
-.. _DecoratorTools: https://pypi.org/project/DecoratorTools/
-.. _TurboGears: http://turbogears.org/
-
-
Still having trouble?
---------------------
diff --git a/howto.txt b/howto.txt
index e915c446..ae20d0b9 100644
--- a/howto.txt
+++ b/howto.txt
@@ -55,7 +55,7 @@
- https://ci.appveyor.com/project/nedbat/coveragepy
- $ make download_appveyor
- examine the dist directory, and remove anything that looks malformed.
-- Update PyPi:
+- Update PyPI:
- upload kits:
- $ make kit_upload
- Tag the tree
diff --git a/pylintrc b/pylintrc
index d4ba155c..c9e04b9e 100644
--- a/pylintrc
+++ b/pylintrc
@@ -74,9 +74,6 @@ disable=
too-many-ancestors,
# Formatting stuff
superfluous-parens,bad-continuation,
-# I'm fine deciding my own import order,
- wrong-import-position,
- wrong-import-order,
# Messages that are noisy for now, eventually maybe we'll turn them on:
invalid-name,
protected-access,
@@ -133,9 +130,9 @@ evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / stateme
# Special methods don't: __foo__
# Test methods don't: testXXXX
# TestCase overrides don't: setUp, tearDown
-# Nested decorator implementations: _decorator, _wrapped
+# Nested decorator implementations: _decorator, _wrapper
# Dispatched methods don't: _xxx__Xxxx
-no-docstring-rgx=__.*__|test[A-Z_].*|setUp|tearDown|_decorator|_wrapped|_.*__.*
+no-docstring-rgx=__.*__|test[A-Z_].*|setUp|tearDown|_decorator|_wrapper|_.*__.*
# Regular expression which should only match correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
diff --git a/setup.py b/setup.py
index accfd18f..af99b59b 100644
--- a/setup.py
+++ b/setup.py
@@ -9,10 +9,12 @@
import os
import sys
+# Setuptools has to be imported before distutils, or things break.
from setuptools import setup
-from distutils.core import Extension # pylint: disable=no-name-in-module, import-error
-from distutils.command.build_ext import build_ext # pylint: disable=no-name-in-module, import-error
-from distutils import errors # pylint: disable=no-name-in-module
+from distutils.core import Extension # pylint: disable=no-name-in-module, import-error, wrong-import-order
+from distutils.command.build_ext import build_ext # pylint: disable=no-name-in-module, import-error, wrong-import-order
+from distutils import errors # pylint: disable=no-name-in-module, wrong-import-order
+
# Get or massage our metadata. We exec coverage/version.py so we can avoid
# importing the product code into setup.py.
diff --git a/tests/conftest.py b/tests/conftest.py
index aeccec88..e9802517 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -7,9 +7,10 @@ Pytest auto configuration.
This module is run automatically by pytest, to define and enable fixtures.
"""
-import pytest
import warnings
+import pytest
+
from coverage import env
diff --git a/tests/coveragetest.py b/tests/coveragetest.py
index 15c61ece..378097c8 100644
--- a/tests/coveragetest.py
+++ b/tests/coveragetest.py
@@ -40,14 +40,13 @@ TESTS_DIR = os.path.dirname(__file__)
def convert_skip_exceptions(method):
"""A decorator for test methods to convert StopEverything to SkipTest."""
@functools.wraps(method)
- def wrapper(*args, **kwargs):
- """Run the test method, and convert exceptions."""
+ def _wrapper(*args, **kwargs):
try:
result = method(*args, **kwargs)
except StopEverything:
raise unittest.SkipTest("StopEverything!")
return result
- return wrapper
+ return _wrapper
class SkipConvertingMetaclass(type):
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
index 92867a54..db89137b 100644
--- a/tests/test_cmdline.py
+++ b/tests/test_cmdline.py
@@ -470,7 +470,7 @@ class CmdLineTest(BaseCmdLineTest):
# config file.
self.command_line("run --concurrency=multiprocessing --branch foo.py", ret=ERR)
self.assertIn(
- "Options affecting multiprocessing must be specified in a configuration file.",
+ "Options affecting multiprocessing must only be specified in a configuration file.",
self.stderr()
)