-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor the data_kind and validate_data_input functions #3335
Changes from 8 commits
e79a7d0
e2a8ceb
008a56f
46fb307
d3854da
a9670aa
7ff0d9e
70962d0
b575591
c522e36
0bde17d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -12,7 +12,7 @@ | |||||
import warnings | ||||||
import webbrowser | ||||||
from collections.abc import Iterable, Sequence | ||||||
from typing import Any | ||||||
from typing import Any, Literal | ||||||
|
||||||
import xarray as xr | ||||||
from pygmt.encodings import charset | ||||||
|
@@ -79,6 +79,10 @@ def _validate_data_input( | |||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Too much data. Use either data or x/y/z. | ||||||
>>> _validate_data_input(data="infile", x=[1, 2, 3], y=[4, 5, 6]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
pygmt.exceptions.GMTInvalidInput: Too much data. Use either data or x/y/z. | ||||||
>>> _validate_data_input(data="infile", z=[7, 8, 9]) | ||||||
Traceback (most recent call last): | ||||||
... | ||||||
|
@@ -111,7 +115,9 @@ def _validate_data_input( | |||||
raise GMTInvalidInput("data must provide x, y, and z columns.") | ||||||
|
||||||
|
||||||
def data_kind(data=None, x=None, y=None, z=None, required_z=False, required_data=True): | ||||||
def data_kind( | ||||||
data: Any = None, required: bool = True | ||||||
) -> Literal["arg", "file", "geojson", "grid", "image", "matrix", "vectors"]: | ||||||
""" | ||||||
Check what kind of data is provided to a module. | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since x/y/z is no longer used, at L124-129, change the docstring to read:
|
||||||
|
@@ -124,64 +130,53 @@ def data_kind(data=None, x=None, y=None, z=None, required_z=False, required_data | |||||
* 1-D arrays x and y (and z, optionally) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Delete this line about x/y/z?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated the docstring at b575591. Currently, any unrecognized data type is taken as a |
||||||
* an optional argument (None, bool, int or float) provided as 'data' | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
Arguments should be ``None`` if not used. If doesn't fit any of these | ||||||
categories (or fits more than one), will raise an exception. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
data : str, pathlib.PurePath, None, bool, xarray.DataArray or {table-like} | ||||||
Pass in either a file name or :class:`pathlib.Path` to an ASCII data | ||||||
table, an :class:`xarray.DataArray`, a 1-D/2-D | ||||||
{table-classes} or an option argument. | ||||||
x/y : 1-D arrays or None | ||||||
x and y columns as numpy arrays. | ||||||
z : 1-D array or None | ||||||
z column as numpy array. To be used optionally when x and y are given. | ||||||
required_z : bool | ||||||
State whether the 'z' column is required. | ||||||
required_data : bool | ||||||
required | ||||||
Set to True when 'data' is required, or False when dealing with | ||||||
optional virtual files. [Default is True]. | ||||||
|
||||||
Returns | ||||||
------- | ||||||
kind : str | ||||||
One of ``'arg'``, ``'file'``, ``'grid'``, ``image``, ``'geojson'``, | ||||||
``'matrix'``, or ``'vectors'``. | ||||||
kind | ||||||
The data kind. | ||||||
|
||||||
Examples | ||||||
-------- | ||||||
|
||||||
>>> import numpy as np | ||||||
>>> import xarray as xr | ||||||
>>> import pathlib | ||||||
>>> data_kind(data=None, x=np.array([1, 2, 3]), y=np.array([4, 5, 6])) | ||||||
>>> data_kind(data=None) | ||||||
'vectors' | ||||||
>>> data_kind(data=np.arange(10).reshape((5, 2)), x=None, y=None) | ||||||
>>> data_kind(data=np.arange(10).reshape((5, 2))) | ||||||
'matrix' | ||||||
>>> data_kind(data="my-data-file.txt", x=None, y=None) | ||||||
>>> data_kind(data="my-data-file.txt") | ||||||
'file' | ||||||
>>> data_kind(data=pathlib.Path("my-data-file.txt"), x=None, y=None) | ||||||
>>> data_kind(data=pathlib.Path("my-data-file.txt")) | ||||||
'file' | ||||||
>>> data_kind(data=None, x=None, y=None, required_data=False) | ||||||
>>> data_kind(data=None, required=False) | ||||||
'arg' | ||||||
>>> data_kind(data=2.0, x=None, y=None, required_data=False) | ||||||
>>> data_kind(data=2.0, required=False) | ||||||
'arg' | ||||||
>>> data_kind(data=True, x=None, y=None, required_data=False) | ||||||
>>> data_kind(data=True, required=False) | ||||||
'arg' | ||||||
>>> data_kind(data=xr.DataArray(np.random.rand(4, 3))) | ||||||
'grid' | ||||||
>>> data_kind(data=xr.DataArray(np.random.rand(3, 4, 5))) | ||||||
'image' | ||||||
""" | ||||||
# determine the data kind | ||||||
kind: Literal["arg", "file", "geojson", "grid", "image", "matrix", "vectors"] | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this line doing here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To suppress the mypy error:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah interesting. Probably should turn this into an enum, but leave that for another day. |
||||||
if isinstance(data, str | pathlib.PurePath) or ( | ||||||
isinstance(data, list | tuple) | ||||||
and all(isinstance(_file, str | pathlib.PurePath) for _file in data) | ||||||
): | ||||||
# One or more files | ||||||
kind = "file" | ||||||
elif isinstance(data, bool | int | float) or (data is None and not required_data): | ||||||
elif isinstance(data, bool | int | float) or (data is None and not required): | ||||||
kind = "arg" | ||||||
elif isinstance(data, xr.DataArray): | ||||||
kind = "image" if len(data.dims) == 3 else "grid" | ||||||
|
@@ -193,15 +188,6 @@ def data_kind(data=None, x=None, y=None, z=None, required_z=False, required_data | |||||
kind = "matrix" | ||||||
else: | ||||||
kind = "vectors" | ||||||
_validate_data_input( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed from here and moved to |
||||||
data=data, | ||||||
x=x, | ||||||
y=y, | ||||||
z=z, | ||||||
required_z=required_z, | ||||||
required_data=required_data, | ||||||
kind=kind, | ||||||
) | ||||||
return kind | ||||||
|
||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ | |
|
||
from pathlib import Path | ||
|
||
import numpy as np | ||
import pytest | ||
import xarray as xr | ||
from pygmt import Figure | ||
|
@@ -13,7 +12,6 @@ | |
GMTTempFile, | ||
args_in_kwargs, | ||
build_arg_list, | ||
data_kind, | ||
kwargs_to_strings, | ||
unique_name, | ||
) | ||
|
@@ -33,25 +31,6 @@ def test_load_static_earth_relief(): | |
assert isinstance(data, xr.DataArray) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test is removed because:
|
||
("data", "x", "y"), | ||
[ | ||
(None, None, None), | ||
("data.txt", np.array([1, 2]), np.array([4, 5])), | ||
("data.txt", np.array([1, 2]), None), | ||
("data.txt", None, np.array([4, 5])), | ||
(None, np.array([1, 2]), None), | ||
(None, None, np.array([4, 5])), | ||
], | ||
) | ||
def test_data_kind_fails(data, x, y): | ||
""" | ||
Make sure data_kind raises exceptions when it should. | ||
""" | ||
with pytest.raises(GMTInvalidInput): | ||
data_kind(data=data, x=x, y=y) | ||
|
||
|
||
def test_unique_name(): | ||
""" | ||
Make sure the names are really unique. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this function only checks
data
, andx
/y
/z
is no longer used.