From f18aaa7cd24fe814ad0fd45b0ab02043fc53a107 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 20 Feb 2025 15:14:17 +0100 Subject: [PATCH 1/2] autotest: make it robust to numpy presence, but osgeo.gdal_array absence --- autotest/alg/sieve.py | 1 + autotest/alg/transformgeoloc.py | 1 + autotest/alg/warp.py | 4 ++ autotest/gcore/hfa_rfc40.py | 2 +- autotest/gcore/interpolateatpoint.py | 21 ++++-- autotest/gcore/pixfun.py | 2 +- autotest/gcore/rasterio.py | 15 ++++ autotest/gcore/tiff_ovr.py | 1 + autotest/gcore/tiff_write.py | 1 + autotest/gcore/virtualmem.py | 2 + autotest/gcore/vrt_read.py | 2 + autotest/gdrivers/lcp.py | 2 + autotest/gdrivers/memmultidim.py | 4 ++ autotest/gdrivers/netcdf.py | 6 +- autotest/gdrivers/rmf.py | 4 ++ autotest/gdrivers/tiledb_write.py | 4 ++ autotest/gdrivers/vrtderived.py | 72 ++++--------------- autotest/gdrivers/vrtpansharpen.py | 6 +- autotest/ogr/ogr_parquet.py | 4 ++ autotest/pyscripts/test_gdal2tiles.py | 4 ++ autotest/pyscripts/test_gdal2xyz.py | 1 + autotest/pyscripts/test_gdal_retile.py | 1 + .../pyscripts/test_validate_geoparquet.py | 3 + autotest/utilities/test_gdal_rasterize.py | 2 +- autotest/utilities/test_gdal_viewshed.py | 1 + autotest/utilities/test_gdallocationinfo.py | 3 + 26 files changed, 93 insertions(+), 76 deletions(-) diff --git a/autotest/alg/sieve.py b/autotest/alg/sieve.py index 260a92dd980b..68142fd8889e 100755 --- a/autotest/alg/sieve.py +++ b/autotest/alg/sieve.py @@ -176,6 +176,7 @@ def test_sieve_5(): def test_sieve_6(): + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") # Try 3002. Should run in less than 10 seconds diff --git a/autotest/alg/transformgeoloc.py b/autotest/alg/transformgeoloc.py index 4e280c8b28fe..625ce8286752 100755 --- a/autotest/alg/transformgeoloc.py +++ b/autotest/alg/transformgeoloc.py @@ -24,6 +24,7 @@ def test_transformgeoloc_1(): + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") # Setup 2x2 geolocation arrays in a memory dataset with lat/long values. diff --git a/autotest/alg/warp.py b/autotest/alg/warp.py index b060b327242f..22054d7abdd7 100755 --- a/autotest/alg/warp.py +++ b/autotest/alg/warp.py @@ -1175,6 +1175,7 @@ def test_warp_weighted_average(): ) def test_warp_weighted_mode(dtype): + pytest.importorskip("osgeo.gdal_array") np = pytest.importorskip("numpy") with gdal.GetDriverByName("MEM").Create("", 3, 3, eType=dtype) as src_ds: @@ -1563,6 +1564,7 @@ def test_warp_55(): @pytest.mark.parametrize("use_optim", ["YES", "NO"]) def test_warp_56(use_optim): + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") pix_ds = gdal.GetDriverByName("MEM").Create("", 1, 1) @@ -1660,6 +1662,8 @@ def test_warp_rms_2(): @pytest.mark.parametrize("tie_strategy", ("FIRST", "MIN", "MAX", "HOPE")) @pytest.mark.parametrize("dtype", (gdal.GDT_Int16, gdal.GDT_Int32)) def test_warp_mode_ties(tie_strategy, dtype): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") # 1 and 5 are tied for the mode; 1 encountered first diff --git a/autotest/gcore/hfa_rfc40.py b/autotest/gcore/hfa_rfc40.py index 1ddcf2bf34bc..0590bcc3c59e 100755 --- a/autotest/gcore/hfa_rfc40.py +++ b/autotest/gcore/hfa_rfc40.py @@ -24,7 +24,7 @@ # All tests will be skipped if numpy is unavailable. np = pytest.importorskip("numpy") - +pytest.importorskip("osgeo.gdal_array") INT_DATA = np.array([197, 83, 46, 29, 1, 78, 23, 90, 12, 45]) DOUBLE_DATA = np.array([0.1, 43.2, 78.1, 9.9, 23.0, 0.92, 82.5, 0.0, 1.0, 99.0]) diff --git a/autotest/gcore/interpolateatpoint.py b/autotest/gcore/interpolateatpoint.py index 1409ff6a735e..f5a5c537f7f5 100755 --- a/autotest/gcore/interpolateatpoint.py +++ b/autotest/gcore/interpolateatpoint.py @@ -68,10 +68,13 @@ def test_interpolateatpoint_throw(): def test_interpolateatpoint_2_bands(): + pytest.importorskip("osgeo.gdal_array") + np = pytest.importorskip("numpy") + mem_ds = gdal.GetDriverByName("MEM").Create( "", xsize=2, ysize=2, bands=2, eType=gdal.GDT_Float32 ) - np = pytest.importorskip("numpy") + # First band with values values raster_array_1 = np.array(([10.5, 1.3], [2.4, 3.8])) mem_ds.GetRasterBand(1).WriteArray(raster_array_1) @@ -94,10 +97,12 @@ def test_interpolateatpoint_2_bands(): def test_interpolateatpoint_bilinear_several_points(): + pytest.importorskip("osgeo.gdal_array") + np = pytest.importorskip("numpy") + mem_ds = gdal.GetDriverByName("MEM").Create( "", xsize=3, ysize=2, bands=1, eType=gdal.GDT_Float32 ) - np = pytest.importorskip("numpy") raster_array_1 = np.array(([10.5, 1.3, 0.5], [2.4, 3.8, -1.0])) mem_ds.GetRasterBand(1).WriteArray(raster_array_1) @@ -131,10 +136,12 @@ def test_interpolateatpoint_bilinear_several_points(): def test_interpolateatpoint_cubicspline_several_points(): + pytest.importorskip("osgeo.gdal_array") + np = pytest.importorskip("numpy") + mem_ds = gdal.GetDriverByName("MEM").Create( "", xsize=4, ysize=4, bands=1, eType=gdal.GDT_Float32 ) - np = pytest.importorskip("numpy") raster_array_1 = np.array( ( [1.0, 2.0, 1.5, -0.3], @@ -160,10 +167,12 @@ def test_interpolateatpoint_cubicspline_several_points(): def test_interpolateatpoint_cubic_several_points(): + pytest.importorskip("osgeo.gdal_array") + np = pytest.importorskip("numpy") + mem_ds = gdal.GetDriverByName("MEM").Create( "", xsize=4, ysize=4, bands=1, eType=gdal.GDT_Float32 ) - np = pytest.importorskip("numpy") raster_array_1 = np.array( ( [1.0, 2.0, 1.5, -0.3], @@ -196,10 +205,12 @@ def test_interpolateatpoint_cubic_several_points(): def test_interpolateatpoint_at_borders(): + pytest.importorskip("osgeo.gdal_array") + np = pytest.importorskip("numpy") + mem_ds = gdal.GetDriverByName("MEM").Create( "", xsize=6, ysize=5, bands=1, eType=gdal.GDT_Float32 ) - np = pytest.importorskip("numpy") raster_array_1 = np.array( ( [1, 2, 4, 4, 5, 6], diff --git a/autotest/gcore/pixfun.py b/autotest/gcore/pixfun.py index 06f030af380d..ddf9e2b23c78 100755 --- a/autotest/gcore/pixfun.py +++ b/autotest/gcore/pixfun.py @@ -25,7 +25,7 @@ # All tests will be skipped if numpy is unavailable. numpy = pytest.importorskip("numpy") - +pytest.importorskip("osgeo.gdal_array") ############################################################################### # Verify real part extraction from a complex dataset. diff --git a/autotest/gcore/rasterio.py b/autotest/gcore/rasterio.py index ccc474ca1db2..bc575c859aaf 100755 --- a/autotest/gcore/rasterio.py +++ b/autotest/gcore/rasterio.py @@ -709,6 +709,7 @@ def test_rasterio_9(): def test_rasterio_overview_subpixel_resampling(): + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") temp_path = "/vsimem/rasterio_ovr.tif" @@ -774,6 +775,8 @@ def test_rasterio_10(): def test_rasterio_11(): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") mem_ds = gdal.GetDriverByName("MEM").Create("", 4, 3) @@ -810,6 +813,8 @@ def rasterio_12_progress_callback(pct, message, user_data): def test_rasterio_12(): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") mem_ds = gdal.GetDriverByName("MEM").Create("", 4, 3, 4) @@ -878,6 +883,8 @@ def test_rasterio_12(): ], ) def test_rasterio_13(dt): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") dt = gdal.GetDataTypeByName(dt) @@ -1206,6 +1213,8 @@ def test_rasterio_16(): def test_rasterio_nodata(): + + pytest.importorskip("osgeo.gdal_array") pytest.importorskip("numpy") ndv = 123 @@ -1413,6 +1422,8 @@ def test_rasterio_resampled_value_is_nodata(): def test_rasterio_dataset_readarray_cint16(): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") mem_ds = gdal.GetDriverByName("MEM").Create("", 1, 1, 2, gdal.GDT_CInt16) @@ -1488,6 +1499,8 @@ def test_rasterio_floating_point_window_no_resampling(): def test_rasterio_floating_point_window_no_resampling_numpy(): # Same as above but using ReadAsArray() instead of ReadRaster() + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") ds = gdal.Translate( @@ -3158,6 +3171,8 @@ def test_rasterio_gdal_rasterio_resampling(): def test_rasterio_numpy_datatypes_for_xoff(): + + pytest.importorskip("osgeo.gdal_array") np = pytest.importorskip("numpy") ds = gdal.Open("data/byte.tif") diff --git a/autotest/gcore/tiff_ovr.py b/autotest/gcore/tiff_ovr.py index 11644f738c50..4091fc7f8808 100755 --- a/autotest/gcore/tiff_ovr.py +++ b/autotest/gcore/tiff_ovr.py @@ -2472,6 +2472,7 @@ def test_tiff_ovr_color_table_bug_3336_bis(): def test_tiff_ovr_nodata_multiband(): + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") temp_path = "/vsimem/test.tif" diff --git a/autotest/gcore/tiff_write.py b/autotest/gcore/tiff_write.py index 30cdc78e6e24..0bde9fdaa022 100755 --- a/autotest/gcore/tiff_write.py +++ b/autotest/gcore/tiff_write.py @@ -149,6 +149,7 @@ def test_tiff_write_3(): def test_tiff_write_4(): + pytest.importorskip("osgeo.gdal_array") np = pytest.importorskip("numpy") options = ["TILED=YES", "BLOCKXSIZE=32", "BLOCKYSIZE=32"] diff --git a/autotest/gcore/virtualmem.py b/autotest/gcore/virtualmem.py index ffa947a506bf..ba464d4f1ed7 100755 --- a/autotest/gcore/virtualmem.py +++ b/autotest/gcore/virtualmem.py @@ -19,7 +19,9 @@ from osgeo import gdal # All tests will be skipped if numpy unavailable or SKIP_VIRTUALMEM is set. +pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") + pytestmark = pytest.mark.skipif( gdal.GetConfigOption("SKIP_VIRTUALMEM"), reason="SKIP_VIRTUALMEM is set in config" ) diff --git a/autotest/gcore/vrt_read.py b/autotest/gcore/vrt_read.py index 5fb40487e4e3..516298a22073 100755 --- a/autotest/gcore/vrt_read.py +++ b/autotest/gcore/vrt_read.py @@ -128,6 +128,7 @@ def test_vrt_read_3(): def test_vrt_read_4(): + pytest.importorskip("osgeo.gdal_array") np = pytest.importorskip("numpy") data = np.zeros((1, 1), np.complex64) @@ -961,6 +962,7 @@ def test_vrt_read_22(): def test_vrt_read_23(): + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") mem_ds = gdal.GetDriverByName("GTiff").Create("/vsimem/vrt_read_23.tif", 2, 1) diff --git a/autotest/gdrivers/lcp.py b/autotest/gdrivers/lcp.py index 1ce6ea65e92e..5f401b760de5 100755 --- a/autotest/gdrivers/lcp.py +++ b/autotest/gdrivers/lcp.py @@ -849,6 +849,8 @@ def test_lcp_21(): def test_lcp_22(): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") mem_drv = gdal.GetDriverByName("MEM") diff --git a/autotest/gdrivers/memmultidim.py b/autotest/gdrivers/memmultidim.py index 3d9fa42ec75b..88de74b60c25 100755 --- a/autotest/gdrivers/memmultidim.py +++ b/autotest/gdrivers/memmultidim.py @@ -2038,6 +2038,10 @@ def test_mem_md_array_get_mask(): try: import numpy + from osgeo import gdal_array + + str(gdal_array) + has_numpy = True except ImportError: has_numpy = False diff --git a/autotest/gdrivers/netcdf.py b/autotest/gdrivers/netcdf.py index 106f9208075a..4989bc72a168 100755 --- a/autotest/gdrivers/netcdf.py +++ b/autotest/gdrivers/netcdf.py @@ -2920,10 +2920,8 @@ def test_netcdf_66(tmp_path): def test_netcdf_67(): - try: - import numpy - except ImportError: - pytest.skip() + pytest.importorskip("osgeo.gdal_array") + numpy = pytest.importorskip("numpy") # disable bottom-up mode to use the real file's blocks size with gdal.config_option("GDAL_NETCDF_BOTTOMUP", "NO"): diff --git a/autotest/gdrivers/rmf.py b/autotest/gdrivers/rmf.py index bc1aed810491..6834d6a71ac1 100755 --- a/autotest/gdrivers/rmf.py +++ b/autotest/gdrivers/rmf.py @@ -702,6 +702,8 @@ def rmf_31e_data_gen(min_val, max_val, stripeSize, sx): def test_rmf_31e(): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") drv = gdal.GetDriverByName("Gtiff") @@ -846,6 +848,8 @@ def test_rmf_33c(): def test_rmf_34(): + + pytest.importorskip("osgeo.gdal_array") numpy = pytest.importorskip("numpy") drv = gdal.GetDriverByName("RMF") diff --git a/autotest/gdrivers/tiledb_write.py b/autotest/gdrivers/tiledb_write.py index c75a73b0095d..6f23a72e8543 100755 --- a/autotest/gdrivers/tiledb_write.py +++ b/autotest/gdrivers/tiledb_write.py @@ -73,6 +73,8 @@ def test_tiledb_write_custom_blocksize(tmp_path, mode): @pytest.mark.parametrize("mode", ["BAND", "PIXEL"]) def test_tiledb_write_update(tmp_path, mode): + + pytest.importorskip("osgeo.gdal_array") np = pytest.importorskip("numpy") gdaltest.tiledb_drv = gdal.GetDriverByName("TileDB") @@ -240,6 +242,8 @@ def test_tiledb_write_band_meta(tmp_path, mode): @pytest.mark.parametrize("mode", ["BAND", "PIXEL"]) def test_tiledb_write_history(tmp_path, mode): + + pytest.importorskip("osgeo.gdal_array") np = pytest.importorskip("numpy") options = ["INTERLEAVE=%s" % (mode), "TILEDB_TIMESTAMP=1"] diff --git a/autotest/gdrivers/vrtderived.py b/autotest/gdrivers/vrtderived.py index 52220fc4a09d..63dbdc7ea2b6 100755 --- a/autotest/gdrivers/vrtderived.py +++ b/autotest/gdrivers/vrtderived.py @@ -228,12 +228,7 @@ def test_vrtderived_5(): def test_vrtderived_6(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") with gdal.config_option("GDAL_VRT_ENABLE_PYTHON", "YES"): ds = gdal.Open("data/vrt/python_ones.vrt") @@ -319,12 +314,7 @@ def test_vrtderived_7(): def test_vrtderived_8(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") with gdal.config_option("GDAL_VRT_ENABLE_PYTHON", "NO"): ds = gdal.Open("data/vrt/n43_hillshade.vrt") @@ -344,12 +334,7 @@ def test_vrtderived_8(): def test_vrtderived_9(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") # Missing PixelFunctionType with gdal.quiet_errors(): @@ -637,12 +622,7 @@ def one_pix_func( def test_vrtderived_10(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") content = """ @@ -706,12 +686,7 @@ def test_vrtderived_10(): def test_vrtderived_11(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") gdal.FileFromMemBuffer( "/vsimem/n43_hillshade.vrt", @@ -742,12 +717,7 @@ def test_vrtderived_11(): def test_vrtderived_12(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") for dt in [ "Byte", @@ -834,12 +804,7 @@ def test_vrtderived_12(): def test_vrtderived_13(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") with gdal.config_option("GDAL_VRT_ENABLE_PYTHON", "YES"): # Will test the VRTDerivedRasterBand::IGetDataCoverageStatus() interface @@ -859,12 +824,7 @@ def test_vrtderived_13(): def test_vrtderived_14(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") with gdal.config_option("GDAL_VRT_ENABLE_PYTHON", "YES"): ds = gdal.GetDriverByName("VRT").CreateCopy( @@ -914,12 +874,7 @@ def vrtderived_15_worker(args_dict): def test_vrtderived_15(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") gdal.SetConfigOption("GDAL_VRT_ENABLE_PYTHON", "YES") @@ -951,12 +906,7 @@ def test_vrtderived_15(): def test_vrtderived_skip_non_contributing_sources(): - try: - import numpy - - numpy.ones - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("numpy") def create_vrt(SkipNonContributingSources): Trace = "" @@ -1032,6 +982,8 @@ def identity(in_ar, out_ar, xoff, yoff, xsize, ysize, raster_xsize, raster_ysize @pytest.mark.parametrize("dtype", range(1, gdal.GDT_TypeCount)) def test_vrt_derived_dtype(tmp_vsimem, dtype): + + pytest.importorskip("osgeo.gdal_array") pytest.importorskip("numpy") input_fname = tmp_vsimem / "input.tif" diff --git a/autotest/gdrivers/vrtpansharpen.py b/autotest/gdrivers/vrtpansharpen.py index f5022e682b62..c6a0186aab35 100755 --- a/autotest/gdrivers/vrtpansharpen.py +++ b/autotest/gdrivers/vrtpansharpen.py @@ -1315,10 +1315,8 @@ def test_vrtpansharpen_5(): def test_vrtpansharpen_6(): - try: - import numpy - except (ImportError, AttributeError): - pytest.skip() + pytest.importorskip("osgeo.gdal_array") + numpy = pytest.importorskip("numpy") # i = 0: VRT has 7 # i = 1: bands have NBITS=7 and VRT 7 diff --git a/autotest/ogr/ogr_parquet.py b/autotest/ogr/ogr_parquet.py index 0f8f58e15574..60eed5bf9ca1 100755 --- a/autotest/ogr/ogr_parquet.py +++ b/autotest/ogr/ogr_parquet.py @@ -1195,6 +1195,10 @@ def test_ogr_parquet_polygon_orientation(option_value, written_wkt, expected_wkt try: import numpy + from osgeo import gdal_array + + str(gdal_array) + numpy.zeros has_numpy = True diff --git a/autotest/pyscripts/test_gdal2tiles.py b/autotest/pyscripts/test_gdal2tiles.py index 786b1711d27b..6cf57c3a4b2f 100755 --- a/autotest/pyscripts/test_gdal2tiles.py +++ b/autotest/pyscripts/test_gdal2tiles.py @@ -722,6 +722,8 @@ def test_gdal2tiles_py_jpeg_3band_input( script_path, tmp_path, resampling, expected_stats_z0, expected_stats_z1 ): + pytest.importorskip("osgeo.gdal_array") + if resampling == "antialias" and not pil_available(): pytest.skip("'antialias' resampling is not available") @@ -786,6 +788,8 @@ def test_gdal2tiles_py_jpeg_1band_input( script_path, tmp_path, resampling, expected_stats_z14, expected_stats_z13 ): + pytest.importorskip("osgeo.gdal_array") + if resampling == "antialias" and not pil_available(): pytest.skip("'antialias' resampling is not available") diff --git a/autotest/pyscripts/test_gdal2xyz.py b/autotest/pyscripts/test_gdal2xyz.py index 27d105dacd12..399e727c4bc4 100644 --- a/autotest/pyscripts/test_gdal2xyz.py +++ b/autotest/pyscripts/test_gdal2xyz.py @@ -20,6 +20,7 @@ # test that osgeo_utils is available, if not skip all tests pytest.importorskip("osgeo_utils") +pytest.importorskip("osgeo.gdal_array") pytest.importorskip("numpy") from itertools import product diff --git a/autotest/pyscripts/test_gdal_retile.py b/autotest/pyscripts/test_gdal_retile.py index 49acd9a6978a..db9a1373129d 100755 --- a/autotest/pyscripts/test_gdal_retile.py +++ b/autotest/pyscripts/test_gdal_retile.py @@ -351,6 +351,7 @@ def test_gdal_retile_4(script_path, tmp_path): def test_gdal_retile_5(script_path, tmp_path): + pytest.importorskip("osgeo.gdal_array") np = pytest.importorskip("numpy") nodata_value = -3.4028234663852886e38 diff --git a/autotest/pyscripts/test_validate_geoparquet.py b/autotest/pyscripts/test_validate_geoparquet.py index a4ecd5571a3b..d5593d5defe4 100755 --- a/autotest/pyscripts/test_validate_geoparquet.py +++ b/autotest/pyscripts/test_validate_geoparquet.py @@ -247,6 +247,7 @@ def test_validate_geoparquet_invalid_bbox(tmp_path, bbox, error_msg): def test_validate_geoparquet_invalid_wkb(tmp_path): + pytest.importorskip("osgeo.gdal_array") pytest.importorskip("numpy") test_dir = str(tmp_path / "tmp.parquet") @@ -274,6 +275,7 @@ def test_validate_geoparquet_invalid_wkb(tmp_path): def test_validate_geoparquet_geom_type_not_consistent_with_declaration(tmp_path): + pytest.importorskip("osgeo.gdal_array") pytest.importorskip("numpy") test_dir = str(tmp_path / "tmp.parquet") @@ -304,6 +306,7 @@ def test_validate_geoparquet_geom_type_not_consistent_with_declaration(tmp_path) def test_validate_geoparquet_invalid_winding_order(tmp_path): + pytest.importorskip("osgeo.gdal_array") pytest.importorskip("numpy") test_dir = str(tmp_path / "tmp.parquet") diff --git a/autotest/utilities/test_gdal_rasterize.py b/autotest/utilities/test_gdal_rasterize.py index 2f3fb1107eee..982b25c5c833 100755 --- a/autotest/utilities/test_gdal_rasterize.py +++ b/autotest/utilities/test_gdal_rasterize.py @@ -346,7 +346,7 @@ def test_gdal_rasterize_6(gdal_rasterize_path, tmp_path): @pytest.mark.parametrize("sql_in_file", [False, True]) def test_gdal_rasterize_7(gdal_rasterize_path, sql_in_file, tmp_path): - pytest.importorskip("numpy") + pytest.importorskip("osgeo.gdal_array") input_csv = str(tmp_path / "test_gdal_rasterize_7.csv") output_tif = str(tmp_path / "test_gdal_rasterize_7.tif") diff --git a/autotest/utilities/test_gdal_viewshed.py b/autotest/utilities/test_gdal_viewshed.py index 6cb72171e5b5..286ca9e3bf34 100755 --- a/autotest/utilities/test_gdal_viewshed.py +++ b/autotest/utilities/test_gdal_viewshed.py @@ -207,6 +207,7 @@ def test_gdal_viewshed_all_options(gdal_viewshed_path, tmp_path, viewshed_input) def test_gdal_viewshed_cumulative(gdal_viewshed_path, tmp_path, viewshed_input): np = pytest.importorskip("numpy") + pytest.importorskip("osgeo.gdal_array") viewshed_out = str(tmp_path / "test_gdal_viewshed_out.tif") diff --git a/autotest/utilities/test_gdallocationinfo.py b/autotest/utilities/test_gdallocationinfo.py index 8ebebf2b471b..a7b679a855fe 100755 --- a/autotest/utilities/test_gdallocationinfo.py +++ b/autotest/utilities/test_gdallocationinfo.py @@ -403,6 +403,9 @@ def test_gdallocationinfo_value_interpolate_invalid_method(gdallocationinfo_path def test_gdallocationinfo_interpolate_float_data(gdallocationinfo_path, tmp_path): + + pytest.importorskip("osgeo.gdal_array") + dst_filename = str(tmp_path / "tmp_float.tif") driver = gdal.GetDriverByName("GTiff") dst_ds = driver.Create( From 6378b44a0290d8a7bcd4ce0121b5e6891f1597da Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 20 Feb 2025 11:52:18 +0100 Subject: [PATCH 2/2] Python bindings: honour GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY=YES/1/ON/TRUE or NO/0/OFF/FALSE Fixes #11853 --- swig/python/setup.py.in | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/swig/python/setup.py.in b/swig/python/setup.py.in index a0640f8e0163..547ea70ed699 100644 --- a/swig/python/setup.py.in +++ b/swig/python/setup.py.in @@ -186,20 +186,32 @@ if sys.platform == 'win32': numpy_include_dir = '.' numpy_error_msg = "" -try: - numpy_include_dir = get_numpy_include() - HAVE_NUMPY = numpy_include_dir != '.' + +do_numpy_detection = True +if "GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY" in os.environ: + v = os.environ["GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY"].upper() + if v in ('YES', '1', 'ON', 'TRUE'): + do_numpy_detection = False + elif v not in ('NO', '0', 'OFF', 'FALSE'): + raise Exception("Unrecognized value for GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY") + +if do_numpy_detection: + try: + numpy_include_dir = get_numpy_include() + HAVE_NUMPY = numpy_include_dir != '.' + if not HAVE_NUMPY: + numpy_error_msg = "numpy found, but numpy headers were not found!" + except ImportError: + HAVE_NUMPY = False + numpy_error_msg = "numpy not available!" + if not HAVE_NUMPY: - numpy_error_msg = "numpy found, but numpy headers were not found!" -except ImportError: + if "GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY" in os.environ: + print("WARNING: " + numpy_error_msg + " Array support will not be enabled.") + else: + raise Exception(numpy_error_msg + " This error may happen if you build/install using setup.py directly, but should normally not happen if you install using pip install. If you still want to build the bindings without numpy support, define the GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY environment variable") +else: HAVE_NUMPY = False - numpy_error_msg = "numpy not available!" - -if not HAVE_NUMPY: - if "GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY" in os.environ: - print("WARNING: " + numpy_error_msg + " Array support will not be enabled.") - else: - raise Exception(numpy_error_msg + " This error may happen if you build/install using setup.py directly, but should normally not happen if you install using pip install. If you still want to build the bindings without numpy support, define the GDAL_PYTHON_BINDINGS_WITHOUT_NUMPY environment variable") class gdal_ext(build_ext):