diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2018-09-08 16:56:08 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2018-09-08 20:12:20 -0400 |
commit | 69d106fec5ac2e9aba1146c0004d961e8cb903f5 (patch) | |
tree | 25e385c4ed07dcf0b7d73e6c81bedc939b916baf | |
parent | c001d1676de46aef12f80a21675937756e594acf (diff) | |
download | python-coveragepy-git-69d106fec5ac2e9aba1146c0004d961e8cb903f5.tar.gz |
Defaultable variable substitution
-rw-r--r-- | CHANGES.rst | 7 | ||||
-rw-r--r-- | coverage/misc.py | 15 | ||||
-rw-r--r-- | doc/config.rst | 15 | ||||
-rw-r--r-- | tests/test_misc.py | 1 |
4 files changed, 26 insertions, 12 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 23aa0921..8f8cd32b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -17,9 +17,10 @@ Change history for Coverage.py Unreleased ---------- -- Environment variable substitution in configuration files can now be strict: - using a question mark suffix like ``${VARNAME?}`` will raise an error if - ``VARNAME`` is not defined as an environment variable. +- Environment variable substitution in configuration files now supports two + syntaxes for controlling the behavior of undefined variables: if ``VARNAME`` + is not defined, ``${VARNAME?}`` will raise an error, and ``${VARNAME-default + value}`` will use "default value". .. _changes_50a2: diff --git a/coverage/misc.py b/coverage/misc.py index 037332f5..7b8fbb93 100644 --- a/coverage/misc.py +++ b/coverage/misc.py @@ -258,7 +258,8 @@ def substitute_variables(text, variables=os.environ): $VAR ${VAR} - ${VAR?} strict: an error if VAR isn't defined. + ${VAR?} strict: an error if VAR isn't defined. + ${VAR-missing} defaulted: "missing" if VAR isn't defined. A dollar can be inserted with ``$$``. @@ -280,16 +281,20 @@ def substitute_variables(text, variables=os.environ): if word not in variables: msg = "Variable {} is undefined: {}".format(word, text) raise CoverageException(msg) - return variables.get(word, '') + return variables.get(word, m.group('defval') or '') dollar_pattern = r"""(?x) # Use extended regex syntax \$(?: # A dollar sign, then (?P<v1>\w+) | # a plain word, + (?P<char>\$) | # or a dollar sign. { # or a {-wrapped word, (?P<v2>\w+) - (?P<strict>\??) # with maybe a strict marker - } | - (?P<char>[$]) # or a dollar sign. + (?: + (?P<strict>\?) # with a strict marker + | + -(?P<defval>[^}]*) # or a default value + )? + } ) """ text = re.sub(dollar_pattern, dollar_replace, text) diff --git a/doc/config.rst b/doc/config.rst index ab874619..666a1321 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -59,10 +59,17 @@ or ``0`` and are case-insensitive. Environment variables can be substituted in by using dollar signs: ``$WORD`` or ``${WORD}`` will be replaced with the value of ``WORD`` in the environment. -A dollar sign can be inserted with ``$$``. If you want to raise an error if -an environment variable is undefined, use a question mark suffix: ``${WORD?}``. -Otherwise, missing environment variables will result in empty strings with no -error. +A dollar sign can be inserted with ``$$``. Special forms can be used to +control what happens if the variable isn't defined in the environment: + +- If you want to raise an error if an environment variable is undefined, use a + question mark suffix: ``${WORD?}``. + +- If you want to provide a default for missing variables, use a dash with a + default value: ``${WORD-default value}``. + +- Otherwise, missing environment variables will result in empty strings with no + error. Many sections and values correspond roughly to commands and options in the :ref:`command-line interface <cmd>`. diff --git a/tests/test_misc.py b/tests/test_misc.py index 65476928..c8c2c9e4 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -152,6 +152,7 @@ VARS = { ("Multiple: $$ $FOO $BAR ${FOO}", "Multiple: $ fooey xyzzy fooey"), ("Ill-formed: ${%5} ${{HI}} ${", "Ill-formed: ${%5} ${{HI}} ${"), ("Strict: ${FOO?} is there", "Strict: fooey is there"), + ("Defaulted: ${WUT-missing}!", "Defaulted: missing!"), ]) def test_substitute_variables(before, after): assert substitute_variables(before, VARS) == after |