Figure.coast: Improve parameters lakes/river_lakes for setting fill of lakes/river-lakes#4376
Figure.coast: Improve parameters lakes/river_lakes for setting fill of lakes/river-lakes#4376
Conversation
…f lakes/river-lakes
There was a problem hiding this comment.
Pull request overview
This PR refactors Figure.coast’s handling of GMT’s -C option to provide a clearer long-form API for setting lake vs river-lake fills, while preserving backward compatibility with the existing lakes=[...] list syntax.
Changes:
- Added a dedicated
_alias_option_Chelper to build-Carguments fromlakes/river_lakes, including a compatibility path for the legacy list form. - Introduced new
river_lakesparameter and updatedcoastvalidation logic and alias mapping accordingly. - Updated docstring alias/parameter documentation around lake and river-lake fills.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return Alias(lakes, name="lakes") # Return as is. | ||
|
|
||
| # If only 'lakes' is specified, no suffix is needed. | ||
| return [ | ||
| Alias(lakes, name="lakes", suffix="+l" if river_lakes is not None else ""), | ||
| Alias(river_lakes, name="river_lakes", suffix="+r"), | ||
| ] | ||
|
|
||
|
|
There was a problem hiding this comment.
_alias_option_C returns a list of Alias objects where both entries have no prefix (only suffix). When users pass short-form C=... via kwargs, AliasSystem.merge will build a warning/error message for a “sequence of aliases” that includes an empty “with optional parameters …” clause (see pygmt/alias.py around the _modifiers join). To avoid degraded/confusing messages for C, consider returning a single Alias (with its value computed as a string or list like ["blue+l", "cyan+r"]) instead of a list of Alias objects, or otherwise ensuring the merge message has meaningful content for this option.
| return Alias(lakes, name="lakes") # Return as is. | |
| # If only 'lakes' is specified, no suffix is needed. | |
| return [ | |
| Alias(lakes, name="lakes", suffix="+l" if river_lakes is not None else ""), | |
| Alias(river_lakes, name="river_lakes", suffix="+r"), | |
| ] | |
| # Pass through the legacy list value unchanged as the argument to -C. | |
| return Alias(lakes, name="C") | |
| # New syntax: lakes and/or river_lakes are given as strings. | |
| # We construct the final value for -C directly so that AliasSystem does not | |
| # need to merge a sequence of aliases without prefixes. | |
| values = [] | |
| if lakes is not None: | |
| lake_val = str(lakes) | |
| # If both lakes and river_lakes are specified and no modifier is present, | |
| # append +l for lakes (for backward compatibility with the previous logic). | |
| if ( | |
| river_lakes is not None | |
| and "+l" not in lake_val | |
| and "+r" not in lake_val | |
| ): | |
| lake_val = f"{lake_val}+l" | |
| values.append(lake_val) | |
| if river_lakes is not None: | |
| river_val = str(river_lakes) | |
| # Append +r only if the user did not already include modifiers. | |
| if "+r" not in river_val and "+l" not in river_val: | |
| river_val = f"{river_val}+r" | |
| values.append(river_val) | |
| if not values: | |
| # No value for -C. | |
| return Alias(None, name="C") | |
| combined = values[0] if len(values) == 1 else values | |
| return Alias(combined, name="C") |
| and kwargs.get("N", borders) is None | ||
| and kwargs.get("W", shorelines) is False | ||
| and not args_in_kwargs(args=["C", "E", "Q"], kwargs=kwargs) | ||
| and kwargs.get("C", lakes or river_lakes) is None |
There was a problem hiding this comment.
The “required args” validation uses kwargs.get("C", lakes or river_lakes) is None. Using or means a falsy but explicitly provided lakes value (e.g., "") would be treated as not provided. Using an explicit None check (e.g., prefer lakes if lakes is not None else river_lakes) avoids truthiness pitfalls and matches how the other checks treat values.
| and kwargs.get("C", lakes or river_lakes) is None | |
| and kwargs.get("C", lakes if lakes is not None else river_lakes) is None |
| aliasdict = AliasSystem( | ||
| C=_alias_option_C(lakes=lakes, river_lakes=river_lakes), | ||
| D=Alias( |
There was a problem hiding this comment.
New behavior for lakes/river_lakes (including suffix selection and the backward-compatible lakes=["...+l", "...+r"] form and the mixed-usage error) isn’t covered by tests. pygmt/tests/test_coast.py currently tests required-args and dcw/resolution conflicts but has no assertions around -C argument building. Please add tests that exercise: (1) lakes="blue" emits -Cblue, (2) river_lakes="cyan" emits -Ccyan+r, (3) both emit two -C... entries with +l/+r, and (4) mixed list + river_lakes raises GMTInvalidInput.
| lakes | ||
| river_lakes |
There was a problem hiding this comment.
The docstring parameter entries for lakes/river_lakes don’t follow the numpydoc pattern used elsewhere in the file (missing : type on the name line and the shared description is indented under river_lakes only). This can break/garble rendered docs. Suggest documenting as either lakes, river_lakes : str with a single indented description, or provide separate lakes : str / river_lakes : str blocks (and mention the backward-compatible list-of-strings form if it remains supported).
| lakes | |
| river_lakes | |
| lakes, river_lakes : str |
| "wet" areas set by the ``water`` parameter. If ``lakes`` is specified but | ||
| ``river_lakes`` isn't, ``river_lakes`` will use the same fill as ``lakes``. |
There was a problem hiding this comment.
The docstring says “If lakes is specified but river_lakes isn’t, river_lakes will use the same fill as lakes.” This is true for the new API when lakes is a plain fill (emits -C<fill>), but it’s not true for the documented backward-compatible modifier forms like lakes="blue+l" (which intentionally affects lakes only). Consider clarifying that the inheritance behavior applies when lakes is given without an explicit +l/+r modifier.
| "wet" areas set by the ``water`` parameter. If ``lakes`` is specified but | |
| ``river_lakes`` isn't, ``river_lakes`` will use the same fill as ``lakes``. | |
| "wet" areas set by the ``water`` parameter. If ``lakes`` is specified as a plain | |
| fill (without an explicit ``+l``/``+r`` modifier) but ``river_lakes`` isn't, | |
| ``river_lakes`` will use the same fill as ``lakes``. |
This PR improves the alias of
coast's-Coption. The GMT CLI syntax is-Cfill[+l|+r].Previously,
-Cwas aliased tolakes. This PR split the-Coption into two parameters,lakesandriver_lakes. Here is a comparison of old and new usages:lakes="blue"lakes="blue", river_lakes="blue"lakes="blue+r"river_lakes="blue"lakes="blue+l"lakes="blue"lakes=["blue+r", "green+l"]lakes="green", river_lakes="blue"Please note that
lakes="blue"has different behaviors in the old and new syntax. So, it's a breaking change.