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

When instantiating ItemCollections clone items by default #1016

Merged
merged 3 commits into from
Mar 1, 2023
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- Use `from __future__ import annotations` for type signatures ([#962](https://github.com/stac-utils/pystac/pull/962))
- Use `TypeVar` for alternate constructors ([#983](https://github.com/stac-utils/pystac/pull/983))
- Behavior when required fields are missing in `Item.from_dict` ([#994](https://github.com/stac-utils/pystac/pull/994))
- By default, `ItemCollection` now clones items in iterator (`clone_items=True`) ([#1016](https://github.com/stac-utils/pystac/pull/1016))
- `TemplateError` in `layout.py` deprecated in favor of duplicate in `errors.py` ([#1018](https://github.com/stac-utils/pystac/pull/1018))

### Fixed
Expand Down
22 changes: 9 additions & 13 deletions pystac/item_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ class ItemCollection(Collection[pystac.Item]):
:class:`~ItemCollection`.
clone_items : Optional flag indicating whether :class:`~pystac.Item` instances
should be cloned before storing in the :class:`~ItemCollection`. Setting to
``True`` ensures that changes made to :class:`~pystac.Item` instances in
the :class:`~ItemCollection` will not mutate the original ``Item``, but
will result in slower instantiation. Defaults to ``False``.
``False`` will result in faster instantiation, but changes made to
:class:`~pystac.Item` instances in the :class:`~ItemCollection` will mutate
the original ``Item``. Defaults to ``True``.

Examples:

Expand All @@ -71,7 +71,7 @@ class ItemCollection(Collection[pystac.Item]):
object equality (i.e. ``item_1 is item_2``).

>>> item: Item = ...
>>> item_collection = ItemCollection(items=[item])
>>> item_collection = ItemCollection(items=[item], clone_items=False)
>>> assert item in item_collection

Combine :class:`~ItemCollection` instances
Expand All @@ -82,8 +82,8 @@ class ItemCollection(Collection[pystac.Item]):
>>> item_collection_1 = ItemCollection(items=[item_1, item_2])
>>> item_collection_2 = ItemCollection(items=[item_2, item_3])
>>> combined = item_collection_1 + item_collection_2
>>> assert len(combined) == 3
# If an item is present in both ItemCollections it will only be added once
>>> assert len(combined) == 4
# If an item is present in both ItemCollections it will occur twice
"""

items: List[pystac.Item]
Expand All @@ -97,7 +97,7 @@ def __init__(
self,
items: Iterable[ItemLike],
extra_fields: Optional[Dict[str, Any]] = None,
clone_items: bool = False,
clone_items: bool = True,
):
def map_item(item_or_dict: ItemLike) -> pystac.Item:
# Converts dicts to pystac.Items and clones if necessary
Expand Down Expand Up @@ -125,12 +125,8 @@ def __add__(self, other: object) -> "ItemCollection":
if not isinstance(other, ItemCollection):
return NotImplemented

combined = []
for item in self.items + other.items:
if item not in combined:
combined.append(item)

return ItemCollection(items=combined, clone_items=False)
combined = [*self.items, *other.items]
return ItemCollection(items=combined)

def to_dict(self, transform_hrefs: bool = False) -> Dict[str, Any]:
"""Serializes an :class:`ItemCollection` instance to a JSON-like dictionary.
Expand Down
4 changes: 2 additions & 2 deletions tests/test_item_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_item_collection_get_item_by_index(self) -> None:

def test_item_collection_contains(self) -> None:
item = pystac.Item.from_file(self.SIMPLE_ITEM)
item_collection = pystac.ItemCollection(items=[item])
item_collection = pystac.ItemCollection(items=[item], clone_items=False)

self.assertIn(item, item_collection)

Expand Down Expand Up @@ -126,7 +126,7 @@ def test_add_item_collections(self) -> None:

combined = item_collection_1 + item_collection_2

self.assertEqual(len(combined), 3)
self.assertEqual(len(combined), 4)

def test_add_other_raises_error(self) -> None:
item_collection = pystac.ItemCollection.from_file(self.ITEM_COLLECTION)
Expand Down