diff options
-rw-r--r-- | CHANGES.txt | 3 | ||||
-rw-r--r-- | coverage/cmdline.py | 7 | ||||
-rw-r--r-- | coverage/control.py | 16 | ||||
-rw-r--r-- | test/test_coverage.py | 38 |
4 files changed, 58 insertions, 6 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 50ac0dd6..b1634ca8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,6 +10,9 @@ HTML reporting, and continued refactoring. - HTML reports and annotation of source files: use the new -b switch. Thanks
to George Song for code, inspiration and guidance.
+- Code in the Python standard library is not measured by default. If you need
+ to measure standard library code, use the -L switch during execution.
+
- Annotation into a directory (-a -d) behaves differently. The annotated files
are named with their hierarchy flattened so that same-named files from
different directories no longer collide. Also, only files in the current
diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 8c6688a8..39d92927 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -9,10 +9,11 @@ Coverage version %(__version__)s Usage: -coverage -x [-p] MODULE.py [ARG1 ARG2 ...] +coverage -x [-p] [-L] MODULE.py [ARG1 ARG2 ...] Execute the module, passing the given command-line arguments, collecting coverage data. With the -p option, include the machine name and process - ID in the .coverage file name. + ID in the .coverage file name. With -L, measure coverage even inside the + Python standard library, which isn't done by default. coverage -e Erase collected coverage data. @@ -86,6 +87,7 @@ class CoverageScript: '-e': 'erase', '-h': 'help', '-i': 'ignore-errors', + '-L': 'stdlib', '-m': 'show-missing', '-p': 'parallel-mode', '-r': 'report', @@ -135,6 +137,7 @@ class CoverageScript: # Do something. self.coverage.parallel_mode = settings.get('parallel-mode') + self.coverage.cover_stdlib = settings.get('stdlib') self.coverage.get_ready() if settings.get('erase'): diff --git a/coverage/control.py b/coverage/control.py index d03c69b3..6d3187d6 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -1,6 +1,6 @@ """Core control stuff for coverage.py""" -import os, socket +import os, socket, sys from coverage.annotate import AnnotateReporter from coverage.codeunit import code_unit_factory @@ -17,11 +17,13 @@ class coverage: self.parallel_mode = False self.exclude_re = '' + self.cover_stdlib = False self.nesting = 0 + self.file_locator = FileLocator() + self.sysprefix = self.file_locator.abs_file(sys.prefix) self.collector = Collector(self.should_trace) - self.data = CoverageData(collector="coverage.py v%s" % __version__) # The default exclude pattern. @@ -36,14 +38,20 @@ class coverage: Returns a canonicalized filename if it should be traced, False if it should not. + """ if filename == '<string>': # There's no point in ever tracing string executions, we can't do # anything with the data later anyway. return False - # TODO: flag: ignore std lib? + + canonical = self.file_locator.canonical_filename(filename) + if not self.cover_stdlib: + if canonical.startswith(self.sysprefix): + return False + # TODO: ignore by module as well as file? - return self.file_locator.canonical_filename(filename) + return canonical def use_cache(self, usecache): """Control the use of a data file (incorrectly called a cache). diff --git a/test/test_coverage.py b/test/test_coverage.py index f9f4c55f..cc30ecda 100644 --- a/test/test_coverage.py +++ b/test/test_coverage.py @@ -1688,6 +1688,44 @@ class ApiTest(CoverageTest): filename, _, _, _ = cov.analysis(sys.modules["mymod"]) self.assertEqual(os.path.basename(filename), "mymod.py") + def testIgnoreStdLib(self): + self.makeFile("mymain", """\ + import mymod, colorsys + a = 1 + hls = colorsys.rgb_to_hls(1.0, 0.5, 0.0) + """) + + self.makeFile("mymod", """\ + fooey = 17 + """) + + # Measure without the stdlib. + cov1 = coverage.coverage() + self.assertEqual(cov1.cover_stdlib, False) + cov1.start() + self.importModule("mymain") + cov1.stop() + + # some statements were marked executed in mymain.py + _, statements, missing, _ = cov1.analysis("mymain.py") + self.assertNotEqual(statements, missing) + # but none were in colorsys.py + _, statements, missing, _ = cov1.analysis("colorsys.py") + self.assertEqual(statements, missing) + + # Measure with the stdlib. + cov2 = coverage.coverage() + cov2.cover_stdlib = True + cov2.start() + self.importModule("mymain") + cov2.stop() + + # some statements were marked executed in mymain.py + _, statements, missing, _ = cov2.analysis("mymain.py") + self.assertNotEqual(statements, missing) + # and some were marked executed in colorsys.py + _, statements, missing, _ = cov2.analysis("colorsys.py") + self.assertNotEqual(statements, missing) class ProcessTest(CoverageTest): |