diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2015-05-17 18:36:30 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2015-05-17 18:36:30 -0400 |
commit | ca1a24ac46844ef83a7c1491659a1f36c8df37b1 (patch) | |
tree | 8ec4f7348cec7e561b983cb30ee01f8990cc557a | |
parent | ccc1b37086e04d65fbac880248fca3f57b42b901 (diff) | |
download | python-coveragepy-git-ca1a24ac46844ef83a7c1491659a1f36c8df37b1.tar.gz |
Use PyContracts so we can declare/enforce parameter and return types.
This commit doesn't add any uses of PyContracts, but gets the machinery in
place.
-rw-r--r-- | coverage/control.py | 15 | ||||
-rw-r--r-- | coverage/env.py | 5 | ||||
-rw-r--r-- | coverage/misc.py | 27 | ||||
-rw-r--r-- | igor.py | 1 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
-rw-r--r-- | tests/test_debug.py | 2 | ||||
-rw-r--r-- | tox.ini | 1 |
7 files changed, 45 insertions, 7 deletions
diff --git a/coverage/control.py b/coverage/control.py index 2c8d384e..defba56c 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -169,7 +169,7 @@ class Coverage(object): self.source_pkgs = self.file_locator = None self.data = self.collector = None self.plugins = self.file_tracing_plugins = None - self.pylib_dirs = self.cover_dir = None + self.pylib_dirs = self.cover_dirs = None self.data_suffix = self.run_suffix = None self._exclude_re = None self.debug = None @@ -301,7 +301,12 @@ class Coverage(object): # To avoid tracing the coverage code itself, we skip anything located # where we are. - self.cover_dir = self._canonical_dir(__file__) + self.cover_dirs = [self._canonical_dir(__file__)] + if env.TESTING: + # When testing, we use PyContracts, which should be considered + # part of coverage. + import contracts + self.cover_dirs.append(self._canonical_dir(contracts)) # Set the reporting precision. Numbers.set_precision(self.config.precision) @@ -315,8 +320,8 @@ class Coverage(object): self.source_match = TreeMatcher(self.source) self.source_pkgs_match = ModuleMatcher(self.source_pkgs) else: - if self.cover_dir: - self.cover_match = TreeMatcher([self.cover_dir]) + if self.cover_dirs: + self.cover_match = TreeMatcher(self.cover_dirs) if self.pylib_dirs: self.pylib_match = TreeMatcher(self.pylib_dirs) if self.include: @@ -1033,7 +1038,7 @@ class Coverage(object): info = [ ('version', covmod.__version__), ('coverage', covmod.__file__), - ('cover_dir', self.cover_dir), + ('cover_dirs', self.cover_dirs), ('pylib_dirs', self.pylib_dirs), ('tracer', self.collector.tracer_name()), ('file_tracing_plugins', ft_plugins), diff --git a/coverage/env.py b/coverage/env.py index 85ffa5ff..af78844e 100644 --- a/coverage/env.py +++ b/coverage/env.py @@ -15,7 +15,12 @@ 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', '') != '' + +# Are we running our test suite? +TESTING = os.getenv('COVERAGE_TESTING', '') != '' diff --git a/coverage/misc.py b/coverage/misc.py index d5197ea3..64111358 100644 --- a/coverage/misc.py +++ b/coverage/misc.py @@ -6,7 +6,32 @@ import inspect import os from coverage import env -from coverage.backward import string_class, to_bytes +from coverage.backward import string_class, to_bytes, unicode_class + + +# Use PyContracts for assertion testing on parameters and returns, but only if +# we are running our own test suite. +contract = None + +if env.TESTING: + try: + from contracts import contract + except ImportError: + pass + else: + from contracts import new_contract + + # Define contract words that PyContract doesn't have. + new_contract('bytes', lambda v: isinstance(v, bytes)) + if env.PY3: + new_contract('unicode', lambda v: isinstance(v, unicode_class)) + +if not contract: + # We aren't using real PyContracts, so just define a no-op decorator as a + # stunt double. + def contract(**unused): # pylint: disable=function-redefined + """Dummy no-op implementation of `contract`.""" + return lambda func: func def nice_pair(pair): @@ -60,6 +60,7 @@ def run_tests(tracer, *nose_args): print(msg) return + os.environ['COVERAGE_TESTING'] = "True" print_banner(label) nose_args = ["nosetests"] + list(nose_args) nose.core.main(argv=nose_args) diff --git a/requirements.txt b/requirements.txt index ab84656b..c02502da 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ # PyPI requirements for running tests for coverage.py nose mock +PyContracts pylint tox >= 1.9 diff --git a/tests/test_debug.py b/tests/test_debug.py index 8dd13a57..8576112d 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -116,7 +116,7 @@ class DebugTraceTest(CoverageTest): out_lines = self.f1_debug_output(["sys"]) labels = """ - version coverage cover_dir pylib_dirs tracer config_files + version coverage cover_dirs pylib_dirs tracer config_files configs_read data_path python platform implementation executable cwd path environment command_line cover_match pylib_match """.split() @@ -26,6 +26,7 @@ commands = deps = nose mock + PyContracts py26: unittest2 py26,py27: gevent py26,py27: eventlet |