Skip to content

Commit

Permalink
Merge pull request #2788 from vkarak/enhancement/mode-combine-append-…
Browse files Browse the repository at this point in the history
…opts

[enhancement] Properly combine `append`-type command-line options defined in execution modes
  • Loading branch information
vkarak committed Feb 14, 2023
2 parents b6e14c6 + 990a6cc commit 723e8b2
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
2 changes: 2 additions & 0 deletions docs/config_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,8 @@ This handler transmits the whole log record, meaning that all the information wi



.. _exec-mode-config:

Execution Mode Configuration
----------------------------

Expand Down
11 changes: 9 additions & 2 deletions docs/manpage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,15 @@ Options controlling ReFrame execution

ReFrame execution mode to use.

An execution mode is simply a predefined invocation of ReFrame that is set with the :data:`modes` configuration parameter.
If an option is specified both in an execution mode and in the command-line, then command-line takes precedence.
An execution mode is simply a predefined set of options that is set in the :attr:`~modes` :ref:`configuration parameter <exec-mode-config>`.
Additional options can be passed to the command line, in which case they will be combined with the options defined in the selected execution mode.
More specifically, any additional ReFrame options will be *appended* to the command line options of the selected mode.
As a result, if a normal option is specified both inside the execution mode and the in the command line, the command line option will take precedence.
On the other hand, if an option that is allowed to be specified multiple times, e.g., the :option:`-S` option, is passed both inside the execution mode and in the command line, their values will be combined.
For example, if the execution mode ``foo`` defines ``-S modules=foo``, the invocation ``--mode=foo -S num_tasks=10`` is the equivalent of ``-S modules=foo -S num_tasks=10``.

.. versionchanged:: 4.1
Options that can be specified multiple times are now combined between execution modes and the command line.

.. option:: --repeat=N

Expand Down
17 changes: 14 additions & 3 deletions reframe/frontend/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import reframe.utility.typecheck as typ


#
# Notes on the ArgumentParser design
#
Expand Down Expand Up @@ -278,10 +279,20 @@ def parse_args(self, args=None, namespace=None):

# Update parser's defaults with groups' defaults
self._update_defaults()

# Update the parsed options of those from the given namespace and/or
# the defaults
for attr, val in options.__dict__.items():
if val is None:
options.__dict__[attr] = self._resolve_attr(
attr, [namespace, self._defaults]
)
resolved = self._resolve_attr(attr,
[namespace, self._defaults])
options.__dict__[attr] = resolved
elif self._option_map[attr][2] == 'append':
# 'append' options are combined with those from the given
# namespace, but *not* with the defaults (important)
resolved = self._resolve_attr(attr, [namespace])
if resolved is not None:
v = options.__dict__[attr]
options.__dict__[attr] = resolved + v

return _Namespace(options, self._option_map)
4 changes: 3 additions & 1 deletion unittests/test_argparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ def test_parsing(argparser, foo_options, bar_options):
'--bar beer --foolist any'.split(), options
)
assert 'name' == options.foo
assert ['any'] == options.foolist

# 'append' options are extended
assert ['gag', 'any'] == options.foolist
assert not options.foobar
assert not options.unfoo
assert 'beer' == options.bar
Expand Down

0 comments on commit 723e8b2

Please sign in to comment.