1
1
from copy import copy
2
- from typing import Any , Dict , Optional , TYPE_CHECKING , Union , cast
2
+ from typing import Any , Dict , Optional , TYPE_CHECKING , Union
3
3
4
4
import pystac
5
5
from pystac .utils import make_absolute_href , make_relative_href , is_absolute_href
@@ -52,11 +52,6 @@ class Link:
52
52
"""The relation of the link (e.g. 'child', 'item'). Registered rel Types are
53
53
preferred. See :class:`~pystac.RelType` for common media types."""
54
54
55
- target : Union [str , "STACObject_Type" ]
56
- """The target of the link. If the link is unresolved, or the link is to something
57
- that is not a STACObject, the target is an HREF. If resolved, the target is a
58
- STACObject."""
59
-
60
55
media_type : Optional [str ]
61
56
"""Optional description of the media type. Registered Media Types are preferred.
62
57
See :class:`~pystac.MediaType` for common media types."""
@@ -82,7 +77,12 @@ def __init__(
82
77
extra_fields : Optional [Dict [str , Any ]] = None ,
83
78
) -> None :
84
79
self .rel = rel
85
- self .target = target
80
+ if isinstance (target , str ):
81
+ self ._target_href : Optional [str ] = target
82
+ self ._target_object = None
83
+ else :
84
+ self ._target_href = None
85
+ self ._target_object = target
86
86
self .media_type = media_type
87
87
self .title = title
88
88
self .extra_fields = extra_fields or {}
@@ -119,10 +119,10 @@ def get_href(self) -> Optional[str]:
119
119
In all other cases, this method will return an absolute HREF.
120
120
"""
121
121
# get the self href
122
- if self .is_resolved () :
123
- href = cast ( pystac . STACObject , self .target ) .get_self_href ()
122
+ if self ._target_object :
123
+ href = self ._target_object .get_self_href ()
124
124
else :
125
- href = cast ( Optional [ str ], self .target )
125
+ href = self ._target_href
126
126
127
127
if href and is_absolute_href (href ) and self .owner and self .owner .get_root ():
128
128
root = self .owner .get_root ()
@@ -158,16 +158,42 @@ def get_absolute_href(self) -> Optional[str]:
158
158
from this link; however, if the link is relative, has no owner,
159
159
and has an unresolved target, this will return a relative HREF.
160
160
"""
161
- if self .is_resolved () :
162
- href = cast ( pystac . STACObject , self .target ) .get_self_href ()
161
+ if self ._target_object :
162
+ href = self ._target_object .get_self_href ()
163
163
else :
164
- href = cast ( Optional [ str ], self .target )
164
+ href = self ._target_href
165
165
166
166
if href is not None and self .owner is not None :
167
167
href = make_absolute_href (href , self .owner .get_self_href ())
168
168
169
169
return href
170
170
171
+ @property
172
+ def target (self ) -> Union [str , "STACObject_Type" ]:
173
+ """The target of the link. If the link is unresolved, or the link is to something
174
+ that is not a STACObject, the target is an HREF. If resolved, the target is a
175
+ STACObject."""
176
+ if self ._target_object :
177
+ return self ._target_object
178
+ elif self ._target_href :
179
+ return self ._target_href
180
+ else :
181
+ raise ValueError ("No target defined for link." )
182
+
183
+ @target .setter
184
+ def target (self , target : Union [str , "STACObject_Type" ]) -> None :
185
+ """Sets this link's target to a string or a STAC object."""
186
+ if isinstance (target , str ):
187
+ self ._target_href = target
188
+ self ._target_object = None
189
+ else :
190
+ self ._target_href = None
191
+ self ._target_object = target
192
+
193
+ def get_target_str (self ) -> Optional [str ]:
194
+ """Returns this link's target as a string."""
195
+ return self ._target_href
196
+
171
197
def __repr__ (self ) -> str :
172
198
return "<Link rel={} target={}>" .format (self .rel , self .target )
173
199
@@ -180,8 +206,10 @@ def resolve_stac_object(self, root: Optional["Catalog_Type"] = None) -> "Link":
180
206
If provided, the root's resolved object cache is used to search for
181
207
previously resolved instances of the STAC object.
182
208
"""
183
- if isinstance (self .target , str ):
184
- target_href = self .target
209
+ if self ._target_object :
210
+ pass
211
+ elif self ._target_href :
212
+ target_href = self ._target_href
185
213
186
214
# If it's a relative link, base it off the parent.
187
215
if not is_absolute_href (target_href ):
@@ -221,17 +249,17 @@ def resolve_stac_object(self, root: Optional["Catalog_Type"] = None) -> "Link":
221
249
if root is not None :
222
250
obj = root ._resolved_objects .get_or_cache (obj )
223
251
obj .set_root (root )
252
+ self ._target_object = obj
224
253
else :
225
- obj = self .target
226
-
227
- self .target = obj
254
+ raise ValueError ("Cannot resolve STAC object without a target" )
228
255
229
256
if (
230
257
self .owner
231
258
and self .rel in [pystac .RelType .CHILD , pystac .RelType .ITEM ]
232
259
and isinstance (self .owner , pystac .Catalog )
233
260
):
234
- self .target .set_parent (self .owner )
261
+ assert self ._target_object
262
+ self ._target_object .set_parent (self .owner )
235
263
236
264
return self
237
265
@@ -241,7 +269,7 @@ def is_resolved(self) -> bool:
241
269
Returns:
242
270
bool: True if this link is resolved.
243
271
"""
244
- return not isinstance ( self .target , str )
272
+ return self ._target_object is not None
245
273
246
274
def to_dict (self ) -> Dict [str , Any ]:
247
275
"""Generate a dictionary representing the JSON of this serialized Link.
0 commit comments