Skip to content

Commit

Permalink
ShellCalculation: Resolve escaped curly braces in arguments
Browse files Browse the repository at this point in the history
Any argument that did not contain a placeholder would simply be appended
as is, but this would cause escaped curly braces not to be resolved. The
solution is to just call `argument.format()` in this case, letting the
string formatter take care of resolving the escaped characters.
  • Loading branch information
sphuber committed Sep 4, 2024
1 parent 2ab8219 commit 87e2f85
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
18 changes: 18 additions & 0 deletions docs/source/howto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ To pass arguments to the shell command, pass them as a string to the ``arguments
which should print something like ``2022-03-17``.

.. tip::

Curly braces ``{}`` carry specific meaning in ``arguments`` and are considered as placeholders for input files (see :ref:`this section <how-to:running-a-shell-command-with-files-as-arguments>`).
If you need literal curly braces, escape them by doubling them, `just as you would for a normal f-string<https://docs.python.org/3/library/string.html#format-string-syntax>`_:

.. code::
from aiida_shell import launch_shell_job
results, node = launch_shell_job(
'echo',
arguments='some{{curly}}braces',
)
print(results['stdout'].get_content())
which prints ``some{curly}braces``.


.. _how-to:running-a-shell-command-with-files-as-arguments:

Running a shell command with files as arguments
===============================================
Expand Down
2 changes: 1 addition & 1 deletion src/aiida_shell/calculations/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def process_arguments_and_nodes(

# If the argument contains no placeholders simply append the argument and continue.
if not field_names:
processed_arguments.append(argument)
processed_arguments.append(argument.format())
continue

# Otherwise we validate that there is exactly one placeholder and that a ``SinglefileData`` input node is
Expand Down
12 changes: 12 additions & 0 deletions tests/calculations/test_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,18 @@ def test_arguments_files_filenames(generate_calc_job, generate_code):
assert code_info.cmdline_params == ['custom_filename']


def test_arguments_escaped_braces(generate_calc_job, generate_code):
"""Test the ``arguments`` with arguments containing escaped curly braces."""
arguments = List(['some{{escaped}}braces'])
inputs = {
'code': generate_code(),
'arguments': arguments,
}
_, calc_info = generate_calc_job('core.shell', inputs)
code_info = calc_info.codes_info[0]
assert code_info.cmdline_params == ['some{escaped}braces']


def test_output_filename(generate_calc_job, generate_code, file_regression):
"""Test the ``metadata.options.output_filename`` input."""
output_filename = 'custom_stdout'
Expand Down

0 comments on commit 87e2f85

Please sign in to comment.