From 44f983fd0d520972b0f792c6ea6dfe4cd368d0dc Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Thu, 18 Jan 2024 16:47:07 +0800 Subject: [PATCH 1/6] Figure.coast: Use long names ("crude"/"low"/"intermediate"/"high"/"full") for the 'resolution' parameter --- examples/tutorials/basics/coastlines.py | 26 +++++++++++-------------- pygmt/src/coast.py | 23 +++++++++++++++++----- pygmt/tests/test_coast.py | 2 +- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/examples/tutorials/basics/coastlines.py b/examples/tutorials/basics/coastlines.py index 5e611b3e2d3..d1e4fa4399d 100644 --- a/examples/tutorials/basics/coastlines.py +++ b/examples/tutorials/basics/coastlines.py @@ -27,9 +27,9 @@ # 3. island-in-lake shore # 4. lake-in-island-in-lake shore # -# You can specify which level you want to plot by passing the level number and -# a GMT pen configuration. For example, to plot just the coastlines with 0.5p -# thickness and black lines: +# You can specify which level you want to plot by passing the level number and a GMT +# pen configuration. For example, to plot just the coastlines with 0.5p thickness and +# black lines: fig = pygmt.Figure() fig.basemap(region="g", projection="W15c", frame=True) @@ -50,18 +50,14 @@ # Resolutions # ----------- # -# The coastline database comes with 5 resolutions. The resolution drops by 80% -# between levels: -# -# 1. ``"c"``: crude -# 2. ``"l"``: low (default) -# 3. ``"i"``: intermediate -# 4. ``"h"``: high -# 5. ``"f"``: full +# The coastline database comes with 5 resolutions: ``"full"``, ``"high"``, +# ``"intermediate"``, ``"low"``, and ``"crude"``. The resolution drops by 80% between +# levels. The ``resolution`` parameter defaults to ``"auto"`` to automatically select +# the best resolution given the chosen map scale. oahu = [-158.3, -157.6, 21.2, 21.8] fig = pygmt.Figure() -for res in ["c", "l", "i", "h", "f"]: +for res in ["crude", "low", "intermediate", "high", "full"]: fig.coast(resolution=res, shorelines="1p", region=oahu, projection="M5c") fig.shift_origin(xshift="5c") fig.show() @@ -71,9 +67,9 @@ # Land and water # -------------- # -# Use the ``land`` and ``water`` parameters to specify a fill color for land -# and water bodies. The colors can be given by name or hex codes (like the ones -# used in HTML and CSS): +# Use the ``land`` and ``water`` parameters to specify a fill color for land and water +# bodies. The colors can be given by name or hex codes (like the ones used in HTML and +# CSS): fig = pygmt.Figure() fig.basemap(region="g", projection="W15c", frame=True) diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index 87a99692541..d7ad8ea7d29 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -2,6 +2,8 @@ coast - Plot land and water. """ +from typing import Literal + from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import ( @@ -37,7 +39,13 @@ t="transparency", ) @kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence") -def coast(self, **kwargs): +def coast( + self, + resolution: Literal[ # noqa: ARG001 + "auto", "full", "high", "intermediate", "low", "crude" + ] = "auto", + **kwargs, +): r""" Plot continents, shorelines, rivers, and borders on maps. @@ -73,10 +81,11 @@ def coast(self, **kwargs): parameter. Optionally, specify separate fills by appending **+l** for lakes or **+r** for river-lakes, and passing multiple strings in a list. - resolution : str - **f**\|\ **h**\|\ **i**\|\ **l**\|\ **c**. - Select the resolution of the data set to: (**f**\ )ull, (**h**\ )igh, - (**i**\ )ntermediate, (**l**\ )ow, and (**c**\ )rude. + resolution + Select the resolution of the coastline dataset to use. The available resolutions + from highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``, + ``"low"``, and ``"crude"``. Default is ``"auto"`` to automatically select the + most suitable resolution given the chosen map scale. land : str Select filling of "dry" areas. rivers : int, str, or list @@ -199,5 +208,9 @@ def coast(self, **kwargs): """At least one of the following parameters must be specified: lakes, land, water, rivers, borders, dcw, Q, or shorelines""" ) + # resolution + if kwargs.get("D") is not None: + kwargs["D"] = kwargs["D"][0] + with Session() as lib: lib.call_module(module="coast", args=build_arg_list(kwargs)) diff --git a/pygmt/tests/test_coast.py b/pygmt/tests/test_coast.py index 780ec63cace..64153e8e36e 100644 --- a/pygmt/tests/test_coast.py +++ b/pygmt/tests/test_coast.py @@ -29,7 +29,7 @@ def test_coast_world_mercator(): projection="M15c", frame="af", land="#aaaaaa", - resolution="c", + resolution="crude", water="white", ) return fig From 4fae7459d12ced88f919aee04658448146495b32 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Mon, 22 Jul 2024 23:07:40 +0800 Subject: [PATCH 2/6] Also improve select and grdlandmask --- pygmt/src/coast.py | 8 +++++--- pygmt/src/grdlandmask.py | 30 ++++++++++++++++++------------ pygmt/src/select.py | 22 ++++++++++++---------- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index d7ad8ea7d29..e456fc74a55 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -84,8 +84,9 @@ def coast( resolution Select the resolution of the coastline dataset to use. The available resolutions from highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``, - ``"low"``, and ``"crude"``. Default is ``"auto"`` to automatically select the - most suitable resolution given the chosen map scale. + ``"low"``, and ``"crude"``, which drops by 80% between levels. Default is + ``"auto"`` to automatically select the most suitable resolution given the chosen + map scale. land : str Select filling of "dry" areas. rivers : int, str, or list @@ -208,7 +209,8 @@ def coast( """At least one of the following parameters must be specified: lakes, land, water, rivers, borders, dcw, Q, or shorelines""" ) - # resolution + + # Resolution if kwargs.get("D") is not None: kwargs["D"] = kwargs["D"][0] diff --git a/pygmt/src/grdlandmask.py b/pygmt/src/grdlandmask.py index 5244c89eca2..fd8a539a8fa 100644 --- a/pygmt/src/grdlandmask.py +++ b/pygmt/src/grdlandmask.py @@ -2,6 +2,8 @@ grdlandmask - Create a "wet-dry" mask grid from shoreline data base """ +from typing import Literal + import xarray as xr from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput @@ -23,7 +25,11 @@ x="cores", ) @kwargs_to_strings(I="sequence", R="sequence", N="sequence", E="sequence") -def grdlandmask(outgrid: str | None = None, **kwargs) -> xr.DataArray | None: +def grdlandmask( + outgrid: str | None = None, + resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", # noqa: ARG001 + **kwargs, +) -> xr.DataArray | None: r""" Create a grid file with set values for land and water. @@ -44,17 +50,13 @@ def grdlandmask(outgrid: str | None = None, **kwargs) -> xr.DataArray | None: {spacing} {region} {area_thresh} - resolution : str - *res*\[\ **+f**\]. Select the resolution of the data set to use - ((**f**)ull, (**h**)igh, (**i**)ntermediate, (**l**)ow, or - (**c**)rude). The resolution drops off by ~80% between data sets. - [Default is **l**]. Append **+f** to automatically select a lower - resolution should the one requested not be available - [abort if not found]. Alternatively, choose (**a**)uto to automatically - select the best resolution given the chosen region. Note that because - the coastlines differ in details a node in a mask file using one - resolution is not guaranteed to remain inside [or outside] when a - different resolution is selected. + resolution + Ignored unless ``mask`` is set. Select the resolution of the coastline dataset + to use. The available resolutions from highest to lowest are: ``"full"``, + ``"high"``, ``"intermediate"``, ``"low"``, and ``"crude"``, which drops by 80% + between levels. Note that because the coastlines differ in details it is not + guaranteed that a point will remain inside [or outside] when a different + resolution is selected. bordervalues : bool, str, float, or list Nodes that fall exactly on a polygon boundary should be considered to be outside the polygon [Default considers them to be @@ -98,6 +100,10 @@ def grdlandmask(outgrid: str | None = None, **kwargs) -> xr.DataArray | None: if kwargs.get("I") is None or kwargs.get("R") is None: raise GMTInvalidInput("Both 'region' and 'spacing' must be specified.") + # Resolution + if kwargs.get("D") is not None: + kwargs["D"] = kwargs["D"][0] + with Session() as lib: with lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd: kwargs["G"] = voutgrd diff --git a/pygmt/src/select.py b/pygmt/src/select.py index ecd6d12bfad..c54c2fdf3a5 100644 --- a/pygmt/src/select.py +++ b/pygmt/src/select.py @@ -48,6 +48,7 @@ def select( data=None, output_type: Literal["pandas", "numpy", "file"] = "pandas", outfile: str | None = None, + resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", # noqa: ARG001 **kwargs, ) -> pd.DataFrame | np.ndarray | None: r""" @@ -116,16 +117,13 @@ def select( ` *polygonfile*. For spherical polygons (lon, lat), make sure no consecutive points are separated by 180 degrees or more in longitude. - resolution : str - *resolution*\ [**+f**]. - Ignored unless ``mask`` is set. Selects the resolution of the coastline - data set to use ((**f**)ull, (**h**)igh, (**i**)ntermediate, (**l**)ow, - or (**c**)rude). The resolution drops off by ~80% between data sets. - [Default is **l**]. Append (**+f**) to automatically select a lower - resolution should the one requested not be available [Default is abort - if not found]. Note that because the coastlines differ in details - it is not guaranteed that a point will remain inside [or outside] when - a different resolution is selected. + resolution + Ignored unless ``mask`` is set. Select the resolution of the coastline dataset + to use. The available resolutions from highest to lowest are: ``"full"``, + ``"high"``, ``"intermediate"``, ``"low"``, and ``"crude"``, which drops by 80% + between levels. Note that because the coastlines differ in details it is not + guaranteed that a point will remain inside [or outside] when a different + resolution is selected. gridmask : str Pass all locations that are inside the valid data area of the grid *gridmask*. Nodes that are outside are either NaN or zero. @@ -205,6 +203,10 @@ def select( >>> # longitudes 246 and 247 and latitudes 20 and 21 >>> out = pygmt.select(data=ship_data, region=[246, 247, 20, 21]) """ + # Resolution + if kwargs.get("D") is not None: + kwargs["D"] = kwargs["D"][0] + output_type = validate_output_table_type(output_type, outfile=outfile) column_names = None From 5fac3ae086fa09c84b52fd1d2eaabc63774d6998 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 29 Sep 2024 18:49:03 +0800 Subject: [PATCH 3/6] Remove the old aliases --- pygmt/src/coast.py | 8 +++----- pygmt/src/grdlandmask.py | 9 +++------ pygmt/src/select.py | 8 +++----- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index e456fc74a55..fe0a034ec30 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -22,7 +22,6 @@ A="area_thresh", B="frame", C="lakes", - D="resolution", E="dcw", F="box", G="land", @@ -41,7 +40,7 @@ @kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence") def coast( self, - resolution: Literal[ # noqa: ARG001 + resolution: Literal[ "auto", "full", "high", "intermediate", "low", "crude" ] = "auto", **kwargs, @@ -210,9 +209,8 @@ def coast( lakes, land, water, rivers, borders, dcw, Q, or shorelines""" ) - # Resolution - if kwargs.get("D") is not None: - kwargs["D"] = kwargs["D"][0] + # Alias 'resolution' to "D". + kwargs["D"] = resolution[0] with Session() as lib: lib.call_module(module="coast", args=build_arg_list(kwargs)) diff --git a/pygmt/src/grdlandmask.py b/pygmt/src/grdlandmask.py index fd8a539a8fa..b99b13497ad 100644 --- a/pygmt/src/grdlandmask.py +++ b/pygmt/src/grdlandmask.py @@ -15,7 +15,6 @@ @fmt_docstring @use_alias( A="area_thresh", - D="resolution", E="bordervalues", I="spacing", N="maskvalues", @@ -27,7 +26,7 @@ @kwargs_to_strings(I="sequence", R="sequence", N="sequence", E="sequence") def grdlandmask( outgrid: str | None = None, - resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", # noqa: ARG001 + resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", **kwargs, ) -> xr.DataArray | None: r""" @@ -100,10 +99,8 @@ def grdlandmask( if kwargs.get("I") is None or kwargs.get("R") is None: raise GMTInvalidInput("Both 'region' and 'spacing' must be specified.") - # Resolution - if kwargs.get("D") is not None: - kwargs["D"] = kwargs["D"][0] - + # Alias "resolution" to "D" + kwargs["D"] = resolution[0] with Session() as lib: with lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd: kwargs["G"] = voutgrd diff --git a/pygmt/src/select.py b/pygmt/src/select.py index c54c2fdf3a5..21d2c856217 100644 --- a/pygmt/src/select.py +++ b/pygmt/src/select.py @@ -22,7 +22,6 @@ @use_alias( A="area_thresh", C="dist2pt", - D="resolution", F="polygon", G="gridmask", I="reverse", @@ -48,7 +47,7 @@ def select( data=None, output_type: Literal["pandas", "numpy", "file"] = "pandas", outfile: str | None = None, - resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", # noqa: ARG001 + resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", **kwargs, ) -> pd.DataFrame | np.ndarray | None: r""" @@ -203,9 +202,8 @@ def select( >>> # longitudes 246 and 247 and latitudes 20 and 21 >>> out = pygmt.select(data=ship_data, region=[246, 247, 20, 21]) """ - # Resolution - if kwargs.get("D") is not None: - kwargs["D"] = kwargs["D"][0] + # Alias "resolution" to "D" + kwargs["D"] = resolution[0] output_type = validate_output_table_type(output_type, outfile=outfile) From 5e1ebe82aa7a3c3d1f0364898bf4208071d7b1a6 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 29 Oct 2024 13:01:11 +0800 Subject: [PATCH 4/6] Move the parser function into _common.py --- pygmt/src/_common.py | 59 +++++++++++++++++++++++++++++++++++++++- pygmt/src/coast.py | 12 ++++---- pygmt/src/grdlandmask.py | 7 +++-- pygmt/src/select.py | 6 ++-- 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/pygmt/src/_common.py b/pygmt/src/_common.py index 96ae9791b71..b3842cc5cf9 100644 --- a/pygmt/src/_common.py +++ b/pygmt/src/_common.py @@ -3,8 +3,9 @@ """ from pathlib import Path -from typing import Any +from typing import Any, Literal +from pygmt.exceptions import GMTInvalidInput from pygmt.src.which import which @@ -39,3 +40,59 @@ def _data_geometry_is_point(data: Any, kind: str) -> bool: except FileNotFoundError: pass return False + + +def _parse_coastline_resolution( + resolution: Literal["auto", "full", "high", "intermediate", "low", "crude", None], + allow_auto: bool = False, +) -> str | None: + """ + Parse the resolution parameter for coastline-related functions. + + Parameters + ---------- + resolution + The resolution of the coastline dataset to use. The available resolutions from + highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``, ``"low"``, + and ``"crude"``, which drops by 80% between levels. + allow_auto + Whether to allow the ``"auto"`` resolution. + + Returns + ------- + str or None + The parsed resolution value. + + Raises + ------ + GMTInvalidInput + If the resolution is invalid. + + Examples + -------- + >>> _parse_coastline_resolution("full") + "f" + >>> _parse_coastline_resolution("f") + "f" + >>> _parse_coastline_resolution("auto", allow_auto=True) + "a" + >>> _parse_coastline_resolution("invalid") + pygmt.exceptions.GMTInvalidInput: Invalid resolution: invalid. Valid values are ... + >>> _parse_coastline_resolution(None) + None + >>> _parse_coastline_resolution("auto") + pygmt.exceptions.GMTInvalidInput: Invalid resolution: auto. Valid values are ... + """ + if resolution is None: + return None + + valid_resolutions = {"full", "high", "intermediate", "low", "crude"} + if allow_auto: + valid_resolutions.add("auto") + if resolution not in {*valid_resolutions, *[res[0] for res in valid_resolutions]}: + msg = ( + f"Invalid resolution: {resolution}." + f"Valid values are {', '.join(valid_resolutions)}." + ) + raise GMTInvalidInput(msg) + return resolution[0] diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index fe0a034ec30..1c5cbfc147f 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -13,6 +13,7 @@ kwargs_to_strings, use_alias, ) +from pygmt.src._common import _parse_coastline_resolution __doctest_skip__ = ["coast"] @@ -41,8 +42,8 @@ def coast( self, resolution: Literal[ - "auto", "full", "high", "intermediate", "low", "crude" - ] = "auto", + "auto", "full", "high", "intermediate", "low", "crude", None + ] = None, **kwargs, ): r""" @@ -208,9 +209,8 @@ def coast( """At least one of the following parameters must be specified: lakes, land, water, rivers, borders, dcw, Q, or shorelines""" ) - - # Alias 'resolution' to "D". - kwargs["D"] = resolution[0] - + kwargs["D"] = kwargs.get( + "D", _parse_coastline_resolution(resolution, allow_auto=True) + ) with Session() as lib: lib.call_module(module="coast", args=build_arg_list(kwargs)) diff --git a/pygmt/src/grdlandmask.py b/pygmt/src/grdlandmask.py index b99b13497ad..a654a3b4e62 100644 --- a/pygmt/src/grdlandmask.py +++ b/pygmt/src/grdlandmask.py @@ -8,6 +8,7 @@ from pygmt.clib import Session from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import build_arg_list, fmt_docstring, kwargs_to_strings, use_alias +from pygmt.src._common import _parse_coastline_resolution __doctest_skip__ = ["grdlandmask"] @@ -26,7 +27,7 @@ @kwargs_to_strings(I="sequence", R="sequence", N="sequence", E="sequence") def grdlandmask( outgrid: str | None = None, - resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", + resolution: Literal["full", "high", "intermediate", "low", "crude", None] = None, **kwargs, ) -> xr.DataArray | None: r""" @@ -99,8 +100,8 @@ def grdlandmask( if kwargs.get("I") is None or kwargs.get("R") is None: raise GMTInvalidInput("Both 'region' and 'spacing' must be specified.") - # Alias "resolution" to "D" - kwargs["D"] = resolution[0] + kwargs["D"] = kwargs.get("D", _parse_coastline_resolution(resolution)) + with Session() as lib: with lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd: kwargs["G"] = voutgrd diff --git a/pygmt/src/select.py b/pygmt/src/select.py index 21d2c856217..a0fe3f2de03 100644 --- a/pygmt/src/select.py +++ b/pygmt/src/select.py @@ -14,6 +14,7 @@ use_alias, validate_output_table_type, ) +from pygmt.src._common import _parse_coastline_resolution __doctest_skip__ = ["select"] @@ -47,7 +48,7 @@ def select( data=None, output_type: Literal["pandas", "numpy", "file"] = "pandas", outfile: str | None = None, - resolution: Literal["full", "high", "intermediate", "low", "crude"] = "low", + resolution: Literal["full", "high", "intermediate", "low", "crude", None] = None, **kwargs, ) -> pd.DataFrame | np.ndarray | None: r""" @@ -202,8 +203,7 @@ def select( >>> # longitudes 246 and 247 and latitudes 20 and 21 >>> out = pygmt.select(data=ship_data, region=[246, 247, 20, 21]) """ - # Alias "resolution" to "D" - kwargs["D"] = resolution[0] + kwargs["D"] = kwargs.get("D", _parse_coastline_resolution(resolution)) output_type = validate_output_table_type(output_type, outfile=outfile) From 2cbe6c9e7acbb4c87c392b972d7b744e514415d6 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 29 Oct 2024 13:10:53 +0800 Subject: [PATCH 5/6] Fix grdlandmask and improve docstrings --- pygmt/src/grdlandmask.py | 11 +++++++---- pygmt/src/select.py | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pygmt/src/grdlandmask.py b/pygmt/src/grdlandmask.py index a654a3b4e62..e00594e5054 100644 --- a/pygmt/src/grdlandmask.py +++ b/pygmt/src/grdlandmask.py @@ -54,9 +54,10 @@ def grdlandmask( Ignored unless ``mask`` is set. Select the resolution of the coastline dataset to use. The available resolutions from highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``, ``"low"``, and ``"crude"``, which drops by 80% - between levels. Note that because the coastlines differ in details it is not - guaranteed that a point will remain inside [or outside] when a different - resolution is selected. + between levels. Note that because the coastlines differ in details a node in a + mask file using one resolution is not guaranteed to remain inside [or outside] + when a different resolution is selected. If ``None``, the low resolution is used + by default. bordervalues : bool, str, float, or list Nodes that fall exactly on a polygon boundary should be considered to be outside the polygon [Default considers them to be @@ -100,7 +101,9 @@ def grdlandmask( if kwargs.get("I") is None or kwargs.get("R") is None: raise GMTInvalidInput("Both 'region' and 'spacing' must be specified.") - kwargs["D"] = kwargs.get("D", _parse_coastline_resolution(resolution)) + kwargs["D"] = kwargs.get( + "D", _parse_coastline_resolution(resolution, allow_auto=True) + ) with Session() as lib: with lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd: diff --git a/pygmt/src/select.py b/pygmt/src/select.py index a0fe3f2de03..43029bfebc4 100644 --- a/pygmt/src/select.py +++ b/pygmt/src/select.py @@ -123,7 +123,7 @@ def select( ``"high"``, ``"intermediate"``, ``"low"``, and ``"crude"``, which drops by 80% between levels. Note that because the coastlines differ in details it is not guaranteed that a point will remain inside [or outside] when a different - resolution is selected. + resolution is selected. If ``None``, the low resolution is used by default. gridmask : str Pass all locations that are inside the valid data area of the grid *gridmask*. Nodes that are outside are either NaN or zero. From e24bbd8af00f0720907337bb3953f817b6040698 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 29 Oct 2024 13:20:14 +0800 Subject: [PATCH 6/6] Fix doctests --- pygmt/src/_common.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/pygmt/src/_common.py b/pygmt/src/_common.py index b3842cc5cf9..044d4662c81 100644 --- a/pygmt/src/_common.py +++ b/pygmt/src/_common.py @@ -60,8 +60,7 @@ def _parse_coastline_resolution( Returns ------- - str or None - The parsed resolution value. + The parsed single-letter resolution or ``None``. Raises ------ @@ -71,17 +70,20 @@ def _parse_coastline_resolution( Examples -------- >>> _parse_coastline_resolution("full") - "f" + 'f' >>> _parse_coastline_resolution("f") - "f" + 'f' >>> _parse_coastline_resolution("auto", allow_auto=True) - "a" - >>> _parse_coastline_resolution("invalid") - pygmt.exceptions.GMTInvalidInput: Invalid resolution: invalid. Valid values are ... + 'a' >>> _parse_coastline_resolution(None) - None + >>> _parse_coastline_resolution("invalid") + Traceback (most recent call last): + ... + pygmt.exceptions.GMTInvalidInput: Invalid resolution: 'invalid'. Valid values ... >>> _parse_coastline_resolution("auto") - pygmt.exceptions.GMTInvalidInput: Invalid resolution: auto. Valid values are ... + Traceback (most recent call last): + ... + pygmt.exceptions.GMTInvalidInput: Invalid resolution: 'auto'. Valid values ... """ if resolution is None: return None @@ -91,7 +93,7 @@ def _parse_coastline_resolution( valid_resolutions.add("auto") if resolution not in {*valid_resolutions, *[res[0] for res in valid_resolutions]}: msg = ( - f"Invalid resolution: {resolution}." + f"Invalid resolution: '{resolution}'. " f"Valid values are {', '.join(valid_resolutions)}." ) raise GMTInvalidInput(msg)