Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
0105bb6
add conflict parameter for GMTParameterError
Chuan1937 Feb 4, 2026
d8c15e7
update test file
Chuan1937 Feb 4, 2026
7b6d102
Merge branch 'main' into feature/conflict
Chuan1937 Feb 4, 2026
406eb7b
Update pygmt/src/_common.py
Chuan1937 Feb 4, 2026
b28747d
Update pygmt/src/_common.py
Chuan1937 Feb 4, 2026
c15f3f3
Update pygmt/src/grdview.py
Chuan1937 Feb 4, 2026
25bad04
fix check
Chuan1937 Feb 4, 2026
7d9bd89
Update pygmt/src/grdview.py
Chuan1937 Feb 4, 2026
fc029ad
Update pygmt/src/_common.py
Chuan1937 Feb 4, 2026
47f3e1e
Update pygmt/src/_common.py
Chuan1937 Feb 4, 2026
11991fe
update alias
Chuan1937 Feb 4, 2026
3fef364
simplify the error message
Chuan1937 Feb 4, 2026
350f67d
update the error message
Chuan1937 Feb 4, 2026
e4f040f
Update pygmt/exceptions.py
Chuan1937 Feb 5, 2026
f73fcdb
Replace long-form parameter(s) with short-form parameter(s)
Chuan1937 Feb 5, 2026
1ed8e05
Merge branch 'feature/conflict' of github.com:Chuan1937/pygmt into fe…
Chuan1937 Feb 5, 2026
5a5b87d
Merge branch 'main' into feature/conflict
Chuan1937 Feb 5, 2026
a096843
fix test
Chuan1937 Feb 5, 2026
5cbcbe3
Update pygmt/alias.py
Chuan1937 Feb 5, 2026
af21ef2
fix error
Chuan1937 Feb 5, 2026
ce3c9cc
Merge branch 'main' into feature/conflict
Chuan1937 Feb 5, 2026
3c94d17
fix sort error in alias system
Chuan1937 Feb 5, 2026
7c454ba
Update pygmt/alias.py
Chuan1937 Feb 6, 2026
355ba29
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
c260d4a
Update pygmt/alias.py
Chuan1937 Feb 6, 2026
b3c4ba5
simplify the code
Chuan1937 Feb 6, 2026
368a102
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
35ebe3c
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
e8380d4
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
fdeba84
Update pygmt/src/_common.py
Chuan1937 Feb 6, 2026
0deddd2
Update pygmt/src/grdview.py
Chuan1937 Feb 6, 2026
6e951b3
Update pygmt/alias.py
Chuan1937 Feb 6, 2026
c3bf105
Update pygmt/alias.py
Chuan1937 Feb 6, 2026
28e0582
Update pygmt/alias.py
Chuan1937 Feb 6, 2026
e33a11a
update test_alias_system.py
Chuan1937 Feb 6, 2026
3743e11
fix test
Chuan1937 Feb 6, 2026
f2194bf
Update pygmt/alias.py
Chuan1937 Feb 6, 2026
3a73381
Update pygmt/alias.py
Chuan1937 Feb 6, 2026
ff0c829
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
389161c
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
5cbfba4
Update pygmt/src/_common.py
Chuan1937 Feb 6, 2026
9737971
Update pygmt/src/grdview.py
Chuan1937 Feb 6, 2026
e6dcc7c
Merge branch 'main' into feature/conflict
Chuan1937 Feb 6, 2026
b5ca451
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
983caf3
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
dffbc3f
Update pygmt/exceptions.py
Chuan1937 Feb 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pygmt/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ class GMTParameterError(GMTError):
at_most_one
A set of mutually exclusive parameter names, of which at most one can be
specified.
conflicts_with
A dictionary mapping parameter names to sets of conflicting parameter
names. Used to indicate which parameters cannot be used together.
reason
Detailed reason why the parameters are invalid.
"""
Expand All @@ -155,6 +158,7 @@ def __init__(
required: str | set[str] | None = None,
at_least_one: set[str] | None = None,
at_most_one: set[str] | None = None,
conflicts_with: dict[str, set[str]] | None = None,
reason: str | None = None,
):
msg = []
Expand All @@ -177,6 +181,12 @@ def __init__(
f"{', '.join(repr(par) for par in at_most_one)}. "
"Specify at most one of them."
)
if conflicts_with:
for param, conflicts in conflicts_with.items():
msg.append(
f"Conflicting parameters: {param!r} cannot be used with "
f"{', '.join(repr(c) for c in sorted(conflicts))}."
)
if reason:
msg.append(reason)
super().__init__(" ".join(msg))
12 changes: 5 additions & 7 deletions pygmt/src/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pathlib import Path
from typing import Any, ClassVar, Literal

from pygmt.exceptions import GMTInvalidInput, GMTTypeError, GMTValueError
from pygmt.exceptions import GMTParameterError, GMTTypeError, GMTValueError
from pygmt.params.position import Position
from pygmt.src.which import which

Expand Down Expand Up @@ -328,7 +328,7 @@ def _parse_position(
... )
Traceback (most recent call last):
...
pygmt.exceptions.GMTInvalidInput: Parameter 'position' is given with a raw GMT...
pygmt.exceptions.GMTParameterError: ...

>>> _parse_position(
... 123,
Expand Down Expand Up @@ -364,12 +364,10 @@ def _parse_position(
position = Position(position, cstype="inside")
elif kwdict is not None: # Raw GMT command string with potential conflicts.
if any(v is not None and v is not False for v in kwdict.values()):
msg = (
"Parameter 'position' is given with a raw GMT command string, "
"and conflicts with parameters "
f"{', '.join(repr(c) for c in kwdict)}."
raise GMTParameterError(
conflicts_with={"position": set(kwdict.keys())},
reason="Parameter 'position' is given with a raw GMT command string",
)
raise GMTInvalidInput(msg)
else:
# No conflicting parameters to check, indicating it's a new function.
# The string must be an anchor code.
Expand Down
11 changes: 6 additions & 5 deletions pygmt/src/grdview.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pygmt._typing import PathLike
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session, __gmt_version__
from pygmt.exceptions import GMTInvalidInput
from pygmt.exceptions import GMTInvalidInput, GMTParameterError
from pygmt.helpers import build_arg_list, deprecate_parameter, fmt_docstring, use_alias
from pygmt.src.grdinfo import grdinfo

Expand Down Expand Up @@ -71,11 +71,12 @@ def _alias_option_Q( # noqa: N802
v is not None and v is not False
for v in (dpi, mesh_fill, monochrome, nan_transparent)
):
msg = (
"Parameter 'surftype' is given with a raw GMT command string, and conflicts "
"with parameters 'dpi', 'mesh_fill', 'monochrome', or 'nan_transparent'."
raise GMTParameterError(
conflicts_with={
"surftype": {"dpi", "mesh_fill", "monochrome", "nan_transparent"}
},
reason="Parameter 'surftype' is given with a raw GMT command string",
)
raise GMTInvalidInput(msg)

if dpi is not None and surftype != "image":
msg = "Parameter 'dpi' can only be used when 'surftype' is 'image'."
Expand Down
18 changes: 9 additions & 9 deletions pygmt/tests/test_colorbar.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput
from pygmt.exceptions import GMTParameterError
from pygmt.params.position import Position


Expand Down Expand Up @@ -50,21 +50,21 @@ def test_image_position_mixed_syntax():
Test that mixing deprecated GMT CLI syntax string with new parameters.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(cmap="gmt/rainbow", position="x0/0", length="4c")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(cmap="gmt/rainbow", position="x0/0", width="0.5c")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(cmap="gmt/rainbow", position="x0/0", orientation="horizontal")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(cmap="gmt/rainbow", position="x0/0", reverse=True)
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(cmap="gmt/rainbow", position="x0/0", nan=True)
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(
cmap="gmt/rainbow", position="x0/0", fg_triangle=True, bg_triangle=True
)
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(cmap="gmt/rainbow", position="x0/0", move_text="label")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.colorbar(cmap="gmt/rainbow", position="x0/0", label_as_column=True)
10 changes: 5 additions & 5 deletions pygmt/tests/test_grdview.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest
from pygmt import Figure, grdcut
from pygmt.exceptions import GMTInvalidInput, GMTTypeError
from pygmt.exceptions import GMTInvalidInput, GMTParameterError, GMTTypeError
from pygmt.helpers import GMTTempFile
from pygmt.helpers.testing import load_static_earth_relief

Expand Down Expand Up @@ -343,13 +343,13 @@ def test_grdview_mixed_syntax(gridfile):
Run grdview using grid as a file and drapegrid as an xarray.DataArray.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.grdview(grid=gridfile, cmap="SCM/oleron", surftype="i", dpi=300)
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.grdview(grid=gridfile, cmap="SCM/oleron", surftype="m", mesh_fill="red")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.grdview(grid=gridfile, cmap="SCM/oleron", surftype="s", monochrome=True)
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.grdview(
grid=gridfile, cmap="SCM/oleron", surftype="i", nan_transparent=True
)
10 changes: 5 additions & 5 deletions pygmt/tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput
from pygmt.exceptions import GMTParameterError
from pygmt.params import Box, Position


Expand Down Expand Up @@ -66,11 +66,11 @@ def test_image_position_mixed_syntax():
and conflicts with other parameters.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.image(imagefile="@circuit.png", position="x0/0", width="4c")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.image(imagefile="@circuit.png", position="x0/0", height="3c")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.image(imagefile="@circuit.png", position="x0/0", dpi="300")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.image(imagefile="@circuit.png", position="x0/0", replicate=(2, 1))
4 changes: 2 additions & 2 deletions pygmt/tests/test_inset.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput, GMTParameterError
from pygmt.exceptions import GMTParameterError
from pygmt.params import Box, Position


Expand Down Expand Up @@ -94,6 +94,6 @@ def test_inset_invalid_inputs():
with fig.inset(position=Position("TL"), height="5c"):
pass
# Old position syntax conflicts with width/height
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
with fig.inset(position="jTL+w3.5c", width="3.5c"):
pass
8 changes: 4 additions & 4 deletions pygmt/tests/test_legend.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput, GMTTypeError
from pygmt.exceptions import GMTParameterError, GMTTypeError
from pygmt.helpers import GMTTempFile


Expand Down Expand Up @@ -174,9 +174,9 @@ def test_legend_position_mixed_syntax(legend_spec):
spec = io.StringIO(legend_spec)
fig = Figure()
fig.basemap(projection="x6i", region=[0, 1, 0, 1], frame=True)
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.legend(spec, position="jTL", width="5i")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.legend(spec, position="jTL", height="5i")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.legend(spec, position="jTL", line_spacing=2.0)
6 changes: 3 additions & 3 deletions pygmt/tests/test_logo.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput, GMTParameterError
from pygmt.exceptions import GMTParameterError
from pygmt.params import Position


Expand Down Expand Up @@ -66,7 +66,7 @@ def test_logo_position_mixed_syntax():
Test that an error is raised when mixing new and deprecated syntax in 'position'.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.logo(position="jTL", width="5c")
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.logo(position="jTL", height="6c")
10 changes: 5 additions & 5 deletions pygmt/tests/test_wiggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy as np
import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput
from pygmt.exceptions import GMTParameterError
from pygmt.params import Position


Expand Down Expand Up @@ -136,11 +136,11 @@ def test_wiggle_mixed_syntax(data):
"pen": "1.0p",
"track": "0.5p",
}
with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.wiggle(position="jMR+w2+lnT", length=2, **kwargs)

with pytest.raises(GMTInvalidInput):
with pytest.raises(GMTParameterError):
fig.wiggle(position="jMR+w2+lnT", label="nT", **kwargs)

with pytest.raises(GMTInvalidInput):
fig.wiggle(position="jMR+w2+lnT", length_alignment="left", **kwargs)
with pytest.raises(GMTParameterError):
fig.wiggle(position="jMR+w2+lnT", label_alignment="left", **kwargs)
Loading