From 9880c5c40faf44a031e722a7bc177f35cd73e5e2 Mon Sep 17 00:00:00 2001 From: "Alan D. Snow" Date: Fri, 5 Dec 2025 08:47:04 -0600 Subject: [PATCH] DEP: Python 3.10+ & GDAL 3.6+ (#3440) --- .github/workflows/tests.yaml | 16 +++++++--------- CONTRIBUTING.rst | 4 ++-- Dockerfile | 2 +- Makefile | 2 +- README.rst | 2 +- docs/installation.rst | 2 +- rasterio/features.py | 10 ---------- setup.py | 7 +++---- tests/test__env.py | 7 ++++++- tests/test_warp.py | 3 +-- 10 files changed, 23 insertions(+), 32 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index dcec9536..28c6ba12 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -97,23 +97,21 @@ jobs: strategy: fail-fast: false matrix: - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] gdal-version: ['3.11.5'] include: - python-version: '3.14' gdal-version: 'latest' - - python-version: '3.9' + - python-version: '3.10' gdal-version: '3.10.3' - - python-version: '3.9' + - python-version: '3.10' gdal-version: '3.9.3' - - python-version: '3.9' + - python-version: '3.10' gdal-version: '3.8.5' - - python-version: '3.9' + - python-version: '3.10' gdal-version: '3.7.3' - - python-version: '3.9' + - python-version: '3.10' gdal-version: '3.6.4' - - python-version: '3.9' - gdal-version: '3.5.3' steps: - uses: actions/checkout@v6 @@ -157,7 +155,7 @@ jobs: # macos-15-intel is OSX Intel # macos-14 is OSX Arm64 os: [macos-15-intel, macos-14] - python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14'] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] include: - os: ubuntu-latest python-version: '*' diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3c285e08..21758c5c 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -122,7 +122,7 @@ C extension modules are written using `Cython `__. The Cython language is a superset of Python. Cython files end with ``.pyx`` and ``.pxd`` and are where we keep all the code that calls GDAL's C functions. -Rasterio works with Python versions 3.6 through 3.9. +Rasterio works with Python versions 3.10 through 3.14. We strongly prefer code adhering to `PEP8 `__. @@ -161,7 +161,7 @@ Developing Rasterio requires Python 3.6 or any final release after and including 3.10. We prefer developing with the most recent version of Python but recognize this is not possible for all contributors. A C compiler is also required to leverage `existing protocols -`__ for extending Python +`__ for extending Python with C or C++. See the Windows install instructions in the `readme `__ for more information about building on Windows. diff --git a/Dockerfile b/Dockerfile index 7ad99b50..fdef2521 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ ARG GDAL=ubuntu-small-3.6.4 FROM ghcr.io/osgeo/gdal:${GDAL} AS gdal -ARG PYTHON_VERSION=3.9 +ARG PYTHON_VERSION=3.10 ENV LANG="C.UTF-8" LC_ALL="C.UTF-8" RUN apt-get update && apt-get install -y software-properties-common RUN add-apt-repository -y ppa:deadsnakes/ppa diff --git a/Makefile b/Makefile index 02aad1e2..db38eac9 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PYTHON_VERSION ?= 3.9 +PYTHON_VERSION ?= 3.10 GDAL ?= ubuntu-small-3.6.4 all: deps clean install test diff --git a/README.rst b/README.rst index ba62c392..17b74775 100644 --- a/README.rst +++ b/README.rst @@ -20,7 +20,7 @@ Geographic information systems use GeoTIFF and other formats to organize and store gridded, or raster, datasets. Rasterio reads and writes these formats and provides a Python API based on N-D arrays. -Rasterio 1.4 works with Python >= 3.9, Numpy >= 1.24, and GDAL >= 3.5. Official +Rasterio 1.4.4+ works with Python >= 3.10, Numpy >= 1.24, and GDAL >= 3.6. Official binary packages for Linux, macOS, and Windows with most built-in format drivers plus HDF5, netCDF, and OpenJPEG2000 are available on PyPI. diff --git a/docs/installation.rst b/docs/installation.rst index 65a5f123..99be3510 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -27,7 +27,7 @@ optional format drivers. Many users find Anaconda and conda-forge a good way to install Rasterio and get access to more optional format drivers (like TileDB and others). -Rasterio 1.4 requires Python 3.9 or higher and GDAL 3.5 or higher. +Rasterio 1.4.4+ requires Python 3.10 or higher and GDAL 3.5 or higher. Advanced installation ===================== diff --git a/rasterio/features.py b/rasterio/features.py index 2f4d958d..9d453067 100644 --- a/rasterio/features.py +++ b/rasterio/features.py @@ -348,16 +348,6 @@ def rasterize( values_arr = np.array(shape_values) dtype = values_arr.dtype.name - # GDAL 3.5 doesn't support int64 output. We'll try int32. - if dtype not in valid_dtypes and dtype.startswith("int"): - lo, hi = values_arr.min(), values_arr.max() - if -2147483648 <= lo and hi <= 2147483647: - dtype = "int32" - elif 0 <= lo and hi <= 4294967295: - dtype = "uint32" - else: - raise ValueError("GDAL versions < 3.6 cannot rasterize int64 values.") - with ExitStack() as exit_stack: if dst_path is not None: if isinstance(dst_path, DatasetWriter): diff --git a/setup.py b/setup.py index 4f204654..40ee1075 100755 --- a/setup.py +++ b/setup.py @@ -133,8 +133,8 @@ if "clean" not in sys.argv: int, re.findall("[0-9]+", gdalversion)[:3] ) - if (gdal_major_version, gdal_minor_version) < (3, 5): - raise SystemExit("ERROR: GDAL >= 3.5 is required for rasterio. " + if (gdal_major_version, gdal_minor_version) < (3, 6): + raise SystemExit("ERROR: GDAL >= 3.6 is required for rasterio. " "Please upgrade GDAL.") # Conditionally copy the GDAL data. To be used in conjunction with @@ -297,7 +297,6 @@ setup_args = dict( "License :: OSI Approved :: BSD License", "Programming Language :: C", "Programming Language :: Cython", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", @@ -319,7 +318,7 @@ setup_args = dict( zip_safe=False, install_requires=inst_reqs, extras_require=extra_reqs, - python_requires=">=3.9", + python_requires=">=3.10", ) if os.environ.get('PACKAGE_DATA'): diff --git a/tests/test__env.py b/tests/test__env.py index 17ab352b..29e676db 100644 --- a/tests/test__env.py +++ b/tests/test__env.py @@ -34,8 +34,13 @@ def mock_fhs(tmpdir): @pytest.fixture def mock_debian(tmpdir): """A fake Debian multi-install system""" - tmpdir.ensure("share/gdal/3.5/gdalvrt.xsd") tmpdir.ensure("share/gdal/3.6/gdalvrt.xsd") + tmpdir.ensure("share/gdal/3.7/gdalvrt.xsd") + tmpdir.ensure("share/gdal/3.8/gdalvrt.xsd") + tmpdir.ensure("share/gdal/3.9/gdalvrt.xsd") + tmpdir.ensure("share/gdal/3.10/gdalvrt.xsd") + tmpdir.ensure("share/gdal/3.11/gdalvrt.xsd") + tmpdir.ensure("share/gdal/3.12/gdalvrt.xsd") tmpdir.ensure(f"share/gdal/{gdal_version.major}.{gdal_version.minor}/gdalvrt.xsd") tmpdir.ensure("share/proj/epsg") return tmpdir diff --git a/tests/test_warp.py b/tests/test_warp.py index 385325b7..c01d4b39 100644 --- a/tests/test_warp.py +++ b/tests/test_warp.py @@ -2487,8 +2487,7 @@ def test_geoloc_warp_dataset(data, tmp_path): # MEM:::DATAPOINTER=137539856,PIXELS=791,LINES=718,BANDS=3,DATATYPE=Byte. # There is no affine transformation and no GCPs. Specify transformation # option SRC_METHOD=NO_GEOTRANSFORM to bypass this check. -@pytest.mark.skipif(not gdal_version.at_least("3.6"), reason="Requires GDAL 3.6") -def test_geoloc_warp_array(path_rgb_byte_tif, tmp_path): +def test_geoloc_warp_array(path_rgb_byte_tif): """Warp an array using external geolocation arrays.""" with rasterio.open(path_rgb_byte_tif) as src: xs, ys = src.transform * np.meshgrid(