diff options
| -rw-r--r-- | coverage/__init__.py | 5 | ||||
| -rw-r--r-- | coverage/cmdline.py | 5 | ||||
| -rw-r--r-- | coverage/debug.py | 12 | ||||
| -rw-r--r-- | coverage/misc.py | 9 | ||||
| -rw-r--r-- | coverage/results.py | 4 | ||||
| -rw-r--r-- | coverage/sqldata.py | 6 | ||||
| -rw-r--r-- | doc/cmd.rst | 11 | ||||
| -rw-r--r-- | doc/trouble.rst | 15 | ||||
| -rw-r--r-- | howto.txt | 2 | ||||
| -rw-r--r-- | pylintrc | 7 | ||||
| -rw-r--r-- | setup.py | 8 | ||||
| -rw-r--r-- | tests/conftest.py | 3 | ||||
| -rw-r--r-- | tests/coveragetest.py | 5 | ||||
| -rw-r--r-- | tests/test_cmdline.py | 2 |
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? --------------------- @@ -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 @@ -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]+))$ @@ -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() ) |
