Skip to content

Commit cf6b016

Browse files
authored
Use Path.resolve() consistently to prevent UNC/drive letter ambiguity (#304)
* Use Path.resolve() consistently to prevent UNC/drive letter ambiguity * Ignore VSCode files * Black linting * Try causing a relative path error by using a drive alias * More consistently call resolve on returned paths and fix tests to compare resolved paths
1 parent 5bd010f commit cf6b016

File tree

6 files changed

+113
-89
lines changed

6 files changed

+113
-89
lines changed

.github/workflows/windows-conda.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ jobs:
3232
3333
- shell: bash -l {0}
3434
run: |
35+
# make a drive letter alias so we can test canonical path resolution
36+
subst Z: .
37+
cd /z
3538
conda activate mescore
3639
mamba install pytest
3740
caimanmanager install

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,6 @@ dmypy.json
138138
tests/tmp
139139
tests/videos
140140
tests/ground_truths*
141+
142+
# VSCode
143+
.vscode/

mesmerize_core/algorithms/cnmf.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def run_algo(batch_path, uuid, data_path: str = None):
3333
input_movie_path = str(df.paths.resolve(input_movie_path))
3434

3535
# make output dir
36-
output_dir = Path(batch_path).parent.joinpath(str(uuid))
36+
output_dir = Path(batch_path).parent.joinpath(str(uuid)).resolve()
3737
output_dir.mkdir(parents=True, exist_ok=True)
3838

3939
params = item["params"]
@@ -96,14 +96,14 @@ def run_algo(batch_path, uuid, data_path: str = None):
9696
print("performing eval")
9797
cnm.estimates.evaluate_components(images, cnm.params, dview=dview)
9898

99-
output_path = output_dir.joinpath(f"{uuid}.hdf5").resolve()
99+
output_path = output_dir.joinpath(f"{uuid}.hdf5")
100100

101101
cnm.save(str(output_path))
102102

103103
Cn = cm.local_correlations(images, swap_dim=False)
104104
Cn[np.isnan(Cn)] = 0
105105

106-
corr_img_path = output_dir.joinpath(f"{uuid}_cn.npy").resolve()
106+
corr_img_path = output_dir.joinpath(f"{uuid}_cn.npy")
107107
np.save(str(corr_img_path), Cn, allow_pickle=False)
108108

109109
# output dict for dataframe row (pd.Series)

mesmerize_core/algorithms/cnmfe.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def run_algo(batch_path, uuid, data_path: str = None):
2929
# resolve full path
3030
input_movie_path = str(df.paths.resolve(input_movie_path))
3131

32-
output_dir = Path(batch_path).parent.joinpath(str(uuid))
32+
output_dir = Path(batch_path).parent.joinpath(str(uuid)).resolve()
3333
output_dir.mkdir(parents=True, exist_ok=True)
3434

3535
params = item["params"]
@@ -87,7 +87,7 @@ def run_algo(batch_path, uuid, data_path: str = None):
8787
print("evaluating components")
8888
cnm.estimates.evaluate_components(images, cnm.params, dview=dview)
8989

90-
cnmf_hdf5_path = output_dir.joinpath(f"{uuid}.hdf5").resolve()
90+
cnmf_hdf5_path = output_dir.joinpath(f"{uuid}.hdf5")
9191
cnm.save(str(cnmf_hdf5_path))
9292

9393
# save output paths to outputs dict

mesmerize_core/batch_utils.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def set_parent_raw_data_path(path: Union[Path, str]) -> Path:
4949
raise NotADirectoryError(
5050
"The directory passed to `set_parent_raw_data_path()` does not exist.\n"
5151
)
52-
PARENT_DATA_PATH = path
52+
PARENT_DATA_PATH = path.resolve()
5353

5454
return PARENT_DATA_PATH
5555

@@ -65,15 +65,15 @@ def get_parent_raw_data_path() -> Path:
6565
6666
"""
6767
global PARENT_DATA_PATH
68-
return PARENT_DATA_PATH
68+
return PARENT_DATA_PATH.resolve()
6969

7070

7171
class _BasePathExtensions:
7272
def __init__(self, data: Union[pd.DataFrame, pd.Series]):
7373
self._data = data
7474

7575
def set_batch_path(self, path: Union[str, Path]):
76-
self._data.attrs["batch_path"] = Path(path)
76+
self._data.attrs["batch_path"] = Path(path).resolve()
7777

7878
def get_batch_path(self) -> Path:
7979
"""
@@ -84,9 +84,11 @@ def get_batch_path(self) -> Path:
8484
Path
8585
full path to the batch dataframe file as a Path object
8686
"""
87-
if "batch_path" in self._data.attrs.keys():
88-
if self._data.attrs["batch_path"] is not None:
89-
return self._data.attrs["batch_path"]
87+
if (
88+
"batch_path" in self._data.attrs.keys()
89+
and self._data.attrs["batch_path"] is not None
90+
):
91+
return Path(self._data.attrs["batch_path"]).resolve()
9092
else:
9193
raise ValueError("Batch path is not set")
9294

@@ -133,24 +135,23 @@ def split(self, path: Union[str, Path]):
133135
(<batch_dir> or <raw_data_dir>, <relative_path>)
134136
135137
"""
136-
path = Path(path)
138+
path = Path(path).resolve()
137139
# check if input movie is within batch dir
138-
if self.get_batch_path().parent in path.parents:
139-
return self.get_batch_path().parent, path.relative_to(
140-
self.get_batch_path().parent
141-
)
140+
batch_parent = self.get_batch_path().parent
141+
if batch_parent in path.parents:
142+
return batch_parent, path.relative_to(batch_parent)
142143

143144
# else check if in parent raw data dir
144-
elif get_parent_raw_data_path() is not None:
145-
if get_parent_raw_data_path() in path.parents:
146-
return get_parent_raw_data_path(), path.relative_to(
147-
get_parent_raw_data_path()
148-
)
145+
else:
146+
raw_data_path = get_parent_raw_data_path()
147+
if raw_data_path is not None:
148+
if raw_data_path in path.parents:
149+
return raw_data_path, path.relative_to(raw_data_path)
149150

150151
raise NotADirectoryError(
151152
f"Could not split `path`:\n{path}"
152-
f"\nnot relative to either batch path:\n{self.get_batch_path()}"
153-
f"\nor parent raw data path:\n{get_parent_raw_data_path()}"
153+
f"\nnot relative to either batch path:\n{batch_parent}"
154+
f"\nor parent raw data path:\n{raw_data_path if raw_data_path is not None else '(not set)'}"
154155
)
155156

156157

@@ -258,6 +259,6 @@ def create_batch(path: Union[str, Path], remove_existing: bool = False) -> pd.Da
258259
def get_full_raw_data_path(path: Union[Path, str]) -> Path:
259260
path = Path(path)
260261
if PARENT_DATA_PATH is not None:
261-
return PARENT_DATA_PATH.joinpath(path)
262+
path = PARENT_DATA_PATH.joinpath(path)
262263

263-
return path
264+
return path.resolve() # needed in case path is absolute but not canonical

0 commit comments

Comments
 (0)