5
5
import time
6
6
import traceback
7
7
from collections .abc import Iterable
8
+ from glob import glob
8
9
from typing import TYPE_CHECKING , Any , ClassVar
9
10
10
11
import numpy as np
19
20
from io import BufferedIOBase
20
21
21
22
from xarray .core .dataset import Dataset
23
+ from xarray .core .types import NestedSequence
22
24
23
25
# Create a logger object, but don't add any handlers. Leave that to user code.
24
26
logger = logging .getLogger (__name__ )
28
30
29
31
30
32
def _normalize_path (path ):
33
+ """
34
+ Normalize pathlikes to string.
35
+
36
+ Parameters
37
+ ----------
38
+ path :
39
+ Path to file.
40
+
41
+ Examples
42
+ --------
43
+ >>> from pathlib import Path
44
+
45
+ >>> directory = Path(xr.backends.common.__file__).parent
46
+ >>> paths_path = Path(directory).joinpath("comm*n.py")
47
+ >>> paths_str = xr.backends.common._normalize_path(paths_path)
48
+ >>> print([type(p) for p in (paths_str,)])
49
+ [<class 'str'>]
50
+ """
31
51
if isinstance (path , os .PathLike ):
32
52
path = os .fspath (path )
33
53
@@ -37,6 +57,64 @@ def _normalize_path(path):
37
57
return path
38
58
39
59
60
+ def _find_absolute_paths (
61
+ paths : str | os .PathLike | NestedSequence [str | os .PathLike ], ** kwargs
62
+ ) -> list [str ]:
63
+ """
64
+ Find absolute paths from the pattern.
65
+
66
+ Parameters
67
+ ----------
68
+ paths :
69
+ Path(s) to file(s). Can include wildcards like * .
70
+ **kwargs :
71
+ Extra kwargs. Mainly for fsspec.
72
+
73
+ Examples
74
+ --------
75
+ >>> from pathlib import Path
76
+
77
+ >>> directory = Path(xr.backends.common.__file__).parent
78
+ >>> paths = str(Path(directory).joinpath("comm*n.py")) # Find common with wildcard
79
+ >>> paths = xr.backends.common._find_absolute_paths(paths)
80
+ >>> [Path(p).name for p in paths]
81
+ ['common.py']
82
+ """
83
+ if isinstance (paths , str ):
84
+ if is_remote_uri (paths ) and kwargs .get ("engine" , None ) == "zarr" :
85
+ try :
86
+ from fsspec .core import get_fs_token_paths
87
+ except ImportError as e :
88
+ raise ImportError (
89
+ "The use of remote URLs for opening zarr requires the package fsspec"
90
+ ) from e
91
+
92
+ fs , _ , _ = get_fs_token_paths (
93
+ paths ,
94
+ mode = "rb" ,
95
+ storage_options = kwargs .get ("backend_kwargs" , {}).get (
96
+ "storage_options" , {}
97
+ ),
98
+ expand = False ,
99
+ )
100
+ tmp_paths = fs .glob (fs ._strip_protocol (paths )) # finds directories
101
+ paths = [fs .get_mapper (path ) for path in tmp_paths ]
102
+ elif is_remote_uri (paths ):
103
+ raise ValueError (
104
+ "cannot do wild-card matching for paths that are remote URLs "
105
+ f"unless engine='zarr' is specified. Got paths: { paths } . "
106
+ "Instead, supply paths as an explicit list of strings."
107
+ )
108
+ else :
109
+ paths = sorted (glob (_normalize_path (paths )))
110
+ elif isinstance (paths , os .PathLike ):
111
+ paths = [os .fspath (paths )]
112
+ else :
113
+ paths = [os .fspath (p ) if isinstance (p , os .PathLike ) else p for p in paths ]
114
+
115
+ return paths
116
+
117
+
40
118
def _encode_variable_name (name ):
41
119
if name is None :
42
120
name = NONE_VAR_NAME
0 commit comments