Skip to content

Commit 741e99e

Browse files
committed
fix: never use string-based imports
1 parent 3be1eb6 commit 741e99e

File tree

1 file changed

+14
-51
lines changed

1 file changed

+14
-51
lines changed

src/zarr/core/array_spec.py

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from typing_extensions import TypedDict
77

8-
from zarr.abc.codec import ArrayArrayCodec, ArrayBytesCodec, BytesBytesCodec, Codec, CodecPipeline
98
from zarr.core.common import (
109
MemoryOrder,
1110
parse_bool,
@@ -19,6 +18,13 @@
1918
from collections.abc import Mapping
2019
from typing import NotRequired
2120

21+
from zarr.abc.codec import (
22+
ArrayArrayCodec,
23+
ArrayBytesCodec,
24+
BytesBytesCodec,
25+
Codec,
26+
CodecPipeline,
27+
)
2228
from zarr.core.buffer import BufferPrototype
2329
from zarr.core.dtype.wrapper import TBaseDType, TBaseScalar, ZDType
2430

@@ -187,67 +193,24 @@ def to_dict(self) -> ArrayConfigParams:
187193
ArrayConfigLike = ArrayConfig | ArrayConfigRequest
188194

189195

190-
def _import_by_name(path: str) -> object | type:
191-
"""
192-
Import an object by its fully qualified name.
193-
"""
194-
import importlib
195-
196-
parts = path.split(".")
197-
198-
# Try progressively shorter module paths
199-
for i in range(len(parts), 0, -1):
200-
module_path = ".".join(parts[:i])
201-
try:
202-
module = importlib.import_module(module_path)
203-
break
204-
except ModuleNotFoundError:
205-
continue
206-
else:
207-
raise ImportError(f"Could not import any module from '{path}'")
208-
209-
obj = module
210-
for attr in parts[i:]:
211-
try:
212-
obj = getattr(obj, attr)
213-
except AttributeError as e:
214-
raise ImportError(f"Attribute '{attr}' not found in '{obj}'") from e
215-
return obj
216-
217-
218196
def parse_codec_pipeline_class(obj: type[CodecPipeline] | None) -> type[CodecPipeline]:
219197
if obj is None:
220-
config_entry: dict[str, str] = zarr_config.get("codec_pipeline")
221-
if "path" not in config_entry:
222-
msg = (
223-
"The codec_pipeline field in the global config is malformed. "
224-
"Expected 'path' key was not found."
225-
)
226-
raise KeyError(msg)
227-
return _import_by_name(config_entry["path"]) # type: ignore[return-value]
198+
from zarr.registry import get_pipeline_class
199+
200+
return get_pipeline_class()
228201
return obj
229202

230203

231204
def parse_codec_class_map(obj: Mapping[str, type[Codec]] | None) -> Mapping[str, type[Codec]]:
232205
"""
233206
Convert a request for a codec class map into an actual Mapping[str, type[Codec]].
234-
If the input is `None`, then we look up the list of codecs from the registry, where they
235-
are stored as fully qualified class names. We must resolve these names to concrete classes
236-
before inserting them into the returned mapping.
207+
If the input is `None`, build the map from the codec registry.
237208
"""
238209
if obj is None:
210+
from zarr.registry import get_codec_class
211+
239212
name_map: dict[str, str] = zarr_config.get("codecs", {})
240-
out: dict[str, type[Codec]] = {}
241-
for key, value in name_map.items():
242-
maybe_cls = _import_by_name(value)
243-
if not isinstance(maybe_cls, type):
244-
msg = f"Expected a type, got {maybe_cls}"
245-
raise TypeError(msg)
246-
if not issubclass(maybe_cls, Codec):
247-
msg = f"Expected a subclass of `Codec`, got {maybe_cls}"
248-
raise TypeError(msg)
249-
out[key] = maybe_cls
250-
return out
213+
return {key: get_codec_class(key) for key in name_map}
251214
return obj
252215

253216

0 commit comments

Comments
 (0)