Skip to content

Commit 30f08c9

Browse files
authored
Truncate filenames to avoid ones that are too long (#129)
* Truncate data filenames to avoid OSError * Add test and revert to Path / operator
1 parent 518f651 commit 30f08c9

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

servicex/cache.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
_ignore_cache = False
99

10+
# Make sure that generated download path names are below this to avoid os errors
11+
MAX_PATH_LEN = 235
12+
1013

1114
@contextmanager
1215
def ignore_cache():
@@ -175,6 +178,11 @@ def data_file_location(self, request_id: str, data_name: str) -> Path:
175178
'''
176179
Return the path to the file that should be written out for this
177180
data_name. This is where the output file should get stored.
181+
Truncate the leftmost characters from filenames to avoid throwing a
182+
OSError: [Errno 63] File name too long error Assume that the most unique part of
183+
the name is the right hand side
178184
'''
179-
(self._path / 'data' / request_id).mkdir(parents=True, exist_ok=True)
180-
return self._path / 'data' / request_id / sanitize_filename(data_name)
185+
parent = self._path / 'data' / request_id
186+
parent.mkdir(parents=True, exist_ok=True)
187+
sanitized = sanitize_filename(data_name)
188+
return parent / sanitized[-1 * (MAX_PATH_LEN - len(parent.name)):]

tests/test_cache.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import string
2+
import random
13
from servicex.utils import ServiceXException
24
import pytest
35

@@ -148,6 +150,18 @@ def test_data_file_location(tmp_path):
148150
assert str(p).startswith(str(tmp_path))
149151

150152

153+
def test_data_file_location_long_path(tmp_path):
154+
c = Cache(tmp_path)
155+
letters = string.ascii_lowercase
156+
file_significant_name = 'junk.root'
157+
long_file_name = ''.join(random.choice(letters) for i in range(230))
158+
159+
p = c.data_file_location('123-456', long_file_name+file_significant_name)
160+
161+
assert(len(p.name) == 235 - len(p.parent.name))
162+
assert p.name.endswith(file_significant_name)
163+
164+
151165
def test_data_file_location_twice(tmp_path):
152166
c = Cache(tmp_path)
153167
_ = c.data_file_location('123-456', 'junk1.root')

0 commit comments

Comments
 (0)