Skip to content

Commit 4d3d213

Browse files
authored
Fix the normalization for file names to work for specifying a file, path, or relative path (#53)
1 parent df6b52f commit 4d3d213

File tree

3 files changed

+65
-51
lines changed

3 files changed

+65
-51
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "socketdev"
7-
version = "3.0.13"
7+
version = "3.0.14"
88
requires-python = ">= 3.9"
99
dependencies = [
1010
'requests',

socketdev/utils/__init__.py

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -269,63 +269,77 @@ def load_files_for_sending_lazy(files: List[str], workspace: str = None, max_ope
269269
if "\\" in file_path:
270270
file_path = file_path.replace("\\", "/")
271271

272-
_, name = file_path.rsplit("/", 1)
272+
for file_path in files:
273+
# Normalize file path
274+
if "\\" in file_path:
275+
file_path = file_path.replace("\\", "/")
273276

274-
# Calculate the key name for the form data
275-
key = file_path
276-
path_stripped = False
277-
278-
# If base_paths is provided, try to strip one of the paths from the file path
279-
if base_paths:
280-
for bp in base_paths:
281-
# Normalize base_path to ensure consistent handling of trailing slashes
282-
normalized_base_path = bp.rstrip("/") + "/" if not bp.endswith("/") else bp
277+
# Skip directories
278+
if os.path.isdir(file_path):
279+
continue
280+
281+
# Handle file path splitting safely
282+
if "/" in file_path:
283+
_, name = file_path.rsplit("/", 1)
284+
else:
285+
name = file_path
286+
287+
# Calculate the key name for the form data
288+
key = file_path
289+
path_stripped = False
290+
291+
# If base_paths is provided, try to strip one of the paths from the file path
292+
if base_paths:
293+
for bp in base_paths:
294+
normalized_base_path = bp.rstrip("/") + "/" if not bp.endswith("/") else bp
295+
if key.startswith(normalized_base_path):
296+
key = key[len(normalized_base_path):]
297+
path_stripped = True
298+
break
299+
elif key.startswith(bp.rstrip("/")):
300+
stripped_base = bp.rstrip("/")
301+
if key.startswith(stripped_base + "/") or key == stripped_base:
302+
key = key[len(stripped_base):]
303+
key = key.lstrip("/")
304+
path_stripped = True
305+
break
306+
elif base_path:
307+
normalized_base_path = base_path.rstrip("/") + "/" if not base_path.endswith("/") else base_path
283308
if key.startswith(normalized_base_path):
284309
key = key[len(normalized_base_path):]
285310
path_stripped = True
286-
break
287-
elif key.startswith(bp.rstrip("/")):
288-
# Handle case where base_path matches exactly without trailing slash
289-
stripped_base = bp.rstrip("/")
311+
elif key.startswith(base_path.rstrip("/")):
312+
stripped_base = base_path.rstrip("/")
290313
if key.startswith(stripped_base + "/") or key == stripped_base:
291314
key = key[len(stripped_base):]
292315
key = key.lstrip("/")
293316
path_stripped = True
294-
break
295-
296-
# If base_path is provided and no base_paths matched, use single base_path
297-
elif base_path:
298-
# Normalize base_path to ensure consistent handling of trailing slashes
299-
normalized_base_path = base_path.rstrip("/") + "/" if not base_path.endswith("/") else base_path
300-
if key.startswith(normalized_base_path):
301-
key = key[len(normalized_base_path):]
317+
318+
# If workspace is provided and no base paths matched, fall back to workspace logic
319+
if not path_stripped and workspace and file_path.startswith(workspace):
320+
key = file_path[len(workspace):]
321+
# Remove all leading slashes (for absolute paths)
322+
while key.startswith("/"):
323+
key = key[1:]
302324
path_stripped = True
303-
elif key.startswith(base_path.rstrip("/")):
304-
# Handle case where base_path matches exactly without trailing slash
305-
stripped_base = base_path.rstrip("/")
306-
if key.startswith(stripped_base + "/") or key == stripped_base:
307-
key = key[len(stripped_base):]
308-
key = key.lstrip("/")
309-
path_stripped = True
310-
311-
# If workspace is provided and no base paths matched, fall back to workspace logic
312-
if not path_stripped and workspace and file_path.startswith(workspace):
313-
key = file_path[len(workspace):]
314-
key = key.lstrip("/")
315-
key = key.lstrip("./")
316-
path_stripped = True
317-
318-
# If no path stripping occurred, clean up the key
319-
if not path_stripped:
320-
# No base_path, base_paths, or workspace stripping occurred, clean up leading parts
321-
key = key.lstrip("/")
322-
key = key.lstrip("./")
323325

324-
# Create lazy file loader instead of opening file immediately
325-
# Use the relative path (key) as filename instead of truncated basename
326-
lazy_file = LazyFileLoader(file_path, key)
327-
payload = (key, (key, lazy_file))
328-
send_files.append(payload)
326+
# Clean up relative path prefixes, but preserve filename dots
327+
while key.startswith("./"):
328+
key = key[2:]
329+
while key.startswith("../"):
330+
key = key[3:]
331+
# Remove any remaining leading slashes (for absolute paths)
332+
while key.startswith("/"):
333+
key = key[1:]
334+
335+
# Remove Windows drive letter if present (C:/...)
336+
if len(key) > 2 and key[1] == ':' and (key[2] == '/' or key[2] == '\\'):
337+
key = key[2:]
338+
while key.startswith("/"):
339+
key = key[1:]
329340

330-
log.debug(f"Prepared {len(send_files)} files for lazy loading")
331-
return send_files
341+
# Create lazy file loader instead of opening file immediately
342+
lazy_file = LazyFileLoader(file_path, key)
343+
payload = (key, (key, lazy_file))
344+
send_files.append(payload)
345+
return send_files

socketdev/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.0.13"
1+
__version__ = "3.0.14"

0 commit comments

Comments
 (0)