-
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 all 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,77 +115,69 @@ 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. | ||
Check the kind of data that is provided to a module. | ||
|
||
Possible types: | ||
The ``data`` argument can be in any type, but only following types are supported: | ||
|
||
* a file name provided as 'data' | ||
* a pathlib.PurePath object provided as 'data' | ||
* an xarray.DataArray object provided as 'data' | ||
* a 2-D matrix provided as 'data' | ||
* 1-D arrays x and y (and z, optionally) | ||
* an optional argument (None, bool, int or float) provided as 'data' | ||
|
||
Arguments should be ``None`` if not used. If doesn't fit any of these | ||
categories (or fits more than one), will raise an exception. | ||
- a string or a :class:`pathlib.PurePath` object or a sequence of them, representing | ||
a file name or a list of file names | ||
- a 2-D or 3-D :class:`xarray.DataArray` object | ||
- a 2-D matrix | ||
- None, bool, int or float type representing an optional arguments | ||
- a geo-like Python object that implements ``__geo_interface__`` (e.g., | ||
geopandas.GeoDataFrame or shapely.geometry) | ||
|
||
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 +189,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.