Skip to content

Commit c80e307

Browse files
committed
Merge branch 'main' into item-assets
2 parents dd88fe5 + 97f87cb commit c80e307

File tree

8 files changed

+53
-17
lines changed

8 files changed

+53
-17
lines changed

.github/workflows/continuous-integration.yml

+6-10
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,12 @@ 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
4238
with:
4339
python-version: ${{ matrix.python-version }}
44-
- uses: astral-sh/setup-uv@v3
40+
- uses: astral-sh/setup-uv@v4
4541
with:
4642
enable-cache: true
4743
- name: Sync
@@ -64,7 +60,7 @@ jobs:
6460
- uses: actions/setup-python@v5
6561
with:
6662
python-version: "3.10"
67-
- uses: astral-sh/setup-uv@v3
63+
- uses: astral-sh/setup-uv@v4
6864
with:
6965
enable-cache: true
7066
- name: Install with dependencies
@@ -105,7 +101,7 @@ jobs:
105101
- uses: actions/setup-python@v5
106102
with:
107103
python-version: ${{ matrix.python-version }}
108-
- uses: astral-sh/setup-uv@v3
104+
- uses: astral-sh/setup-uv@v4
109105
with:
110106
enable-cache: true
111107
- name: Sync
@@ -120,7 +116,7 @@ jobs:
120116
- uses: actions/setup-python@v5
121117
with:
122118
python-version: "3.10"
123-
- uses: astral-sh/setup-uv@v3
119+
- uses: astral-sh/setup-uv@v4
124120
with:
125121
enable-cache: true
126122
- name: Sync
@@ -140,7 +136,7 @@ jobs:
140136
- uses: actions/setup-python@v5
141137
with:
142138
python-version: "3.10"
143-
- uses: astral-sh/setup-uv@v3
139+
- uses: astral-sh/setup-uv@v4
144140
with:
145141
enable-cache: true
146142
- name: Sync
@@ -157,7 +153,7 @@ jobs:
157153
- uses: actions/setup-python@v5
158154
with:
159155
python-version: "3.10"
160-
- uses: astral-sh/setup-uv@v3
156+
- uses: astral-sh/setup-uv@v4
161157
with:
162158
enable-cache: true
163159
- name: Install pandoc

.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)