Skip to content

Commit 69d106f

Browse files
committed
Defaultable variable substitution
1 parent c001d16 commit 69d106f

File tree

4 files changed

+26
-12
lines changed

4 files changed

+26
-12
lines changed

CHANGES.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ Change history for Coverage.py
1717
Unreleased
1818
----------
1919

20-
- Environment variable substitution in configuration files can now be strict:
21-
using a question mark suffix like ``${VARNAME?}`` will raise an error if
22-
``VARNAME`` is not defined as an environment variable.
20+
- Environment variable substitution in configuration files now supports two
21+
syntaxes for controlling the behavior of undefined variables: if ``VARNAME``
22+
is not defined, ``${VARNAME?}`` will raise an error, and ``${VARNAME-default
23+
value}`` will use "default value".
2324

2425

2526
.. _changes_50a2:

coverage/misc.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ def substitute_variables(text, variables=os.environ):
258258
259259
$VAR
260260
${VAR}
261-
${VAR?} strict: an error if VAR isn't defined.
261+
${VAR?} strict: an error if VAR isn't defined.
262+
${VAR-missing} defaulted: "missing" if VAR isn't defined.
262263
263264
A dollar can be inserted with ``$$``.
264265
@@ -280,16 +281,20 @@ def dollar_replace(m):
280281
if word not in variables:
281282
msg = "Variable {} is undefined: {}".format(word, text)
282283
raise CoverageException(msg)
283-
return variables.get(word, '')
284+
return variables.get(word, m.group('defval') or '')
284285

285286
dollar_pattern = r"""(?x) # Use extended regex syntax
286287
\$(?: # A dollar sign, then
287288
(?P<v1>\w+) | # a plain word,
289+
(?P<char>\$) | # or a dollar sign.
288290
{ # or a {-wrapped word,
289291
(?P<v2>\w+)
290-
(?P<strict>\??) # with maybe a strict marker
291-
} |
292-
(?P<char>[$]) # or a dollar sign.
292+
(?:
293+
(?P<strict>\?) # with a strict marker
294+
|
295+
-(?P<defval>[^}]*) # or a default value
296+
)?
297+
}
293298
)
294299
"""
295300
text = re.sub(dollar_pattern, dollar_replace, text)

doc/config.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,17 @@ or ``0`` and are case-insensitive.
5959

6060
Environment variables can be substituted in by using dollar signs: ``$WORD``
6161
or ``${WORD}`` will be replaced with the value of ``WORD`` in the environment.
62-
A dollar sign can be inserted with ``$$``. If you want to raise an error if
63-
an environment variable is undefined, use a question mark suffix: ``${WORD?}``.
64-
Otherwise, missing environment variables will result in empty strings with no
65-
error.
62+
A dollar sign can be inserted with ``$$``. Special forms can be used to
63+
control what happens if the variable isn't defined in the environment:
64+
65+
- If you want to raise an error if an environment variable is undefined, use a
66+
question mark suffix: ``${WORD?}``.
67+
68+
- If you want to provide a default for missing variables, use a dash with a
69+
default value: ``${WORD-default value}``.
70+
71+
- Otherwise, missing environment variables will result in empty strings with no
72+
error.
6673

6774
Many sections and values correspond roughly to commands and options in
6875
the :ref:`command-line interface <cmd>`.

tests/test_misc.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ def test_format_lines(statements, lines, result):
152152
("Multiple: $$ $FOO $BAR ${FOO}", "Multiple: $ fooey xyzzy fooey"),
153153
("Ill-formed: ${%5} ${{HI}} ${", "Ill-formed: ${%5} ${{HI}} ${"),
154154
("Strict: ${FOO?} is there", "Strict: fooey is there"),
155+
("Defaulted: ${WUT-missing}!", "Defaulted: missing!"),
155156
])
156157
def test_substitute_variables(before, after):
157158
assert substitute_variables(before, VARS) == after

0 commit comments

Comments
 (0)