Skip to content

Commit ec4d446

Browse files
authored
No slashes in layer name (#924)
* Change conversion layer mapping to not allow slashes in layernames anymore. * Update Changelog. * Add uncomplete test for slash in layername. * Add test that checks if a slash is in layername.
1 parent 609ada6 commit ec4d446

File tree

6 files changed

+38
-14
lines changed

6 files changed

+38
-14
lines changed

webknossos/Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ For upgrade instructions, please check the respective _Breaking Changes_ section
1717
### Added
1818

1919
### Changed
20+
- The conversion folder structures to layer names does not allow slashes in the layer name anymore. [#918](https://github.com/scalableminds/webknossos-libs/issues/918)
2021

2122
### Fixed
2223
- Fixed a bug where compression in add_layer_from_images uses too much memory [#900](https://github.com/scalableminds/webknossos-libs/issues/900)

webknossos/tests/constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
from webknossos.utils import rmtree
1313

14-
TESTDATA_DIR = Path("testdata")
15-
TESTOUTPUT_DIR = Path("testoutput")
14+
TESTDATA_DIR = Path(__file__).parent.parent / "testdata"
15+
TESTOUTPUT_DIR = Path(__file__).parent.parent / "testoutput"
1616

1717

1818
MINIO_ROOT_USER = "TtnuieannGt2rGuie2t8Tt7urarg5nauedRndrur"

webknossos/tests/dataset/test_from_images.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import warnings
22
from pathlib import Path
3+
from shutil import copytree
34
from typing import Iterator
45

56
import numpy as np
67
import pytest
78
from tifffile import TiffFile
89

910
import webknossos as wk
11+
from tests.constants import TESTDATA_DIR
12+
from webknossos.dataset import Dataset
1013

1114

1215
@pytest.fixture(autouse=True, scope="function")
@@ -18,7 +21,7 @@ def ignore_warnings() -> Iterator:
1821

1922
def test_compare_tifffile(tmp_path: Path) -> None:
2023
ds = wk.Dataset.from_images(
21-
"testdata/tiff",
24+
TESTDATA_DIR / "tiff",
2225
tmp_path,
2326
(1, 1, 1),
2427
compress=True,
@@ -30,14 +33,14 @@ def test_compare_tifffile(tmp_path: Path) -> None:
3033
assert "tiff" in ds.layers
3134
data = ds.layers["tiff"].get_finest_mag().read()[0, :, :]
3235
for z_index in range(0, data.shape[-1]):
33-
with TiffFile("testdata/tiff/test.0000.tiff") as tif_file:
36+
with TiffFile(TESTDATA_DIR / "tiff" / "test.0000.tiff") as tif_file:
3437
comparison_slice = tif_file.asarray().T
3538
assert np.array_equal(data[:, :, z_index], comparison_slice)
3639

3740

3841
def test_multiple_multitiffs(tmp_path: Path) -> None:
3942
ds = wk.Dataset.from_images(
40-
"testdata/various_tiff_formats",
43+
TESTDATA_DIR / "various_tiff_formats",
4144
tmp_path,
4245
(1, 1, 1),
4346
)
@@ -55,3 +58,22 @@ def test_multiple_multitiffs(tmp_path: Path) -> None:
5558
assert layer.dtype_per_channel == np.dtype(dtype)
5659
assert layer.num_channels == channels
5760
assert layer.bounding_box.size == size
61+
62+
63+
def test_no_slashes_in_layername(tmp_path: Path) -> None:
64+
(input_path := tmp_path / "tiff" / "subfolder" / "tifffiles").mkdir(parents=True)
65+
copytree(
66+
TESTDATA_DIR / "tiff_with_different_dimensions",
67+
input_path,
68+
dirs_exist_ok=True,
69+
)
70+
71+
for strategy in Dataset.ConversionLayerMapping:
72+
dataset = wk.Dataset.from_images(
73+
tmp_path / "tiff",
74+
tmp_path / str(strategy),
75+
voxel_size=(10, 10, 10),
76+
map_filepath_to_layer_name=strategy,
77+
)
78+
79+
assert all("/" not in layername for layername in dataset.layers)

webknossos/tests/test_cli.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
MINIO_ROOT_PASSWORD,
2121
MINIO_ROOT_USER,
2222
REMOTE_TESTOUTPUT_DIR,
23+
TESTDATA_DIR,
2324
use_minio,
2425
)
2526
from webknossos import BoundingBox, DataFormat, Dataset
@@ -43,9 +44,6 @@ def tmp_cwd() -> Iterator[None]:
4344
os.chdir(prev_cwd)
4445

4546

46-
TESTDATA_DIR = Path(__file__).parent.parent / "testdata"
47-
48-
4947
@pytest.fixture(autouse=True, scope="module")
5048
def minio_docker() -> Iterator[None]:
5149
with use_minio():

webknossos/webknossos/dataset/dataset.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,14 @@ def _to_callable(
180180
ConversionLayerMapping = Dataset.ConversionLayerMapping
181181

182182
if self == ConversionLayerMapping.ENFORCE_LAYER_PER_FILE:
183-
return str
183+
return lambda p: p.as_posix().replace("/", "_")
184184
elif self == ConversionLayerMapping.ENFORCE_SINGLE_LAYER:
185185
return lambda p: input_path.name
186186
elif self == ConversionLayerMapping.ENFORCE_LAYER_PER_FOLDER:
187187
return (
188-
lambda p: input_path.name if p.parent == Path() else str(p.parent)
188+
lambda p: input_path.name
189+
if p.parent == Path()
190+
else p.parent.as_posix().replace("/", "_")
189191
)
190192
elif self == ConversionLayerMapping.ENFORCE_LAYER_PER_TOPLEVEL_FOLDER:
191193
return lambda p: input_path.name if p.parent == Path() else p.parts[0]
@@ -201,7 +203,7 @@ def _to_callable(
201203
)
202204
else input_path.name
203205
if p.parent == Path()
204-
else str(p.parent)
206+
else p.parent.as_posix().replace("/", "_")
205207
)
206208
elif self == ConversionLayerMapping.INSPECT_SINGLE_FILE:
207209
# As before, but only a single image is inspected to determine 2D vs 3D.
@@ -213,9 +215,7 @@ def _to_callable(
213215
return str
214216
else:
215217
return (
216-
lambda p: input_path.name
217-
if p.parent == Path()
218-
else str(p.parent)
218+
lambda p: input_path.name if p.parent == Path() else p.parts[-2]
219219
)
220220
else:
221221
raise ValueError(f"Got unexpected ConversionLayerMapping value: {self}")

webknossos/webknossos/dataset/layer.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ def name(self, layer_name: str) -> None:
231231
layer_name not in self.dataset.layers.keys()
232232
), f"Failed to rename layer {self.name} to {layer_name}: The new name already exists."
233233
assert is_fs_path(self.path), f"Cannot rename remote layer {self.path}"
234+
assert (
235+
"/" not in layer_name
236+
), f"Cannot rename layer, because there is a '/' character in the layer name: {layer_name}"
234237
self.path.rename(self.dataset.path / layer_name)
235238
del self.dataset.layers[self.name]
236239
self.dataset.layers[layer_name] = self

0 commit comments

Comments
 (0)