Skip to content

Commit 985ff10

Browse files
authored
BREAKING: Raise GMTValueError exception for invalid values part 2 (#3998)
1 parent 0c57126 commit 985ff10

20 files changed

+93
-78
lines changed

pygmt/clib/conversion.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import pandas as pd
1313
import xarray as xr
1414
from packaging.version import Version
15-
from pygmt.exceptions import GMTInvalidInput
15+
from pygmt.exceptions import GMTValueError
1616

1717

1818
def dataarray_to_matrix(
@@ -49,7 +49,7 @@ def dataarray_to_matrix(
4949
5050
Raises
5151
------
52-
GMTInvalidInput
52+
GMTValueError
5353
If the grid has more than two dimensions or variable grid spacing.
5454
5555
Examples
@@ -92,8 +92,11 @@ def dataarray_to_matrix(
9292
[2.0, 2.0]
9393
"""
9494
if len(grid.dims) != 2:
95-
msg = f"Invalid number of grid dimensions 'len({grid.dims})'. Must be 2."
96-
raise GMTInvalidInput(msg)
95+
raise GMTValueError(
96+
len(grid.dims),
97+
description="number of grid dimensions",
98+
reason="The grid must be 2-D.",
99+
)
97100

98101
# Extract region and inc from the grid
99102
region, inc = [], []
@@ -113,8 +116,11 @@ def dataarray_to_matrix(
113116
)
114117
warnings.warn(msg, category=RuntimeWarning, stacklevel=2)
115118
if coord_inc == 0:
116-
msg = f"Grid has a zero increment in the '{dim}' dimension."
117-
raise GMTInvalidInput(msg)
119+
raise GMTValueError(
120+
coord_inc,
121+
description="grid increment",
122+
reason=f"Grid has a zero increment in the '{dim}' dimension.",
123+
)
118124
region.extend(
119125
[
120126
coord.min() - coord_inc / 2 * grid.gmt.registration,

pygmt/clib/session.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -913,9 +913,10 @@ def _check_dtype_and_dim(self, array: np.ndarray, ndim: int) -> int:
913913
914914
Raises
915915
------
916+
GMTValueError
917+
If the array has the wrong number of dimensions.
916918
GMTInvalidInput
917-
If the array has the wrong number of dimensions or is an unsupported data
918-
type.
919+
If the array is an unsupported data type.
919920
920921
Examples
921922
--------
@@ -933,8 +934,11 @@ def _check_dtype_and_dim(self, array: np.ndarray, ndim: int) -> int:
933934
"""
934935
# Check that the array has the given number of dimensions.
935936
if array.ndim != ndim:
936-
msg = f"Expected a numpy {ndim}-D array, got {array.ndim}-D."
937-
raise GMTInvalidInput(msg)
937+
raise GMTValueError(
938+
array.ndim,
939+
description="array dimension",
940+
reason=f"Expected a numpy {ndim}-D array, got {array.ndim}-D.",
941+
)
938942

939943
# 1-D arrays can be numeric or text, 2-D arrays can only be numeric.
940944
valid_dtypes = DTYPES if ndim == 1 else DTYPES_NUMERIC

pygmt/helpers/utils.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import xarray as xr
1919
from pygmt._typing import PathLike
2020
from pygmt.encodings import charset
21-
from pygmt.exceptions import GMTInvalidInput
21+
from pygmt.exceptions import GMTInvalidInput, GMTValueError
2222

2323
# Type hints for the list of encodings supported by PyGMT.
2424
Encoding = Literal[
@@ -597,8 +597,7 @@ def build_arg_list( # noqa: PLR0912
597597
or os.fspath(outfile) in {"", ".", ".."}
598598
or os.fspath(outfile).endswith(("/", "\\"))
599599
):
600-
msg = f"Invalid output file name '{outfile}'."
601-
raise GMTInvalidInput(msg)
600+
raise GMTValueError(outfile, description="output file name")
602601
gmt_args.append(f"->{os.fspath(outfile)}")
603602
return gmt_args
604603

pygmt/helpers/validators.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import Literal
77

88
from pygmt._typing import PathLike
9-
from pygmt.exceptions import GMTInvalidInput
9+
from pygmt.exceptions import GMTInvalidInput, GMTValueError
1010

1111

1212
def validate_output_table_type(
@@ -39,7 +39,7 @@ def validate_output_table_type(
3939
>>> validate_output_table_type(output_type="invalid-type")
4040
Traceback (most recent call last):
4141
...
42-
pygmt.exceptions.GMTInvalidInput: Must specify 'output_type' either as 'file', ...
42+
pygmt....GMTValueError: ...: 'invalid-type'. Expected one of: ...
4343
>>> validate_output_table_type("file", outfile=None)
4444
Traceback (most recent call last):
4545
...
@@ -49,9 +49,13 @@ def validate_output_table_type(
4949
... assert len(w) == 1
5050
'file'
5151
"""
52-
if output_type not in {"file", "numpy", "pandas"}:
53-
msg = "Must specify 'output_type' either as 'file', 'numpy', or 'pandas'."
54-
raise GMTInvalidInput(msg)
52+
_valids = {"file", "numpy", "pandas"}
53+
if output_type not in _valids:
54+
raise GMTValueError(
55+
output_type,
56+
description="value for parameter 'output_type'",
57+
choices=_valids,
58+
)
5559
if output_type == "file" and outfile is None:
5660
msg = "Must specify 'outfile' for output_type='file'."
5761
raise GMTInvalidInput(msg)

pygmt/src/_common.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from pathlib import Path
88
from typing import Any, ClassVar, Literal
99

10-
from pygmt.exceptions import GMTInvalidInput, GMTValueError
10+
from pygmt.exceptions import GMTValueError
1111
from pygmt.src.which import which
1212

1313

@@ -125,7 +125,7 @@ class _FocalMechanismConvention:
125125
>>> _FocalMechanismConvention.from_params(["strike", "dip", "rake"])
126126
Traceback (most recent call last):
127127
...
128-
pygmt.exceptions.GMTInvalidInput: Fail to determine focal mechanism convention...
128+
pygmt.exceptions.GMTValueError: Invalid focal mechanism parameters: ...
129129
"""
130130

131131
# Mapping of focal mechanism conventions to their parameters.
@@ -236,18 +236,14 @@ def from_params(
236236
237237
Raises
238238
------
239-
GMTInvalidInput
239+
GMTValueError
240240
If the focal mechanism convention cannot be determined from the given
241241
parameters.
242242
"""
243243
for convention, param_list in cls._params.items():
244244
if set(param_list).issubset(set(params)):
245245
return cls(convention, component=component)
246-
msg = (
247-
"Fail to determine focal mechanism convention from the given parameters: "
248-
f"{', '.join(params)}."
249-
)
250-
raise GMTInvalidInput(msg)
246+
raise GMTValueError(params, description="focal mechanism parameters")
251247

252248

253249
def _parse_coastline_resolution(

pygmt/src/grd2xyz.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import xarray as xr
1010
from pygmt._typing import PathLike
1111
from pygmt.clib import Session
12-
from pygmt.exceptions import GMTInvalidInput
12+
from pygmt.exceptions import GMTValueError
1313
from pygmt.helpers import (
1414
build_arg_list,
1515
fmt_docstring,
@@ -145,10 +145,11 @@ def grd2xyz(
145145
output_type = validate_output_table_type(output_type, outfile=outfile)
146146

147147
if kwargs.get("o") is not None and output_type == "pandas":
148-
msg = (
149-
"If 'outcols' is specified, 'output_type' must be either 'numpy' or 'file'."
148+
raise GMTValueError(
149+
output_type,
150+
description="value for parameter 'output_type'",
151+
reason="Expected one of: 'numpy', 'file' if 'outcols' is specified.",
150152
)
151-
raise GMTInvalidInput(msg)
152153
# Set the default column names for the pandas DataFrame header.
153154
column_names: list[str] = ["x", "y", "z"]
154155
# Let output pandas column names match input DataArray dimension names

pygmt/src/hlines.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from collections.abc import Sequence
66

77
import numpy as np
8-
from pygmt.exceptions import GMTInvalidInput
8+
from pygmt.exceptions import GMTValueError
99

1010
__doctest_skip__ = ["hlines"]
1111

@@ -99,11 +99,12 @@ def hlines(
9999

100100
# Check if xmin/xmax are scalars or have the expected length.
101101
if _xmin.size not in {1, nlines} or _xmax.size not in {1, nlines}:
102-
msg = (
103-
f"'xmin' and 'xmax' are expected to be scalars or have lengths '{nlines}', "
104-
f"but lengths '{_xmin.size}' and '{_xmax.size}' are given."
102+
_value = f"{_xmin.size}, {_xmax.size}"
103+
raise GMTValueError(
104+
_value,
105+
description="size for 'xmin'/'xmax'",
106+
reason=f"'xmin'/'xmax' are expected to be scalars or have lengths {nlines!r}.",
105107
)
106-
raise GMTInvalidInput(msg)
107108

108109
# Repeat xmin/xmax to match the length of y if they are scalars.
109110
if nlines != 1:

pygmt/src/meca.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import pandas as pd
1010
from pygmt._typing import PathLike, TableLike
1111
from pygmt.clib import Session
12-
from pygmt.exceptions import GMTInvalidInput
12+
from pygmt.exceptions import GMTInvalidInput, GMTValueError
1313
from pygmt.helpers import (
1414
build_arg_list,
1515
data_kind,
@@ -66,8 +66,11 @@ def _preprocess_spec(spec, colnames, override_cols):
6666
}
6767
ndiff = spec.shape[1] - len(colnames)
6868
if ndiff not in extra_cols:
69-
msg = f"Input array must have {len(colnames)} or two/three more columns."
70-
raise GMTInvalidInput(msg)
69+
raise GMTValueError(
70+
spec.shape[1],
71+
description="input array shape",
72+
reason=f"Input array must have {len(colnames)} or two/three more columns.",
73+
)
7174
spec = dict(zip([*colnames, *extra_cols[ndiff]], spec.T, strict=False))
7275

7376
# Now, the input data is a dict or an ASCII file.

pygmt/src/vlines.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from collections.abc import Sequence
66

77
import numpy as np
8-
from pygmt.exceptions import GMTInvalidInput
8+
from pygmt.exceptions import GMTValueError
99

1010
__doctest_skip__ = ["vlines"]
1111

@@ -99,11 +99,12 @@ def vlines(
9999

100100
# Check if ymin/ymax are scalars or have the expected length.
101101
if _ymin.size not in {1, nlines} or _ymax.size not in {1, nlines}:
102-
msg = (
103-
f"'ymin' and 'ymax' are expected to be scalars or have lengths '{nlines}', "
104-
f"but lengths '{_ymin.size}' and '{_ymax.size}' are given."
102+
_value = f"{_ymin.size}, {_ymax.size}"
103+
raise GMTValueError(
104+
_value,
105+
description="size for 'ymin'/'ymax'",
106+
reason=f"'ymin'/'ymax' are expected to be scalars or have lengths {nlines!r}.",
105107
)
106-
raise GMTInvalidInput(msg)
107108

108109
# Repeat ymin/ymax to match the length of x if they are scalars.
109110
if nlines != 1:

pygmt/tests/test_clib_dataarray_to_matrix.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pytest
88
import xarray as xr
99
from pygmt.clib.conversion import dataarray_to_matrix
10-
from pygmt.exceptions import GMTInvalidInput
10+
from pygmt.exceptions import GMTValueError
1111

1212

1313
@pytest.mark.benchmark
@@ -81,7 +81,7 @@ def test_dataarray_to_matrix_dims_fails():
8181
y = np.arange(12)
8282
z = np.arange(10)
8383
grid = xr.DataArray(data, coords=[("z", z), ("y", y), ("x", x)])
84-
with pytest.raises(GMTInvalidInput):
84+
with pytest.raises(GMTValueError):
8585
dataarray_to_matrix(grid)
8686

8787

@@ -107,11 +107,11 @@ def test_dataarray_to_matrix_zero_inc_fails():
107107
x = np.linspace(0, 1, 5)
108108
y = np.zeros_like(x)
109109
grid = xr.DataArray(data, coords=[("y", y), ("x", x)])
110-
with pytest.raises(GMTInvalidInput):
110+
with pytest.raises(GMTValueError):
111111
dataarray_to_matrix(grid)
112112

113113
y = np.linspace(0, 1, 5)
114114
x = np.zeros_like(x)
115115
grid = xr.DataArray(data, coords=[("y", y), ("x", x)])
116-
with pytest.raises(GMTInvalidInput):
116+
with pytest.raises(GMTValueError):
117117
dataarray_to_matrix(grid)

0 commit comments

Comments
 (0)