Skip to content

Commit

Permalink
Merge branch 'main' into issues/856-datacube
Browse files Browse the repository at this point in the history
  • Loading branch information
gadomski authored Oct 20, 2023
2 parents 9febf44 + b40f3be commit cec0386
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Interactions between **pytest-recording** and the validator schema cache ([#1242](https://github.com/stac-utils/pystac/pull/1242))
- Call `registry` when instantiating `Draft7Validator` ([#1240](https://github.com/stac-utils/pystac/pull/1240))
- Migration for the classification, datacube, table, and timestamps extensions ([#1258](https://github.com/stac-utils/pystac/pull/1258))
- Handling of `bboxes` and `intervals` arguments to `SpatialExtent` and `TemporalExtent`, respectively ([#1268](https://github.com/stac-utils/pystac/pull/1268))

### Removed

Expand Down
24 changes: 15 additions & 9 deletions pystac/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@

C = TypeVar("C", bound="Collection")

Bboxes = list[list[Union[float, int]]]
TemporalIntervals = Union[list[list[datetime]], list[list[Optional[datetime]]]]
TemporalIntervalsLike = Union[
TemporalIntervals, list[datetime], list[Optional[datetime]]
Expand All @@ -59,7 +60,7 @@ class SpatialExtent:
Spatial Extent object.
"""

bboxes: list[list[float]]
bboxes: Bboxes
"""A list of bboxes that represent the spatial
extent of the collection. Each bbox can be 2D or 3D. The length of the bbox
array must be 2*n where n is the number of dimensions. For example, a
Expand All @@ -71,15 +72,18 @@ class SpatialExtent:

def __init__(
self,
bboxes: list[list[float]] | list[float],
bboxes: Bboxes | list[float | int],
extra_fields: dict[str, Any] | None = None,
) -> None:
if not isinstance(bboxes, list):
raise TypeError("bboxes must be a list")

# A common mistake is to pass in a single bbox instead of a list of bboxes.
# Account for this by transforming the input in that case.
if isinstance(bboxes, list) and isinstance(bboxes[0], float):
self.bboxes: list[list[float]] = [cast(list[float], bboxes)]
if isinstance(bboxes[0], (float, int)):
self.bboxes = [cast(list[Union[float, int]], bboxes)]
else:
self.bboxes = cast(list[list[float]], bboxes)
self.bboxes = cast(Bboxes, bboxes)

self.extra_fields = extra_fields or {}

Expand Down Expand Up @@ -196,16 +200,18 @@ class TemporalExtent:

def __init__(
self,
intervals: TemporalIntervals,
intervals: TemporalIntervals | list[datetime | None],
extra_fields: dict[str, Any] | None = None,
):
if not isinstance(intervals, list):
raise TypeError("intervals must be a list")
# A common mistake is to pass in a single interval instead of a
# list of intervals. Account for this by transforming the input
# in that case.
if isinstance(intervals, list) and isinstance(intervals[0], datetime):
self.intervals = intervals
if isinstance(intervals[0], datetime) or intervals[0] is None:
self.intervals = [cast(list[Optional[datetime]], intervals)]
else:
self.intervals = intervals
self.intervals = cast(TemporalIntervals, intervals)

self.extra_fields = extra_fields or {}

Expand Down
5 changes: 2 additions & 3 deletions pystac/extensions/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ def validate_owner_has_extension(
``None``.
"""
warnings.warn(
"ensure_owner_has_extension is deprecated and will be removed in v1.9. "
"ensure_owner_has_extension is deprecated. "
"Use ensure_owner_has_extension instead",
DeprecationWarning,
)
Expand Down Expand Up @@ -234,8 +234,7 @@ def validate_has_extension(cls, obj: S, add_if_missing: bool = False) -> None:
not already present. Defaults to False.
"""
warnings.warn(
"validate_has_extension is deprecated and will be removed in v1.9. "
"Use ensure_has_extension instead",
"validate_has_extension is deprecated. Use ensure_has_extension instead",
DeprecationWarning,
)

Expand Down
31 changes: 31 additions & 0 deletions tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,31 @@ def test_temporal_extent_init_typing(self) -> None:

_ = TemporalExtent([[start_datetime, end_datetime]])

@pytest.mark.block_network()
def test_temporal_extent_allows_single_interval(self) -> None:
start_datetime = str_to_datetime("2022-01-01T00:00:00Z")
end_datetime = str_to_datetime("2022-01-31T23:59:59Z")

interval = [start_datetime, end_datetime]
temporal_extent = TemporalExtent(intervals=interval) # type: ignore

self.assertEqual(temporal_extent.intervals, [interval])

@pytest.mark.block_network()
def test_temporal_extent_allows_single_interval_open_start(self) -> None:
end_datetime = str_to_datetime("2022-01-31T23:59:59Z")

interval = [None, end_datetime]
temporal_extent = TemporalExtent(intervals=interval)

self.assertEqual(temporal_extent.intervals, [interval])

@pytest.mark.block_network()
def test_temporal_extent_non_list_intervals_fails(self) -> None:
with pytest.raises(TypeError):
# Pass in non-list intervals
_ = TemporalExtent(intervals=1) # type: ignore

@pytest.mark.block_network()
def test_spatial_allows_single_bbox(self) -> None:
temporal_extent = TemporalExtent(intervals=[[TEST_DATETIME, None]])
Expand All @@ -399,6 +424,12 @@ def test_spatial_allows_single_bbox(self) -> None:

collection.validate()

@pytest.mark.block_network()
def test_spatial_extent_non_list_bboxes_fails(self) -> None:
with pytest.raises(TypeError):
# Pass in non-list bboxes
_ = SpatialExtent(bboxes=1) # type: ignore

def test_from_items(self) -> None:
item1 = Item(
id="test-item-1",
Expand Down

0 comments on commit cec0386

Please sign in to comment.