Skip to content

Commit aef42a1

Browse files
committed
fix incorrect path concatenation in make_store_path, and refactor store_path tests
1 parent b25f7e8 commit aef42a1

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

src/zarr/storage/common.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ async def make_store_path(
219219
if mode is not None and mode != store_like.store.mode.str:
220220
_store = store_like.store.with_mode(mode)
221221
await _store._ensure_open()
222-
store_like = StorePath(_store, path=store_like.path) / path_normalized
222+
store_like = StorePath(_store, path=store_like.path)
223223
result = store_like / path_normalized
224224
elif isinstance(store_like, Store):
225225
if mode is not None and mode != store_like.mode.str:

tests/v3/test_group.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import contextlib
44
import pickle
55
import warnings
6-
from typing import TYPE_CHECKING, Any, Literal, cast
6+
from typing import TYPE_CHECKING, Any, Literal
77

88
import numpy as np
99
import pytest
@@ -14,7 +14,6 @@
1414
from zarr import Array, AsyncArray, AsyncGroup, Group
1515
from zarr.abc.store import Store
1616
from zarr.core.buffer import default_buffer_prototype
17-
from zarr.core.common import JSON, ZarrFormat
1817
from zarr.core.group import ConsolidatedMetadata, GroupMetadata
1918
from zarr.core.sync import sync
2019
from zarr.errors import ContainsArrayError, ContainsGroupError
@@ -26,6 +25,8 @@
2625
if TYPE_CHECKING:
2726
from _pytest.compat import LEGACY_PATH
2827

28+
from zarr.core.common import JSON, ZarrFormat
29+
2930

3031
@pytest.fixture(params=["local", "memory", "zip"])
3132
async def store(request: pytest.FixtureRequest, tmpdir: LEGACY_PATH) -> Store:

tests/v3/test_store/test_core.py

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import tempfile
22
from pathlib import Path
3+
from typing import Literal
34

45
import pytest
6+
from _pytest.compat import LEGACY_PATH
57
from upath import UPath
68

79
from zarr.storage._utils import normalize_path
@@ -11,31 +13,59 @@
1113
from zarr.storage.remote import RemoteStore
1214

1315

14-
async def test_make_store_path(tmpdir: str) -> None:
15-
# None
16-
store_path = await make_store_path(None)
16+
@pytest.mark.parametrize("path", [None, "", "bar"])
17+
async def test_make_store_path_none(path: str) -> None:
18+
"""
19+
Test that creating a store_path with None creates a memorystore
20+
"""
21+
store_path = await make_store_path(None, path=path)
1722
assert isinstance(store_path.store, MemoryStore)
18-
19-
# str
20-
store_path = await make_store_path(str(tmpdir))
23+
assert store_path.path == normalize_path(path)
24+
25+
26+
@pytest.mark.parametrize("path", [None, "", "bar"])
27+
@pytest.mark.parametrize("store_type", [str, Path, LocalStore])
28+
@pytest.mark.parametrize("mode", ["r", "w", "a"])
29+
async def test_make_store_path_local(
30+
tmpdir: LEGACY_PATH,
31+
store_type: type[str] | type[Path] | type[LocalStore],
32+
path: str,
33+
mode: Literal["r", "w", "a"],
34+
) -> None:
35+
"""
36+
Test the various ways of invoking make_store_path that create a LocalStore
37+
"""
38+
store_like = store_type(str(tmpdir))
39+
store_path = await make_store_path(store_like, path=path, mode=mode)
2140
assert isinstance(store_path.store, LocalStore)
2241
assert Path(store_path.store.root) == Path(tmpdir)
23-
24-
# Path
25-
store_path = await make_store_path(Path(tmpdir))
42+
assert store_path.path == normalize_path(path)
43+
assert store_path.store.mode.str == mode
44+
45+
46+
@pytest.mark.parametrize("path", [None, "", "bar"])
47+
@pytest.mark.parametrize("mode", ["r", "w", "a"])
48+
async def test_make_store_path_store_path(
49+
tmpdir: LEGACY_PATH, path: str, mode: Literal["r", "w", "a"]
50+
) -> None:
51+
"""
52+
Test invoking make_store_path when the input is another store_path. In particular we want to ensure
53+
that a new path is handled correctly.
54+
"""
55+
store_like = StorePath(LocalStore(str(tmpdir)), path="root")
56+
store_path = await make_store_path(store_like, path=path, mode=mode)
2657
assert isinstance(store_path.store, LocalStore)
2758
assert Path(store_path.store.root) == Path(tmpdir)
59+
path_normalized = normalize_path(path)
60+
assert store_path.path == (store_like / path_normalized).path
2861

29-
# Store
30-
store_path = await make_store_path(store_path.store)
31-
assert isinstance(store_path.store, LocalStore)
32-
assert Path(store_path.store.root) == Path(tmpdir)
62+
assert store_path.store.mode.str == mode
3363

34-
# StorePath
35-
store_path = await make_store_path(store_path)
36-
assert isinstance(store_path.store, LocalStore)
37-
assert Path(store_path.store.root) == Path(tmpdir)
3864

65+
async def test_make_store_path_invalid() -> None:
66+
"""
67+
Test that invalid types raise TypeError
68+
"""
3969
with pytest.raises(TypeError):
4070
await make_store_path(1) # type: ignore[arg-type]
4171

0 commit comments

Comments
 (0)