Skip to content

Commit e4199d5

Browse files
authored
Merge pull request #42 from imcf/pathtools-tab-newline
Pathtools tab newline. Closes #10
2 parents 0ea34d9 + 7611c34 commit e4199d5

2 files changed

Lines changed: 88 additions & 39 deletions

File tree

src/imcflibs/pathtools.py

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
def parse_path(path, prefix=""):
13-
"""Parse a path into its components.
13+
r"""Parse a path into its components.
1414
1515
If the path doesn't end with the pathsep, it is assumed being a file!
1616
No tests based on existing files are done, as this is supposed to also work
@@ -20,6 +20,11 @@ def parse_path(path, prefix=""):
2020
*Script Parameter* `#@ File`) for either of the parameters, so it is safe to
2121
use this in ImageJ Python scripts without additional measures.
2222
23+
**WARNING**: when passing in **Windows paths** literally, make sure to
24+
declare them as **raw strings** using the `r""` notation, otherwise
25+
unexpected things might happen if the path contains sections that Python
26+
will interpret as escape sequences (e.g. `\n`, `\t`, `\u2324`, ...).
27+
2328
Parameters
2429
----------
2530
path : str or str-like
@@ -55,50 +60,61 @@ def parse_path(path, prefix=""):
5560
POSIX-style path to a file with a suffix:
5661
5762
>>> parse_path('/tmp/foo/file.suffix')
58-
{'dname': 'foo',
59-
'ext': '',
60-
'fname': 'file',
61-
'full': '/tmp/foo/file',
62-
'basename': 'file',
63-
'orig': '/tmp/foo/file',
64-
'parent': '/tmp/',
65-
'path': '/tmp/foo/'}
63+
{
64+
"dname": "foo",
65+
"ext": "",
66+
"fname": "file",
67+
"full": "/tmp/foo/file",
68+
"basename": "file",
69+
"orig": "/tmp/foo/file",
70+
"parent": "/tmp/",
71+
"path": "/tmp/foo/",
72+
}
73+
6674
6775
POSIX-style path to a directory:
6876
6977
>>> parse_path('/tmp/foo/')
70-
{'dname': 'foo',
71-
'ext': '',
72-
'fname': '',
73-
'full': '/tmp/foo/',
74-
'basename': '',
75-
'orig': '/tmp/foo/',
76-
'parent': '/tmp/',
77-
'path': '/tmp/foo/'}
78+
{
79+
"dname": "foo",
80+
"ext": "",
81+
"fname": "",
82+
"full": "/tmp/foo/",
83+
"basename": "",
84+
"orig": "/tmp/foo/",
85+
"parent": "/tmp/",
86+
"path": "/tmp/foo/",
87+
}
88+
7889
7990
Windows-style path to a file:
8091
81-
>>> parse_path('C:\\Temp\\foo\\file.ext')
82-
{'dname': 'foo',
83-
'ext': '.ext',
84-
'fname': 'file.ext',
85-
'full': 'C:/Temp/foo/file.ext',
86-
'basename': 'file',
87-
'orig': 'C:\\Temp\\foo\\file.ext',
88-
'parent': 'C:/Temp/',
89-
'path': 'C:/Temp/foo/'}
92+
>>> parse_path(r'C:\Temp\new\file.ext')
93+
{
94+
"dname": "new",
95+
"ext": ".ext",
96+
"fname": "file.ext",
97+
"full": "C:/Temp/new/file.ext",
98+
"basename": "file",
99+
"orig": "C:\\Temp\\new\\file.ext",
100+
"parent": "C:/Temp",
101+
"path": "C:/Temp/new/",
102+
}
103+
90104
91105
Special treatment for *OME-TIFF* suffixes:
92106
93107
>>> parse_path("/path/to/some/nice.OME.tIf")
94-
{'basename': 'nice',
95-
'dname': 'some',
96-
'ext': '.OME.tIf',
97-
'fname': 'nice.OME.tIf',
98-
'full': '/path/to/some/nice.OME.tIf',
99-
'orig': '/path/to/some/nice.OME.tIf',
100-
'parent': '/path/to/',
101-
'path': '/path/to/some/'}
108+
{
109+
"basename": "nice",
110+
"dname": "some",
111+
"ext": ".OME.tIf",
112+
"fname": "nice.OME.tIf",
113+
"full": "/path/to/some/nice.OME.tIf",
114+
"orig": "/path/to/some/nice.OME.tIf",
115+
"parent": "/path/to/",
116+
"path": "/path/to/some/",
117+
}
102118
"""
103119
path = str(path)
104120
if prefix:

tests/test_pathtools.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Tests for `imcflibs.pathtools`."""
22
# -*- coding: utf-8 -*-
33

4-
import pytest
54
from imcflibs.pathtools import parse_path
65
from imcflibs.pathtools import jython_fiji_exists
76
from imcflibs.pathtools import image_basename
@@ -12,6 +11,7 @@
1211

1312

1413
def test_parse_path():
14+
"""Tests using regular POSIX-style paths."""
1515
path = "/tmp/foo/"
1616
path_to_dir = parse_path(path)
1717
path_to_file = parse_path(path + "file.ext")
@@ -35,20 +35,53 @@ def test_parse_path():
3535

3636

3737
def test_parse_path_windows():
38-
path = r"C:\foo\bar"
38+
"""Test using a Windows-style path."""
39+
path = r"C:\Foo\Bar"
3940
parsed = parse_path(path)
4041

4142
assert parsed["orig"] == path
42-
assert parsed["full"] == r"C:/foo/bar"
43-
assert parsed["fname"] == "bar"
44-
assert parsed["dname"] == "foo"
43+
assert parsed["full"] == "C:/Foo/Bar"
44+
assert parsed["fname"] == "Bar"
45+
assert parsed["dname"] == "Foo"
46+
47+
48+
def test_parse_path_windows_newline_tab():
49+
"""Test a Windows path with newline and tab sequences as raw string."""
50+
path = r"C:\Temp\new\file.ext"
51+
parsed = parse_path(path)
52+
53+
assert parsed == {
54+
"dname": "new",
55+
"ext": ".ext",
56+
"fname": "file.ext",
57+
"full": "C:/Temp/new/file.ext",
58+
"basename": "file",
59+
"orig": "C:\\Temp\\new\\file.ext",
60+
"parent": "C:/Temp",
61+
"path": "C:/Temp/new/",
62+
}
63+
64+
65+
def test_parse_path_windows_nonraw():
66+
r"""Test non-raw string containing newline `\n` and tab `\t` sequences.
67+
68+
As `parse_path()` cannot work on non-raw strings containing escape
69+
sequences, the parsed result will not be the expected one.
70+
"""
71+
path = "C:\new_folder\test"
72+
parsed = parse_path(path)
73+
74+
assert parsed["full"] != r"C:\new_folder\test"
75+
assert parsed["fname"] != "test"
4576

4677

4778
def test_jython_fiji_exists(tmpdir):
79+
"""Test the Jython/Fiji `os.path.exists()` workaround."""
4880
assert jython_fiji_exists(str(tmpdir)) == True
4981

5082

5183
def test_image_basename():
84+
"""Test basename extraction for various image file names."""
5285
assert image_basename("/path/to/image_file_01.png") == "image_file_01"
5386
assert image_basename("more-complex-stack.ome.tif") == "more-complex-stack"
5487
assert image_basename("/tmp/FoObAr.OMe.tIf") == "FoObAr"

0 commit comments

Comments
 (0)