Skip to content

Commit 79cda63

Browse files
seismanyvonnefroehlichweiji14
authored
Add function build_arg_list for building arguments list from keyword dictionaries (#3149)
Co-authored-by: Yvonne Fröhlich <[email protected]> Co-authored-by: Wei Ji <[email protected]>
1 parent a32049d commit 79cda63

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

pygmt/helpers/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
)
1717
from pygmt.helpers.utils import (
1818
args_in_kwargs,
19+
build_arg_list,
1920
build_arg_string,
2021
data_kind,
2122
is_nonstr_iter,

pygmt/helpers/decorators.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ def kwargs_to_strings(**conversions):
622622
The strings are what GMT expects from command line arguments.
623623
624624
Boolean arguments and None are not converted and will be processed in the
625-
``build_arg_string`` function.
625+
``build_arg_list`` function.
626626
627627
You can also specify other conversions to specific arguments.
628628

pygmt/helpers/utils.py

+104-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
import sys
1212
import time
1313
import webbrowser
14-
from collections.abc import Iterable
14+
from collections.abc import Iterable, Sequence
15+
from typing import Any
1516

1617
import xarray as xr
1718
from pygmt.exceptions import GMTInvalidInput
@@ -315,6 +316,108 @@ def non_ascii_to_octal(argstr):
315316
return argstr.translate(str.maketrans(mapping))
316317

317318

319+
def build_arg_list(
320+
kwdict: dict[str, Any],
321+
confdict: dict[str, str] | None = None,
322+
infile: str | pathlib.PurePath | Sequence[str | pathlib.PurePath] | None = None,
323+
outfile: str | pathlib.PurePath | None = None,
324+
) -> list[str]:
325+
r"""
326+
Convert keyword dictionaries and input/output files into a list of GMT arguments.
327+
328+
Make sure all values in ``kwdict`` have been previously converted to a string
329+
representation using the ``kwargs_to_strings`` decorator. The only exceptions are
330+
``True``, ``False`` and ``None``.
331+
332+
Any remaining lists or tuples will be interpreted as multiple entries for the same
333+
parameter. For example, the kwargs entry ``"B": ["xa", "yaf"]`` will be
334+
converted to ``["-Bxa", "-Byaf"]``.
335+
336+
Parameters
337+
----------
338+
kwdict
339+
A dictionary containing parsed keyword arguments.
340+
confdict
341+
A dictionary containing configurable GMT parameters.
342+
infile
343+
The input file or a list of input files.
344+
outfile
345+
The output file.
346+
347+
Returns
348+
-------
349+
args
350+
The list of command line arguments that will be passed to GMT modules. The
351+
keyword arguments are sorted alphabetically, followed by GMT configuration
352+
key-value pairs, with optional input file(s) at the beginning and optional
353+
output file at the end.
354+
355+
Examples
356+
--------
357+
>>> build_arg_list(dict(A=True, B=False, C=None, D=0, E=200, F="", G="1/2/3/4"))
358+
['-A', '-D0', '-E200', '-F', '-G1/2/3/4']
359+
>>> build_arg_list(dict(A="1/2/3/4", B=["xaf", "yaf", "WSen"], C=("1p", "2p")))
360+
['-A1/2/3/4', '-BWSen', '-Bxaf', '-Byaf', '-C1p', '-C2p']
361+
>>> print(
362+
... build_arg_list(
363+
... dict(
364+
... B=["af", "WSne+tBlank Space"],
365+
... F='+t"Empty Spaces"',
366+
... l="'Void Space'",
367+
... )
368+
... )
369+
... )
370+
['-BWSne+tBlank Space', '-Baf', '-F+t"Empty Spaces"', "-l'Void Space'"]
371+
>>> print(
372+
... build_arg_list(
373+
... dict(A="0", B=True, C="rainbow"),
374+
... confdict=dict(FORMAT_DATE_MAP="o dd"),
375+
... infile="input.txt",
376+
... outfile="output.txt",
377+
... )
378+
... )
379+
['input.txt', '-A0', '-B', '-Crainbow', '--FORMAT_DATE_MAP=o dd', '->output.txt']
380+
>>> print(
381+
... build_arg_list(
382+
... dict(A="0", B=True),
383+
... confdict=dict(FORMAT_DATE_MAP="o dd"),
384+
... infile=["f1.txt", "f2.txt"],
385+
... outfile="out.txt",
386+
... )
387+
... )
388+
['f1.txt', 'f2.txt', '-A0', '-B', '--FORMAT_DATE_MAP=o dd', '->out.txt']
389+
>>> print(build_arg_list(dict(R="1/2/3/4", J="X4i", watre=True)))
390+
Traceback (most recent call last):
391+
...
392+
pygmt.exceptions.GMTInvalidInput: Unrecognized parameter 'watre'.
393+
"""
394+
gmt_args = []
395+
for key, value in kwdict.items():
396+
if len(key) > 2: # Raise an exception for unrecognized options
397+
raise GMTInvalidInput(f"Unrecognized parameter '{key}'.")
398+
if value is None or value is False: # Exclude arguments that are None or False
399+
pass
400+
elif value is True:
401+
gmt_args.append(f"-{key}")
402+
elif is_nonstr_iter(value):
403+
gmt_args.extend(non_ascii_to_octal(f"-{key}{_value}") for _value in value)
404+
else:
405+
gmt_args.append(non_ascii_to_octal(f"-{key}{value}"))
406+
gmt_args = sorted(gmt_args)
407+
408+
if confdict:
409+
gmt_args.extend(f"--{key}={value}" for key, value in confdict.items())
410+
411+
if infile: # infile can be a single file or a list of files
412+
if isinstance(infile, str | pathlib.PurePath):
413+
gmt_args = [str(infile), *gmt_args]
414+
else:
415+
gmt_args = [str(_file) for _file in infile] + gmt_args
416+
if outfile:
417+
gmt_args.append(f"->{outfile}")
418+
return gmt_args
419+
420+
318421
def build_arg_string(kwdict, confdict=None, infile=None, outfile=None):
319422
r"""
320423
Convert keyword dictionaries and input/output files into a GMT argument string.

0 commit comments

Comments
 (0)