diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4233bc682..03321520b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: - id: ruff-format name: ruff-format - entry: ruff format --force-exclude --check + entry: ruff format --force-exclude language: system stages: [commit] types_or: [python, pyi, jupyter] diff --git a/CHANGELOG.md b/CHANGELOG.md index e562f9858..07f0c189e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Add netCDF to pystac.media_type ([#1386](https://github.com/stac-utils/pystac/pull/1386)) - Add convenience method for accessing pystac_client ([#1365](https://github.com/stac-utils/pystac/pull/1365)) +- Fix field ordering when saving `Item`s ([#1423](https://github.com/stac-utils/pystac/pull/1423)) ### Changed diff --git a/pystac/item.py b/pystac/item.py index a24028361..054f124d1 100644 --- a/pystac/item.py +++ b/pystac/item.py @@ -365,25 +365,25 @@ def to_dict( d: dict[str, Any] = { "type": "Feature", "stac_version": pystac.get_stac_version(), + "stac_extensions": self.stac_extensions if self.stac_extensions else [], "id": self.id, - "properties": self.properties, "geometry": self.geometry, + "bbox": self.bbox if self.bbox is not None else [], + "properties": self.properties, "links": [link.to_dict(transform_href=transform_hrefs) for link in links], "assets": assets, } - if self.bbox is not None: - d["bbox"] = self.bbox - - if self.stac_extensions is not None: - d["stac_extensions"] = self.stac_extensions - if self.collection_id: d["collection"] = self.collection_id for key in self.extra_fields: d[key] = self.extra_fields[key] + # This field is prohibited if there's no geometry + if not self.geometry: + d.pop("bbox") + return d def clone(self) -> Item: diff --git a/tests/test_item.py b/tests/test_item.py index 46fd984af..2ab846cef 100644 --- a/tests/test_item.py +++ b/tests/test_item.py @@ -108,6 +108,30 @@ def test_asset_absolute_href_no_item_self(self) -> None: actual_href = rel_asset.get_absolute_href() self.assertEqual(None, actual_href) + def test_item_field_order(self) -> None: + item = pystac.Item.from_file( + TestCases.get_path("data-files/item/sample-item.json") + ) + item_dict = item.to_dict(include_self_link=False) + expected_order = [ + "type", + "stac_version", + "stac_extensions", + "id", + "geometry", + "bbox", + "properties", + "links", + "assets", + "collection", + ] + actual_order = list(item_dict.keys()) + self.assertEqual( + actual_order, + expected_order, + f"Order was {actual_order}, expected {expected_order}", + ) + def test_extra_fields(self) -> None: item = pystac.Item.from_file( TestCases.get_path("data-files/item/sample-item.json")