diff --git a/.github/workflows/ci_tests.yaml b/.github/workflows/ci_tests.yaml index 976d080ccfa..7fc228f58a2 100644 --- a/.github/workflows/ci_tests.yaml +++ b/.github/workflows/ci_tests.yaml @@ -72,9 +72,9 @@ jobs: include: # Python 3.11 + core packages (minimum supported versions) + optional packages (minimum supported versions if any) - python-version: '3.11' - numpy-version: '1.26' + numpy-version: '2.0' pandas-version: '=2.2' - xarray-version: '=2023.10' + xarray-version: '=2024.5' optional-packages: ' contextily geopandas ipython pyarrow-core rioxarray netCDF4 sphinx-gallery' # Python 3.13 + core packages (latest versions) + optional packages - python-version: '3.13' diff --git a/.github/workflows/ci_tests_legacy.yaml b/.github/workflows/ci_tests_legacy.yaml index 239a6fd5116..99e961ed181 100644 --- a/.github/workflows/ci_tests_legacy.yaml +++ b/.github/workflows/ci_tests_legacy.yaml @@ -61,9 +61,9 @@ jobs: python=3.11 gmt=${{ matrix.gmt_version }} ghostscript - numpy=1.26 + numpy=2.0 pandas=2.2 - xarray=2023.10 + xarray=2024.5 packaging=24.2 contextily=1.5 geopandas=1.0 diff --git a/environment.yml b/environment.yml index 5ab8f6cb94b..bc4722dcf09 100644 --- a/environment.yml +++ b/environment.yml @@ -7,9 +7,9 @@ dependencies: # Required dependencies - gmt=6.6.0 - ghostscript=10.06.0 - - numpy>=1.26 + - numpy>=2.0 - pandas>=2.2 - - xarray>=2023.10 + - xarray>=2024.5 - packaging>=24.2 # Optional dependencies - contextily>=1.5 diff --git a/pygmt/conftest.py b/pygmt/conftest.py deleted file mode 100644 index ee491b7f8bc..00000000000 --- a/pygmt/conftest.py +++ /dev/null @@ -1,11 +0,0 @@ -""" -conftest.py for pytest. -""" - -import numpy as np -from packaging.version import Version - -# TODO(NumPy>=2.0): Remove the conftest.py file. -# Address https://github.com/GenericMappingTools/pygmt/issues/2628. -if Version(np.__version__) >= Version("2.0.0.dev0+git20230726"): - np.set_printoptions(legacy="1.25") # type: ignore[arg-type] diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 08520396099..758354ebf5c 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -122,12 +122,12 @@ def load_tile_map( ... ) >>> raster.sizes Frozen({'band': 3, 'y': 256, 'x': 512}) - >>> raster.coords # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + >>> raster.coords Coordinates: - * band (band) uint8... 1 2 3 - * y (y) float64... -7.081e-10 -7.858e+04 ... -1.996e+07 -2.004e+07 - * x (x) float64... -2.004e+07 -1.996e+07 ... 1.996e+07 2.004e+07 - spatial_ref int... 0 + * band (band) uint8 3B 1 2 3 + * y (y) float64 2kB -7.081e-10 -7.858e+04 ... -1.996e+07 -2.004e+07 + * x (x) float64 4kB -2.004e+07 -1.996e+07 ... 1.996e+07 2.004e+07 + spatial_ref int64 8B 0 >>> # CRS is set only if rioxarray is available >>> if hasattr(raster, "rio"): ... raster.rio.crs.to_string() diff --git a/pygmt/datatypes/grid.py b/pygmt/datatypes/grid.py index 0c2632b1eb4..a5b0d2feff7 100644 --- a/pygmt/datatypes/grid.py +++ b/pygmt/datatypes/grid.py @@ -114,8 +114,8 @@ def to_xarray(self) -> xr.DataArray: ... grid = lib.read_virtualfile(voutgrd, kind="grid") ... # Convert to xarray.DataArray and use it later ... da = grid.contents.to_xarray() - >>> da # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS - ... + >>> da + Size: 448B array([[347.5, 344.5, 386. , 640.5, 617. , 579. , 646.5, 671. ], [383. , 284.5, 344.5, 394. , 491. , 556.5, 578.5, 618.5], [373. , 367.5, 349. , 352.5, 419.5, 428. , 570. , 667.5], @@ -132,8 +132,8 @@ def to_xarray(self) -> xr.DataArray: [347.5, 331.5, 309. , 282. , 190. , 208. , 299.5, 348. ]], dtype=float32) Coordinates: - * lat (lat) float64... -23.5 -22.5 -21.5 -20.5 ... -12.5 -11.5 -10.5 - * lon (lon) float64... -54.5 -53.5 -52.5 -51.5 -50.5 -49.5 -48.5 -47.5 + * lat (lat) float64 112B -23.5 -22.5 -21.5 -20.5 ... -12.5 -11.5 -10.5 + * lon (lon) float64 64B -54.5 -53.5 -52.5 -51.5 -50.5 -49.5 -48.5 -47.5 Attributes: Conventions: CF-1.7 title: Produced by grdcut @@ -141,23 +141,23 @@ def to_xarray(self) -> xr.DataArray: description: Reduced by Gaussian Cartesian filtering (111.2 km fullwi... actual_range: [190. 981.] long_name: elevation (m) - >>> da.coords["lon"] # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS - ... + >>> da.coords["lon"] + Size: 64B array([-54.5, -53.5, -52.5, -51.5, -50.5, -49.5, -48.5, -47.5]) Coordinates: - * lon (lon) float64... -54.5 -53.5 -52.5 -51.5 -50.5 -49.5 -48.5 -47.5 + * lon (lon) float64 64B -54.5 -53.5 -52.5 -51.5 -50.5 -49.5 -48.5 -47.5 Attributes: long_name: longitude units: degrees_east standard_name: longitude axis: X actual_range: [-55. -47.] - >>> da.coords["lat"] # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS - ... + >>> da.coords["lat"] + Size: 112B array([-23.5, -22.5, -21.5, -20.5, -19.5, -18.5, -17.5, -16.5, -15.5, -14.5, - -13.5, -12.5, -11.5, -10.5]) + -13.5, -12.5, -11.5, -10.5]) Coordinates: - * lat (lat) float64... -23.5 -22.5 -21.5 -20.5 ... -12.5 -11.5 -10.5 + * lat (lat) float64 112B -23.5 -22.5 -21.5 -20.5 ... -12.5 -11.5 -10.5 Attributes: long_name: latitude units: degrees_north diff --git a/pygmt/datatypes/image.py b/pygmt/datatypes/image.py index 2d6012a152d..75f63871f73 100644 --- a/pygmt/datatypes/image.py +++ b/pygmt/datatypes/image.py @@ -67,16 +67,16 @@ class _GMT_IMAGE(ctp.Structure): # noqa: N801 [2, 2, 2, 2] b'BRPa' 0.5 1 0 - >>> x # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS + >>> x array([-179.5, -178.5, ..., 178.5, 179.5]) - >>> y # doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS + >>> y array([ 89.5, 88.5, ..., -88.5, -89.5]) >>> data.dtype dtype('uint8') >>> data.shape (180, 360, 3) >>> data.min(), data.max() - (10, 255) + (np.uint8(10), np.uint8(255)) """ _fields_: ClassVar = [ @@ -121,7 +121,7 @@ def to_xarray(self) -> xr.DataArray: ... image = lib.read_virtualfile(voutimg, kind="image") ... # Convert to xarray.DataArray and use it later ... da = image.contents.to_xarray() - >>> da # doctest: +NORMALIZE_WHITESPACE + >>> da Size: 194kB array([[[ 10, 10, 10, ..., 10, 10, 10], [ 10, 10, 10, ..., 10, 10, 10], @@ -145,7 +145,8 @@ def to_xarray(self) -> xr.DataArray: ..., [177, 179, 179, ..., 178, 177, 177], [185, 187, 187, ..., 187, 186, 185], - [189, 191, 191, ..., 191, 191, 189]]], dtype=uint8) + [189, 191, 191, ..., 191, 191, 189]]], + shape=(3, 180, 360), dtype=uint8) Coordinates: * band (band) uint8 3B 1 2 3 * y (y) float64 1kB 89.5 88.5 87.5 86.5 ... -86.5 -87.5 -88.5 -89.5 @@ -153,16 +154,16 @@ def to_xarray(self) -> xr.DataArray: Attributes: long_name: z - >>> da.coords["x"] # doctest: +NORMALIZE_WHITESPACE + >>> da.coords["x"] Size: 3kB - array([-179.5, -178.5, -177.5, ..., 177.5, 178.5, 179.5]) + array([-179.5, -178.5, -177.5, ..., 177.5, 178.5, 179.5], shape=(360,)) Coordinates: * x (x) float64 3kB -179.5 -178.5 -177.5 -176.5 ... 177.5 178.5 179.5 Attributes: long_name: x axis: X actual_range: [-180. 180.] - >>> da.coords["y"] # doctest: +NORMALIZE_WHITESPACE + >>> da.coords["y"] Size: 1kB array([ 89.5, 88.5, 87.5, 86.5, ..., -87.5, -88.5, -89.5]) Coordinates: diff --git a/pygmt/helpers/decorators.py b/pygmt/helpers/decorators.py index 62cb37198c1..50fcefaf0b5 100644 --- a/pygmt/helpers/decorators.py +++ b/pygmt/helpers/decorators.py @@ -514,9 +514,7 @@ def use_alias(**aliases): R = bla J = meh >>> my_module(region="bla", projection="meh") R = bla J = meh - >>> my_module( - ... region="bla", projection="meh", J="bla" - ... ) # doctest: +NORMALIZE_WHITESPACE + >>> my_module(region="bla", projection="meh", J="bla") Traceback (most recent call last): ... pygmt.exceptions.GMTInvalidInput: diff --git a/pygmt/tests/test_clib_to_numpy.py b/pygmt/tests/test_clib_to_numpy.py index 4c228f7b0e5..e04f732bb3d 100644 --- a/pygmt/tests/test_clib_to_numpy.py +++ b/pygmt/tests/test_clib_to_numpy.py @@ -3,7 +3,6 @@ """ import datetime -import sys import numpy as np import numpy.testing as npt @@ -52,14 +51,7 @@ def _check_result(result, expected_dtype): @pytest.mark.parametrize( ("data", "expected_dtype"), [ - # TODO(NumPy>=2.0): Remove the if-else statement after NumPy>=2.0. - pytest.param( - [1, 2, 3], - np.int32 - if sys.platform == "win32" and Version(np.__version__) < Version("2.0") - else np.int64, - id="int", - ), + pytest.param([1, 2, 3], np.int64, id="int"), pytest.param([1.0, 2.0, 3.0], np.float64, id="float"), pytest.param( [complex(+1), complex(-2j), complex("-Infinity+NaNj")], diff --git a/pygmt/xarray/backend.py b/pygmt/xarray/backend.py index 26700b8dec6..79a6e1f0c66 100644 --- a/pygmt/xarray/backend.py +++ b/pygmt/xarray/backend.py @@ -50,13 +50,13 @@ class GMTBackendEntrypoint(BackendEntrypoint): >>> da_grid = xr.open_dataarray( ... "@static_earth_relief.nc", engine="gmt", raster_kind="grid" ... ) - >>> da_grid # doctest: +NORMALIZE_WHITESPACE + >>> da_grid Size: 448B [112 values with dtype=float32] Coordinates: * lat (lat) float64 112B -23.5 -22.5 -21.5 -20.5 ... -12.5 -11.5 -10.5 * lon (lon) float64 64B -54.5 -53.5 -52.5 -51.5 -50.5 -49.5 -48.5 -47.5 - Attributes:... + Attributes: Conventions: CF-1.7 title: Produced by grdcut history: grdcut @earth_relief_01d_p -R-55/-47/-24/-10 -Gstatic_eart... @@ -69,14 +69,14 @@ class GMTBackendEntrypoint(BackendEntrypoint): >>> da_image = xr.open_dataarray( ... "@earth_night_01d", engine="gmt", raster_kind="image" ... ) - >>> da_image # doctest: +NORMALIZE_WHITESPACE + >>> da_image Size: 194kB [194400 values with dtype=uint8] Coordinates: - * band (band) uint8... 1 2 3 - * y (y) float64... 89.5 88.5 87.5 86.5 ... -86.5 -87.5 -88.5 -89.5 - * x (x) float64... -179.5 -178.5 -177.5 -176.5 ... 177.5 178.5 179.5 - Attributes:... + * band (band) uint8 3B 1 2 3 + * y (y) float64 1kB 89.5 88.5 87.5 86.5 ... -86.5 -87.5 -88.5 -89.5 + * x (x) float64 3kB -179.5 -178.5 -177.5 -176.5 ... 177.5 178.5 179.5 + Attributes: long_name: z Load a single-band netCDF file using ``raster_kind="grid"`` over a bounding box @@ -95,7 +95,7 @@ class GMTBackendEntrypoint(BackendEntrypoint): Coordinates: * lat (lat) float64 104B 32.0 32.08 32.17 32.25 ... 32.83 32.92 33.0 * lon (lon) float64 200B -64.0 -63.92 -63.83 ... -62.17 -62.08 -62.0 - Attributes:... + Attributes: Conventions: CF-1.7 title: ETOPO5 global topography history: grdreformat -fg bermuda.grd bermuda.nc=ns diff --git a/pyproject.toml b/pyproject.toml index 8dd8a656f01..8a03f58b1a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,9 +35,9 @@ classifiers = [ "Programming Language :: Python :: 3.13", ] dependencies = [ - "numpy>=1.26", + "numpy>=2.0", "pandas>=2.2", - "xarray>=2023.10", + "xarray>=2024.5", "packaging>=24.2", ] dynamic = ["version"] diff --git a/requirements.txt b/requirements.txt index de229b8acb2..804519b48c8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # Required packages -numpy>=1.26 +numpy>=2.0 pandas>=2.2 -xarray>=2023.10 +xarray>=2024.5 packaging>=24.2