Skip to content

Commit 97f87cb

Browse files
Issue 1470 paths windows (#1475)
* test ko * isolate assertion (very simple check here..) * test windows correctly * cleanup comment * ruff fix * update changelog * update changelog * fix for 3.12 * really cover in new test * drive supported only on 3.13 * check one * check two * correct is_windows in tests * correct is_windows in tests part 2 * use os path for path count * use os path for path count in display as well * use os path for path count in display as well * rm whitespace * rm unecc comment * Update tests/test_catalog.py * factor out function * typo * factor out --------- Co-authored-by: Pete Gadomski <[email protected]>
1 parent 360081f commit 97f87cb

File tree

8 files changed

+47
-11
lines changed

8 files changed

+47
-11
lines changed

.github/workflows/continuous-integration.yml

-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ jobs:
3232
- ubuntu-latest
3333
- windows-latest
3434
- macos-latest
35-
exclude:
36-
# https://github.com/stac-utils/pystac/issues/1470
37-
- os: windows-latest
38-
python-version: "3.13"
3935
steps:
4036
- uses: actions/checkout@v4
4137
- uses: actions/setup-python@v5

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ stdout*
88
/integration*
99
.idea
1010
.vscode
11+
.actrc
1112

1213

1314
# Sphinx documentation

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- Write STAC v1.1.0 ([#1427](https://github.com/stac-utils/pystac/pull/1427))
88
- Use [uv](https://github.com/astral-sh/uv) for development dependencies and docs ([#1439](https://github.com/stac-utils/pystac/pull/1439))
9+
- Correctly detect absolute file path ref on windows, reflecting change in python 3.13 ([#1475]https://github.com/stac-utils/pystac/pull/1475) (only effects python 3.13)
910

1011
## [v1.11.0] - 2024-09-26
1112

tests/test_catalog.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -832,12 +832,16 @@ def test_generate_subcatalogs_works_for_subcatalogs_with_same_ids(self) -> None:
832832
assert len(result) == 6
833833

834834
catalog.normalize_hrefs("/")
835+
835836
for item in catalog.get_items(recursive=True):
836837
item_parent = item.get_parent()
837838
assert item_parent is not None
838839
parent_href = item_parent.self_href
839840
path_to_parent, _ = os.path.split(parent_href)
840-
subcats = [el for el in path_to_parent.split("/") if el]
841+
subcats = list(
842+
Path(path_to_parent).parts[1:]
843+
) # Skip drive letter if present (Windows)
844+
841845
assert len(subcats) == 2, f" for item '{item.id}'"
842846

843847
def test_map_items(self) -> None:

tests/test_layout.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@
1515
LayoutTemplate,
1616
TemplateLayoutStrategy,
1717
)
18-
from tests.utils import ARBITRARY_BBOX, ARBITRARY_GEOM, TestCases
18+
from tests.utils import (
19+
ARBITRARY_BBOX,
20+
ARBITRARY_GEOM,
21+
TestCases,
22+
path_includes_drive_letter,
23+
)
1924

2025

2126
class LayoutTemplateTest(unittest.TestCase):
@@ -412,6 +417,9 @@ def test_produces_layout_for_item(self) -> None:
412417
class AsIsLayoutStrategyTest(unittest.TestCase):
413418
def setUp(self) -> None:
414419
self.strategy = AsIsLayoutStrategy()
420+
self.expected_local_href = (
421+
"/an/href" if not path_includes_drive_letter() else "D:/an/href"
422+
)
415423

416424
def test_catalog(self) -> None:
417425
cat = pystac.Catalog(id="test", description="test desc")
@@ -421,7 +429,7 @@ def test_catalog(self) -> None:
421429
href = self.strategy.get_href(
422430
cat, parent_dir="https://example.com", is_root=True
423431
)
424-
self.assertEqual(href, "/an/href")
432+
self.assertEqual(href, self.expected_local_href)
425433

426434
def test_collection(self) -> None:
427435
collection = TestCases.case_8()
@@ -434,7 +442,7 @@ def test_collection(self) -> None:
434442
href = self.strategy.get_href(
435443
collection, parent_dir="https://example.com", is_root=True
436444
)
437-
self.assertEqual(href, "/an/href")
445+
self.assertEqual(href, self.expected_local_href)
438446

439447
def test_item(self) -> None:
440448
collection = TestCases.case_8()
@@ -444,7 +452,7 @@ def test_item(self) -> None:
444452
self.strategy.get_href(item, parent_dir="http://example.com")
445453
item.set_self_href("/an/href")
446454
href = self.strategy.get_href(item, parent_dir="http://example.com")
447-
self.assertEqual(href, "/an/href")
455+
self.assertEqual(href, self.expected_local_href)
448456

449457

450458
class APILayoutStrategyTest(unittest.TestCase):

tests/test_utils.py

+18-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
safe_urlparse,
2222
str_to_datetime,
2323
)
24-
from tests.utils import TestCases
24+
from tests.utils import TestCases, path_includes_drive_letter
2525

2626

2727
class UtilsTest(unittest.TestCase):
@@ -219,17 +219,33 @@ def test_is_absolute_href(self) -> None:
219219
("item.json", False),
220220
("./item.json", False),
221221
("../item.json", False),
222-
("/item.json", True),
223222
("http://stacspec.org/item.json", True),
224223
]
225224

226225
for href, expected in test_cases:
227226
actual = is_absolute_href(href)
228227
self.assertEqual(actual, expected)
229228

229+
def test_is_absolute_href_os_aware(self) -> None:
230+
# Test cases of (href, expected)
231+
232+
is_windows = os.name == "nt"
233+
incl_drive_letter = path_includes_drive_letter()
234+
test_cases = [
235+
("/item.json", not incl_drive_letter),
236+
("/home/someuser/Downloads/item.json", not incl_drive_letter),
237+
("d:/item.json", is_windows),
238+
("c:/files/more_files/item.json", is_windows),
239+
]
240+
241+
for href, expected in test_cases:
242+
actual = is_absolute_href(href)
243+
self.assertEqual(actual, expected)
244+
230245
@pytest.mark.skipif(os.name != "nt", reason="Windows only test")
231246
def test_is_absolute_href_windows(self) -> None:
232247
# Test cases of (href, expected)
248+
233249
test_cases = [
234250
("item.json", False),
235251
(".\\item.json", False),

tests/utils/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"ARBITRARY_BBOX",
55
"ARBITRARY_EXTENT",
66
"MockStacIO",
7+
"path_includes_drive_letter",
78
]
89
from copy import deepcopy
910
from datetime import datetime
@@ -12,6 +13,7 @@
1213
from dateutil.parser import parse
1314

1415
import pystac
16+
from tests.utils.os_utils import path_includes_drive_letter
1517
from tests.utils.stac_io_mock import MockStacIO
1618
from tests.utils.test_cases import (
1719
ARBITRARY_BBOX,

tests/utils/os_utils.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import os
2+
import sys
3+
4+
5+
def path_includes_drive_letter() -> bool:
6+
return (
7+
sys.version_info.major >= 3 and sys.version_info.minor >= 13 and os.name == "nt"
8+
)

0 commit comments

Comments
 (0)