diff options
-rw-r--r-- | CHANGES.txt | 4 | ||||
-rw-r--r-- | coverage/config.py | 29 | ||||
-rw-r--r-- | tests/test_config.py | 10 |
3 files changed, 35 insertions, 8 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index ef7f7ea5..edefb09d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,7 +9,11 @@ Latest - Empty files are now reported as 100% covered in the XML report, not 0% covered, as reported in `issue 345`_. +- Regexes in the configuration file are now compiled as soon as they are read, + to provide error messages earlier. `issue 349`_. + .. _issue 345: https://bitbucket.org/ned/coveragepy/issue/345/xml-reports-line-rate-0-for-empty-files +.. _issue 349: https://bitbucket.org/ned/coveragepy/issue/349/bad-regex-in-config-should-get-an-earlier Version 4.0a2 --- 14 January 2014 diff --git a/coverage/config.py b/coverage/config.py index b14c6d6a..326389c7 100644 --- a/coverage/config.py +++ b/coverage/config.py @@ -95,17 +95,30 @@ class HandyConfigParser(configparser.RawConfigParser): values.append(value) return values - def getlinelist(self, section, option): - """Read a list of full-line strings. + def getregexlist(self, section, option): + """Read a list of full-line regexes. The value of `section` and `option` is treated as a newline-separated - list of strings. Each value is stripped of whitespace. + list of regexes. Each value is stripped of whitespace. Returns the list of strings. """ - value_list = self.get(section, option) - return list(filter(None, value_list.split('\n'))) + line_list = self.get(section, option) + value_list = [] + for value in line_list.splitlines(): + value = value.strip() + try: + re.compile(value) + except re.error as e: + raise CoverageException( + "Invalid [%s].%s value %r: %s" % ( + section, option, value, e + ) + ) + if value: + value_list.append(value) + return value_list # The default line exclusion regexes. @@ -252,13 +265,13 @@ class CoverageConfig(object): ('timid', 'run:timid', 'boolean'), # [report] - ('exclude_list', 'report:exclude_lines', 'linelist'), + ('exclude_list', 'report:exclude_lines', 'regexlist'), ('fail_under', 'report:fail_under', 'int'), ('ignore_errors', 'report:ignore_errors', 'boolean'), ('include', 'report:include', 'list'), ('omit', 'report:omit', 'list'), - ('partial_list', 'report:partial_branches', 'linelist'), - ('partial_always_list', 'report:partial_branches_always', 'linelist'), + ('partial_list', 'report:partial_branches', 'regexlist'), + ('partial_always_list', 'report:partial_branches_always', 'regexlist'), ('precision', 'report:precision', 'int'), ('show_missing', 'report:show_missing', 'boolean'), ('skip_covered', 'report:skip_covered', 'boolean'), diff --git a/tests/test_config.py b/tests/test_config.py index ee4db966..65586846 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -96,6 +96,16 @@ class ConfigTest(CoverageTest): ("[run]\ntimid = maybe?\n", r"maybe[?]"), ("timid = 1\n", r"timid = 1"), ("[run\n", r"\[run"), + ("[report]\nexclude_lines = foo(\n", + r"Invalid \[report\].exclude_lines value 'foo\(': " + r"unbalanced parenthesis"), + ("[report]\npartial_branches = foo[\n", + r"Invalid \[report\].partial_branches value 'foo\[': " + r"unexpected end of regular expression"), + ("[report]\npartial_branches_always = foo***\n", + r"Invalid \[report\].partial_branches_always value " + r"'foo\*\*\*': " + r"multiple repeat"), ] for bad_config, msg in bad_configs_and_msgs: |