diff --git a/pystac/__init__.py b/pystac/__init__.py index e28a03b87..19732af9b 100644 --- a/pystac/__init__.py +++ b/pystac/__init__.py @@ -12,7 +12,7 @@ STACValidationError, ) -from typing import Any, Dict, Optional, Union +from typing import Any, Dict, Optional from pystac.version import ( __version__, get_stac_version, @@ -72,7 +72,7 @@ ) -def read_file(href: str) -> Union[STACObject, ItemCollection]: +def read_file(href: str) -> STACObject: """Reads a STAC object from a file. This method will return either a Catalog, a Collection, or an Item based on what the @@ -86,15 +86,18 @@ def read_file(href: str) -> Union[STACObject, ItemCollection]: Returns: The specific STACObject implementation class that is represented by the JSON read from the file located at HREF. + + Raises: + STACTypeError : If the file at ``href`` does not represent a valid + :class:`~pystac.STACObject`. Note that an :class:`~pystac.ItemCollection` is not + a :class:`~pystac.STACObject` and must be read using + :meth:`ItemCollection.from_file ` """ - try: - return STACObject.from_file(href) - except STACTypeError: - return ItemCollection.from_file(href) + return STACObject.from_file(href) def write_file( - obj: Union[STACObject, ItemCollection], + obj: STACObject, include_self_link: bool = True, dest_href: Optional[str] = None, ) -> None: @@ -113,19 +116,11 @@ def write_file( Args: obj : The STACObject to save. include_self_link : If ``True``, include the ``"self"`` link with this object. - Otherwise, leave out the self link. Ignored for :class:~ItemCollection` - instances. + Otherwise, leave out the self link. dest_href : Optional HREF to save the file to. If ``None``, the object will be - saved to the object's ``"self"`` href (for :class:`~STACObject` sub-classes) - or a :exc:`~STACError` will be raised (for :class:`~ItemCollection` - instances). + saved to the object's ``"self"`` href. """ - if isinstance(obj, ItemCollection): - if dest_href is None: - raise STACError("Must provide dest_href when saving and ItemCollection.") - obj.save_object(dest_href=dest_href) - else: - obj.save_object(include_self_link=include_self_link, dest_href=dest_href) + obj.save_object(include_self_link=include_self_link, dest_href=dest_href) def read_dict( @@ -133,31 +128,32 @@ def read_dict( href: Optional[str] = None, root: Optional[Catalog] = None, stac_io: Optional[StacIO] = None, -) -> Union[STACObject, ItemCollection]: +) -> STACObject: """Reads a :class:`~STACObject` or :class:`~ItemCollection` from a JSON-like dict representing a serialized STAC object. This method will return either a :class:`~Catalog`, :class:`~Collection`, - :class`~Item`, or :class:`~ItemCollection` based on the contents of the dict. + or :class`~Item` based on the contents of the dict. This is a convenience method for either - :meth:`stac_io.stac_object_from_dict ` or - :meth:`ItemCollection.from_dict `. + :meth:`stac_io.stac_object_from_dict `. Args: d : The dict to parse. href : Optional href that is the file location of the object being - parsed. Ignored if the dict represents an :class:`~ItemCollection`. + parsed. root : Optional root of the catalog for this object. If provided, the root's resolved object cache can be used to search for - previously resolved instances of the STAC object. Ignored if the dict - represents an :class:`~ItemCollection`. + previously resolved instances of the STAC object. stac_io: Optional :class:`~StacIO` instance to use for reading. If ``None``, the default instance will be used. + + Raises: + STACTypeError : If the ``d`` dictionary does not represent a valid + :class:`~pystac.STACObject`. Note that an :class:`~pystac.ItemCollection` is not + a :class:`~pystac.STACObject` and must be read using + :meth:`ItemCollection.from_dict ` """ if stac_io is None: stac_io = StacIO.default() - try: - return stac_io.stac_object_from_dict(d, href, root) - except STACTypeError: - return ItemCollection.from_dict(d) + return stac_io.stac_object_from_dict(d, href, root) diff --git a/tests/data-files/change_stac_version.py b/tests/data-files/change_stac_version.py index 2cec60c3d..bc8ab8b1f 100644 --- a/tests/data-files/change_stac_version.py +++ b/tests/data-files/change_stac_version.py @@ -29,10 +29,9 @@ def migrate(path: str) -> None: ) ) obj = pystac.read_dict(stac_json, href=path) - if not isinstance(obj, pystac.ItemCollection): - migrated = obj.to_dict(include_self_link=False) - with open(path, "w") as f: - json.dump(migrated, f, indent=2) + migrated = obj.to_dict(include_self_link=False) + with open(path, "w") as f: + json.dump(migrated, f, indent=2) if __name__ == "__main__": diff --git a/tests/test_item_collection.py b/tests/test_item_collection.py index f95fbde3e..8bdc25213 100644 --- a/tests/test_item_collection.py +++ b/tests/test_item_collection.py @@ -1,5 +1,4 @@ import json -from typing import cast import unittest import pystac @@ -80,19 +79,6 @@ def test_item_collection_from_dict(self) -> None: self.assertEqual(expected, len(item_collection.items)) self.assertEqual(item_collection.extra_fields.get("custom_field"), "My value") - def test_item_collection_from_dict_top_level(self) -> None: - features = [item.to_dict() for item in self.items] - d = { - "type": "FeatureCollection", - "features": features, - "custom_field": "My value", - } - item_collection = pystac.read_dict(d) - item_collection = cast(pystac.ItemCollection, item_collection) - expected = len(features) - self.assertEqual(expected, len(item_collection.items)) - self.assertEqual(item_collection.extra_fields.get("custom_field"), "My value") - def test_clone_item_collection(self) -> None: item_collection_1 = pystac.ItemCollection.from_file(self.ITEM_COLLECTION) item_collection_2 = item_collection_1.clone() diff --git a/tests/test_stac_io.py b/tests/test_stac_io.py index 96437f959..55db6b9b6 100644 --- a/tests/test_stac_io.py +++ b/tests/test_stac_io.py @@ -46,18 +46,10 @@ def test_read_write_catalog(self) -> None: pystac.write_file(catalog, dest_href=dest_href) self.assertTrue(os.path.exists(dest_href), msg="File was not written.") - def test_read_write_item_collection(self) -> None: - item_collection = pystac.read_file( - TestCases.get_path("data-files/item-collection/sample-item-collection.json") - ) - with get_temp_dir() as tmp_dir: - dest_href = os.path.join(tmp_dir, "item-collection.json") - pystac.write_file(item_collection, dest_href=dest_href) - self.assertTrue(os.path.exists(dest_href), msg="File was not written.") - - def test_write_item_collection_needs_href(self) -> None: - item_collection = pystac.read_file( - TestCases.get_path("data-files/item-collection/sample-item-collection.json") - ) - with self.assertRaises(pystac.STACError): - pystac.write_file(item_collection) + def test_read_item_collection_raises_exception(self) -> None: + with self.assertRaises(pystac.STACTypeError): + _ = pystac.read_file( + TestCases.get_path( + "data-files/item-collection/sample-item-collection.json" + ) + ) diff --git a/tests/validation/test_validate.py b/tests/validation/test_validate.py index 7e1ea6af1..c6bf68444 100644 --- a/tests/validation/test_validate.py +++ b/tests/validation/test_validate.py @@ -1,7 +1,7 @@ from datetime import datetime import json import os -from typing import Any, Dict, cast +from typing import Any, Dict from pystac.utils import get_opt import shutil import unittest @@ -20,7 +20,6 @@ def test_validate_current_version(self) -> None: catalog = pystac.read_file( TestCases.get_path("data-files/catalogs/test-case-1/" "catalog.json") ) - catalog = cast(pystac.STACObject, catalog) catalog.validate() collection = pystac.read_file( @@ -30,11 +29,9 @@ def test_validate_current_version(self) -> None: "collection.json" ) ) - collection = cast(pystac.Collection, collection) collection.validate() item = pystac.read_file(TestCases.get_path("data-files/item/sample-item.json")) - item = cast(pystac.Item, item) item.validate() def test_validate_examples(self) -> None: