Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preserve_dict parameter to ItemCollection.from_dict #468

Merged
merged 2 commits into from
Jun 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Added

- Add a `preserve_dict` parameter to `ItemCollection.from_dict` and set it to False when using `ItemCollection.from_file`. ([#468](https://github.com/stac-utils/pystac/pull/468))

### Changed

### Fixed
Expand Down
16 changes: 13 additions & 3 deletions pystac/item_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,26 @@ def clone(self) -> "ItemCollection":
)

@classmethod
def from_dict(cls, d: Dict[str, Any]) -> "ItemCollection":
def from_dict(
cls, d: Dict[str, Any], preserve_dict: bool = True
) -> "ItemCollection":
"""Creates a :class:`ItemCollection` instance from a dictionary.

Arguments:
d : The dictionary from which the :class:`~ItemCollection` will be created
preserve_dict: If False, the dict parameter ``d`` may be modified
during this method call. Otherwise the dict is not mutated.
Defaults to True, which results results in a deepcopy of the
parameter. Set to False when possible to avoid the performance
hit of a deepcopy.
"""
if not cls.is_item_collection(d):
raise STACTypeError("Dict is not a valid ItemCollection")

items = [pystac.Item.from_dict(item) for item in d.get("features", [])]
items = [
pystac.Item.from_dict(item, preserve_dict=preserve_dict)
for item in d.get("features", [])
]
extra_fields = {k: v for k, v in d.items() if k not in ("features", "type")}

return cls(items=items, extra_fields=extra_fields)
Expand All @@ -166,7 +176,7 @@ def from_file(

d = stac_io.read_json(href)

return cls.from_dict(d)
return cls.from_dict(d, preserve_dict=False)

def save_object(
self,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def test_assets(self) -> None:
collection = pystac.Collection.from_dict(data)
collection.validate()

def test_to_dict_preserves_dict(self) -> None:
def test_from_dict_preserves_dict(self) -> None:
path = TestCases.get_path("data-files/collections/with-assets.json")
with open(path) as f:
collection_dict = json.load(f)
Expand Down
14 changes: 14 additions & 0 deletions tests/test_item_collection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from copy import deepcopy
import json
from pystac.item_collection import ItemCollection
import unittest
import pystac

Expand Down Expand Up @@ -149,3 +151,15 @@ def test_identify_0_9_itemcollection(self) -> None:
pystac.ItemCollection.is_item_collection(itemcollection_dict),
msg="Did not correctly identify valid STAC 0.9 ItemCollection.",
)

def test_from_dict_preserves_dict(self) -> None:
param_dict = deepcopy(self.item_collection_dict)

# test that the parameter is preserved
_ = ItemCollection.from_dict(param_dict)
self.assertEqual(param_dict, self.item_collection_dict)

# assert that the parameter is not preserved with
# non-default parameter
_ = ItemCollection.from_dict(param_dict, preserve_dict=False)
self.assertNotEqual(param_dict, self.item_collection_dict)