Skip to content

Commit f01c4d1

Browse files
authored
Relative self hrefs break link resolution (#574)
1 parent 9df3245 commit f01c4d1

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
### Changed
1212

13+
- HREFs in `Link` objects with `rel == "self"` are converted to absolute HREFs ([#574](https://github.com/stac-utils/pystac/pull/574))
14+
1315
### Deprecated
1416

1517
### Fixed

pystac/link.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class Link:
6868
:class:`~pystac.resolved_object_cache.ResolvedObjectCache` to resolve objects, and
6969
will create absolute HREFs from relative HREFs against the owner's self HREF."""
7070

71+
_target_href: Optional[str]
72+
_target_object: Optional["STACObject_Type"]
73+
7174
def __init__(
7275
self,
7376
rel: Union[str, pystac.RelType],
@@ -78,7 +81,10 @@ def __init__(
7881
) -> None:
7982
self.rel = rel
8083
if isinstance(target, str):
81-
self._target_href: Optional[str] = target
84+
if rel == pystac.RelType.SELF:
85+
self._target_href = make_absolute_href(target)
86+
else:
87+
self._target_href = target
8288
self._target_object = None
8389
else:
8490
self._target_href = None

tests/data-files/file/item.json

-4
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@
8282
}
8383
},
8484
"links": [
85-
{
86-
"rel": "self",
87-
"href": "./item.json"
88-
},
8985
{
9086
"rel": "parent",
9187
"href": "./collection.json",

tests/test_link.py

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import datetime
2-
import os.path
2+
import os
33
import unittest
44
from tempfile import TemporaryDirectory
55
from typing import Any, Dict, List
@@ -113,6 +113,23 @@ def test_get_target_str_no_href(self) -> None:
113113
self.item.add_link(link)
114114
self.assertIsNone(link.get_target_str())
115115

116+
def test_relative_self_href(self) -> None:
117+
with TemporaryDirectory() as temporary_directory:
118+
pystac.write_file(
119+
self.item,
120+
include_self_link=False,
121+
dest_href=os.path.join(temporary_directory, "item.json"),
122+
)
123+
previous = os.getcwd()
124+
try:
125+
os.chdir(temporary_directory)
126+
item = pystac.read_file("item.json")
127+
href = item.get_self_href()
128+
assert href
129+
self.assertTrue(os.path.isabs(href), f"Not an absolute path: {href}")
130+
finally:
131+
os.chdir(previous)
132+
116133

117134
class StaticLinkTest(unittest.TestCase):
118135
def setUp(self) -> None:
@@ -134,12 +151,13 @@ def test_from_dict_round_trip(self) -> None:
134151
{"rel": "r", "href": "t"},
135152
{"rel": "r", "href": "/t"},
136153
{"rel": "r", "href": "t", "type": "a/b", "title": "t", "c": "d", "1": 2},
137-
# Special case.
138-
{"rel": "self", "href": "t"},
139154
]
140155
for d in test_cases:
141156
d2 = pystac.Link.from_dict(d).to_dict()
142157
self.assertEqual(d, d2)
158+
d = {"rel": "self", "href": "t"}
159+
d2 = {"rel": "self", "href": os.path.join(os.getcwd(), "t")}
160+
self.assertEqual(pystac.Link.from_dict(d).to_dict(), d2)
143161

144162
def test_from_dict_failures(self) -> None:
145163
dicts: List[Dict[str, Any]] = [{}, {"href": "t"}, {"rel": "r"}]

0 commit comments

Comments
 (0)