Skip to content

Commit 8089276

Browse files
committed
url escape on win
1 parent 8daee30 commit 8089276

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

cloudpathlib/s3/s3path.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import re
3+
import sys
34
from pathlib import Path
45
from tempfile import TemporaryDirectory
56
from typing import Any, Optional, TYPE_CHECKING
@@ -106,3 +107,11 @@ def key(self) -> str:
106107
@property
107108
def etag(self):
108109
return self.client._get_metadata(self).get("etag")
110+
111+
@property
112+
def _local(self) -> Path:
113+
no_prefix = self._no_prefix
114+
# `:` is invalid in Windows paths; percent-encode it for MRAP ARNs
115+
if sys.platform == "win32":
116+
no_prefix = no_prefix.replace(":", "%3A")
117+
return self.client._local_cache_dir / no_prefix

tests/test_s3_specific.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,3 +394,14 @@ def test_mrap_file_operations(s3_rig):
394394
assert new_file.bucket == _MRAP_ARN
395395
new_file.unlink()
396396
assert not new_file.exists()
397+
398+
399+
def test_mrap_local_path_windows_encoding(monkeypatch, s3_rig):
400+
"""On Windows, colons in MRAP ARNs must be percent-encoded in the local cache path."""
401+
import cloudpathlib.s3.s3path as s3path_module
402+
403+
monkeypatch.setattr(s3path_module.sys, "platform", "win32")
404+
client = s3_rig.client_class()
405+
p = client.CloudPath(f"s3://{_MRAP_ARN}/some/key.txt")
406+
assert ":" not in str(p._local), f"Colon found in local path on simulated Windows: {p._local}"
407+
assert "%3A" in str(p._local)

0 commit comments

Comments
 (0)