Description
read_geotiff_gpu(..., stable_only=True) accepts the stable_only kwarg but never enforces it. The function runs _validate_dispatch_kwargs for the generic dispatcher checks, but it skips _validate_stable_only_remote, the gate that rejects advanced-tier HTTP / fsspec sources when a caller asks for stable-tier sources only.
Both sibling entry points already apply this gate:
open_geotiff calls _validate_stable_only_remote(source, stable_only=..., allow_experimental_codecs=...) before dispatch (xrspatial/geotiff/__init__.py).
read_geotiff_dask calls the same helper for its own direct entry point (xrspatial/geotiff/_backends/dask.py).
read_geotiff_gpu is also a public direct entry point, but it skips the gate. For HTTP / fsspec sources the GPU path routes through a CPU fallback, so a direct GPU call goes ahead and reads a remote source that open_geotiff and read_geotiff_dask reject. The GPU docstring makes it worse by calling stable_only a no-op on the GPU path, which is wrong for remote sources.
Impact
Backend-level API behavior diverges. A downstream caller using the GPU read API directly does not get the stability guarantee they asked for with stable_only=True. They can read an advanced-tier remote source that the other two readers turn away.
Expected behavior
read_geotiff_gpu(remote_source, stable_only=True) should raise RemoteStableSourcesOnlyError, matching open_geotiff and read_geotiff_dask. Passing allow_experimental_codecs=True should unlock it the same way.
Coverage gap
There is no test for read_geotiff_gpu(remote, stable_only=True). The existing regression suite for this gate (test_stable_only_remote_2821.py) covers the eager and dask paths but not the GPU entry point.
Fix
Call _validate_stable_only_remote(...) in read_geotiff_gpu before the cupy import, the CUDA preflight, and the remote CPU fallback, the same way open_geotiff and read_geotiff_dask call it. Update the GPU docstring so stable_only is no longer described as a no-op.
Description
read_geotiff_gpu(..., stable_only=True)accepts thestable_onlykwarg but never enforces it. The function runs_validate_dispatch_kwargsfor the generic dispatcher checks, but it skips_validate_stable_only_remote, the gate that rejects advanced-tier HTTP / fsspec sources when a caller asks for stable-tier sources only.Both sibling entry points already apply this gate:
open_geotiffcalls_validate_stable_only_remote(source, stable_only=..., allow_experimental_codecs=...)before dispatch (xrspatial/geotiff/__init__.py).read_geotiff_daskcalls the same helper for its own direct entry point (xrspatial/geotiff/_backends/dask.py).read_geotiff_gpuis also a public direct entry point, but it skips the gate. For HTTP / fsspec sources the GPU path routes through a CPU fallback, so a direct GPU call goes ahead and reads a remote source thatopen_geotiffandread_geotiff_daskreject. The GPU docstring makes it worse by callingstable_onlya no-op on the GPU path, which is wrong for remote sources.Impact
Backend-level API behavior diverges. A downstream caller using the GPU read API directly does not get the stability guarantee they asked for with
stable_only=True. They can read an advanced-tier remote source that the other two readers turn away.Expected behavior
read_geotiff_gpu(remote_source, stable_only=True)should raiseRemoteStableSourcesOnlyError, matchingopen_geotiffandread_geotiff_dask. Passingallow_experimental_codecs=Trueshould unlock it the same way.Coverage gap
There is no test for
read_geotiff_gpu(remote, stable_only=True). The existing regression suite for this gate (test_stable_only_remote_2821.py) covers the eager and dask paths but not the GPU entry point.Fix
Call
_validate_stable_only_remote(...)inread_geotiff_gpubefore the cupy import, the CUDA preflight, and the remote CPU fallback, the same wayopen_geotiffandread_geotiff_daskcall it. Update the GPU docstring sostable_onlyis no longer described as a no-op.