@@ -7252,6 +7252,77 @@ def test_zarr_entrypoint(tmp_path: Path) -> None:
7252
7252
assert not entrypoint .guess_can_open ("something.zarr.txt" )
7253
7253
7254
7254
7255
+ @requires_netCDF4
7256
+ @requires_pydap
7257
+ @requires_zarr
7258
+ def test_remote_url_backend_auto_detection () -> None :
7259
+ """
7260
+ Test that remote URLs are correctly claimed by appropriate backends.
7261
+
7262
+ This tests the fix for issue where netCDF4 and pydap backends were
7263
+ claiming ALL remote URLs, preventing remote Zarr stores from being
7264
+ auto-detected.
7265
+
7266
+ See: https://github.com/pydata/xarray/issues/XXXXX
7267
+ """
7268
+ from xarray .backends .netCDF4_ import NetCDF4BackendEntrypoint
7269
+ from xarray .backends .pydap_ import PydapBackendEntrypoint
7270
+ from xarray .backends .zarr import ZarrBackendEntrypoint
7271
+
7272
+ netcdf4_entrypoint = NetCDF4BackendEntrypoint ()
7273
+ pydap_entrypoint = PydapBackendEntrypoint ()
7274
+ zarr_entrypoint = ZarrBackendEntrypoint ()
7275
+
7276
+ # Remote Zarr URLs should be claimed by Zarr backend, not netCDF4/pydap
7277
+ remote_zarr_urls = [
7278
+ "https://example.com/store.zarr" ,
7279
+ "http://example.com/data.zarr/" ,
7280
+ "s3://bucket/path/to/data.zarr" ,
7281
+ ]
7282
+
7283
+ for url in remote_zarr_urls :
7284
+ assert zarr_entrypoint .guess_can_open (url ), f"Zarr should claim { url } "
7285
+ assert not netcdf4_entrypoint .guess_can_open (url ), (
7286
+ f"NetCDF4 should not claim { url } "
7287
+ )
7288
+ assert not pydap_entrypoint .guess_can_open (url ), f"Pydap should not claim { url } "
7289
+
7290
+ # Remote netCDF URLs with extensions should be claimed by netCDF4, not Zarr
7291
+ remote_netcdf_urls_with_ext = [
7292
+ "https://example.com/file.nc" ,
7293
+ "http://example.com/data.nc4" ,
7294
+ "https://example.com/test.cdf" ,
7295
+ ]
7296
+
7297
+ for url in remote_netcdf_urls_with_ext :
7298
+ assert not zarr_entrypoint .guess_can_open (url ), f"Zarr should not claim { url } "
7299
+ assert netcdf4_entrypoint .guess_can_open (url ), f"NetCDF4 should claim { url } "
7300
+
7301
+ # OPeNDAP endpoints (no extension) should be claimed by both netCDF4 and pydap
7302
+ opendap_urls = [
7303
+ "http://opendap.example.com/data" ,
7304
+ "https://test.opendap.org/dataset" ,
7305
+ ]
7306
+
7307
+ for url in opendap_urls :
7308
+ assert not zarr_entrypoint .guess_can_open (url ), f"Zarr should not claim { url } "
7309
+ assert netcdf4_entrypoint .guess_can_open (url ), f"NetCDF4 should claim { url } "
7310
+ assert pydap_entrypoint .guess_can_open (url ), f"Pydap should claim { url } "
7311
+
7312
+ # Other file types should not be claimed
7313
+ other_urls = [
7314
+ "https://example.com/data.zip" ,
7315
+ "https://example.com/data.tar.gz" ,
7316
+ ]
7317
+
7318
+ for url in other_urls :
7319
+ assert not zarr_entrypoint .guess_can_open (url ), f"Zarr should not claim { url } "
7320
+ assert not netcdf4_entrypoint .guess_can_open (url ), (
7321
+ f"NetCDF4 should not claim { url } "
7322
+ )
7323
+ assert not pydap_entrypoint .guess_can_open (url ), f"Pydap should not claim { url } "
7324
+
7325
+
7255
7326
@requires_netCDF4
7256
7327
@pytest .mark .parametrize ("str_type" , (str , np .str_ ))
7257
7328
def test_write_file_from_np_str (str_type : type [str | np .str_ ], tmpdir : str ) -> None :
0 commit comments