Skip to content

Commit 75a8c21

Browse files
committed
Add mypy to test step; fixes based on mypy errors
1 parent 4bb702a commit 75a8c21

33 files changed

+408
-354
lines changed

mypy.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[mypy]
2+
ignore_missing_imports = True
3+
disallow_untyped_defs = True

pystac/__init__.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class STACTypeError(Exception):
2323

2424
from typing import Any, Dict, Optional
2525
from pystac.version import (__version__, get_stac_version, set_stac_version) # type:ignore
26-
from pystac.stac_io import STAC_IO
26+
from pystac.stac_io import STAC_IO # type:ignore
2727
from pystac.extensions import Extensions # type:ignore
2828
from pystac.stac_object import (STACObject, STACObjectType) # type:ignore
2929
from pystac.media_type import MediaType # type:ignore
@@ -37,12 +37,8 @@ class STACTypeError(Exception):
3737
Provider) # type:ignore
3838
from pystac.item import (Item, Asset, CommonMetadata) # type:ignore
3939

40-
from pystac.serialization import stac_object_from_dict
41-
4240
import pystac.validation
4341

44-
STAC_IO.stac_object_from_dict = stac_object_from_dict
45-
4642
import pystac.extensions.base
4743
import pystac.extensions.eo
4844
import pystac.extensions.label
@@ -92,7 +88,9 @@ def read_file(href: str) -> STACObject:
9288
return STACObject.from_file(href)
9389

9490

95-
def write_file(obj: STACObject, include_self_link: bool = True, dest_href: Optional[str] = None):
91+
def write_file(obj: STACObject,
92+
include_self_link: bool = True,
93+
dest_href: Optional[str] = None) -> None:
9694
"""Writes a STACObject to a file.
9795
9896
This will write only the Catalog, Collection or Item ``obj``. It will not attempt
@@ -115,7 +113,9 @@ def write_file(obj: STACObject, include_self_link: bool = True, dest_href: Optio
115113
obj.save_object(include_self_link=include_self_link, dest_href=dest_href)
116114

117115

118-
def read_dict(d: Dict[str, Any], href: Optional[str] = None, root: Optional[Catalog] = None):
116+
def read_dict(d: Dict[str, Any],
117+
href: Optional[str] = None,
118+
root: Optional[Catalog] = None) -> STACObject:
119119
"""Reads a STAC object from a dict representing the serialized JSON version of the
120120
STAC object.
121121
@@ -132,4 +132,4 @@ def read_dict(d: Dict[str, Any], href: Optional[str] = None, root: Optional[Cata
132132
If provided, the root's resolved object cache can be used to search for
133133
previously resolved instances of the STAC object.
134134
"""
135-
return stac_object_from_dict(d, href, root)
135+
return STAC_IO.stac_object_from_dict(d, href, root)

pystac/cache.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def get_cache_key(stac_object: "STACObject") -> Tuple[str, bool]:
2626
return (href, True)
2727
else:
2828
ids: List[str] = []
29-
obj = stac_object
29+
obj: Optional[STACObject] = stac_object
3030
while obj is not None:
3131
ids.append(obj.id)
3232
obj = obj.get_parent()
@@ -65,7 +65,7 @@ def __init__(self,
6565
self.hrefs_to_objects = hrefs_to_objects or {}
6666
self.ids_to_collections = ids_to_collections or {}
6767

68-
self._collection_cache = None
68+
self._collection_cache: Optional[ResolvedObjectCollectionCache] = None
6969

7070
def get_or_cache(self, obj: "STACObject") -> "STACObject":
7171
"""Gets the STACObject that is the cached version of the given STACObject; or, if
@@ -268,7 +268,9 @@ def contains_id(self, collection_id: str) -> bool:
268268
return (self.resolved_object_cache.contains_collection_id(collection_id)
269269
or super().contains_id(collection_id))
270270

271-
def cache(self, collection: Dict[str, Any], href: Optional[str] = None) -> None:
271+
def cache(self,
272+
collection: Union["Collection", Dict[str, Any]],
273+
href: Optional[str] = None) -> None:
272274
super().cache(collection, href)
273275

274276
@staticmethod

pystac/catalog.py

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
class CatalogType(str, Enum):
17-
def __str__(self):
17+
def __str__(self) -> str:
1818
return str(self.value)
1919

2020
SELF_CONTAINED = 'SELF_CONTAINED'
@@ -137,7 +137,7 @@ def __init__(self,
137137
if href is not None:
138138
self.set_self_href(href)
139139

140-
self.catalog_type = catalog_type
140+
self.catalog_type: CatalogType = catalog_type
141141

142142
self._resolved_objects.cache(self)
143143

@@ -156,7 +156,7 @@ def is_relative(self) -> bool:
156156
def add_child(self,
157157
child: "Catalog",
158158
title: Optional[str] = None,
159-
strategy: Optional[HrefLayoutStrategy] = None):
159+
strategy: Optional[HrefLayoutStrategy] = None) -> None:
160160
"""Adds a link to a child :class:`~pystac.Catalog` or :class:`~pystac.Collection`.
161161
This method will set the child's parent to this object, and its root to
162162
this Catalog's root.
@@ -268,15 +268,15 @@ def get_children(self) -> Iterable["Catalog"]:
268268
"""
269269
return map(lambda x: cast(ps.Catalog, x), self.get_stac_objects('child'))
270270

271-
def get_child_links(self):
271+
def get_child_links(self) -> List[Link]:
272272
"""Return all child links of this catalog.
273273
274274
Return:
275275
List[Link]: List of links of this catalog with ``rel == 'child'``
276276
"""
277277
return self.get_links('child')
278278

279-
def clear_children(self) -> "Catalog":
279+
def clear_children(self) -> None:
280280
"""Removes all children from this catalog.
281281
282282
Return:
@@ -285,7 +285,6 @@ def clear_children(self) -> "Catalog":
285285
child_ids = [child.id for child in self.get_children()]
286286
for child_id in child_ids:
287287
self.remove_child(child_id)
288-
return self
289288

290289
def remove_child(self, child_id: str) -> None:
291290
"""Removes an child from this catalog.
@@ -336,7 +335,7 @@ def get_items(self) -> Iterable["ItemType"]:
336335
"""
337336
return map(lambda x: cast(ps.Item, x), self.get_stac_objects('item'))
338337

339-
def clear_items(self) -> "Catalog":
338+
def clear_items(self) -> None:
340339
"""Removes all items from this catalog.
341340
342341
Return:
@@ -349,7 +348,6 @@ def clear_items(self) -> "Catalog":
349348
item.set_root(None)
350349

351350
self.links = [link for link in self.links if link.rel != 'item']
352-
return self
353351

354352
def remove_item(self, item_id: str) -> None:
355353
"""Removes an item from this catalog.
@@ -396,7 +394,7 @@ def get_item_links(self) -> List[Link]:
396394
def to_dict(self, include_self_link: bool = True) -> Dict[str, Any]:
397395
links = self.links
398396
if not include_self_link:
399-
links = filter(lambda l: l.rel != 'self', links)
397+
links = [x for x in links if x.rel != 'self']
400398

401399
d: Dict[str, Any] = {
402400
'id': self.id,
@@ -438,15 +436,15 @@ def clone(self) -> "Catalog":
438436

439437
return clone
440438

441-
def make_all_asset_hrefs_relative(self):
439+
def make_all_asset_hrefs_relative(self) -> None:
442440
"""Makes all the HREFs of assets belonging to items in this catalog
443441
and all children to be relative, recursively.
444442
"""
445443
for _, _, items in self.walk():
446444
for item in items:
447445
item.make_asset_hrefs_relative()
448446

449-
def make_all_asset_hrefs_absolute(self):
447+
def make_all_asset_hrefs_absolute(self) -> None:
450448
"""Makes all the HREFs of assets belonging to items in this catalog
451449
and all children to be absolute, recursively.
452450
"""
@@ -457,7 +455,7 @@ def make_all_asset_hrefs_absolute(self):
457455
def normalize_and_save(self,
458456
root_href: str,
459457
catalog_type: Optional[CatalogType] = None,
460-
strategy: Optional[HrefLayoutStrategy] = None):
458+
strategy: Optional[HrefLayoutStrategy] = None) -> None:
461459
"""Normalizes link HREFs to the given root_href, and saves the catalog.
462460
463461
This is a convenience method that simply calls :func:`Catalog.normalize_hrefs
@@ -476,7 +474,9 @@ def normalize_and_save(self,
476474
self.normalize_hrefs(root_href, strategy=strategy)
477475
self.save(catalog_type)
478476

479-
def normalize_hrefs(self, root_href: str, strategy: Optional[HrefLayoutStrategy] = None):
477+
def normalize_hrefs(self,
478+
root_href: str,
479+
strategy: Optional[HrefLayoutStrategy] = None) -> None:
480480
"""Normalize HREFs will regenerate all link HREFs based on
481481
an absolute root_href and the canonical catalog layout as specified
482482
in the STAC specification's best practices.
@@ -492,7 +492,9 @@ def normalize_hrefs(self, root_href: str, strategy: Optional[HrefLayoutStrategy]
492492
`STAC best practices document <https://github.com/radiantearth/stac-spec/blob/v0.8.1/best-practices.md#catalog-layout>`_ for the canonical layout of a STAC.
493493
""" # noqa E501
494494
if strategy is None:
495-
strategy = BestPracticesLayoutStrategy()
495+
_strategy: HrefLayoutStrategy = BestPracticesLayoutStrategy()
496+
else:
497+
_strategy = strategy
496498

497499
# Normalizing requires an absolute path
498500
if not is_absolute_href(root_href):
@@ -501,9 +503,9 @@ def normalize_hrefs(self, root_href: str, strategy: Optional[HrefLayoutStrategy]
501503
def process_item(item: "ItemType", _root_href: str) -> Callable[[], None]:
502504
item.resolve_links()
503505

504-
new_self_href = strategy.get_href(item, _root_href)
506+
new_self_href = _strategy.get_href(item, _root_href)
505507

506-
def fn():
508+
def fn() -> None:
507509
item.set_self_href(new_self_href)
508510

509511
return fn
@@ -514,7 +516,7 @@ def process_catalog(cat: Catalog, _root_href: str,
514516

515517
cat.resolve_links()
516518

517-
new_self_href = strategy.get_href(cat, _root_href, is_root)
519+
new_self_href = _strategy.get_href(cat, _root_href, is_root)
518520
new_root = os.path.dirname(new_self_href)
519521

520522
for item in cat.get_items():
@@ -523,7 +525,7 @@ def process_catalog(cat: Catalog, _root_href: str,
523525
for child in cat.get_children():
524526
setter_funcs.extend(process_catalog(child, new_root, is_root=False))
525527

526-
def fn():
528+
def fn() -> None:
527529
cat.set_self_href(new_self_href)
528530

529531
setter_funcs.append(fn)
@@ -538,8 +540,6 @@ def fn():
538540
for fn in setter_funcs:
539541
fn()
540542

541-
return self
542-
543543
def generate_subcatalogs(self,
544544
template: str,
545545
defaults: Optional[Dict[str, Any]] = None,
@@ -602,9 +602,9 @@ def generate_subcatalogs(self,
602602
curr_parent = subcat
603603

604604
# resolve collection link so when added back points to correct location
605-
link = item.get_single_link('collection')
606-
if link is not None:
607-
link.resolve_stac_object()
605+
col_link = item.get_single_link('collection')
606+
if col_link is not None:
607+
col_link.resolve_stac_object()
608608

609609
curr_parent.add_item(item)
610610

@@ -613,7 +613,7 @@ def generate_subcatalogs(self,
613613

614614
return result
615615

616-
def save(self, catalog_type: CatalogType = None) -> None:
616+
def save(self, catalog_type: Optional[CatalogType] = None) -> None:
617617
"""Save this catalog and all it's children/item to files determined by the object's
618618
self link HREF.
619619
@@ -652,14 +652,16 @@ def save(self, catalog_type: CatalogType = None) -> None:
652652

653653
include_self_link = False
654654
# include a self link if this is the root catalog or if ABSOLUTE_PUBLISHED catalog
655-
if ((self.get_self_href() == self.get_root_link().get_absolute_href()
656-
and root.catalog_type != CatalogType.SELF_CONTAINED)
657-
or root.catalog_type == CatalogType.ABSOLUTE_PUBLISHED):
655+
if root.catalog_type == CatalogType.ABSOLUTE_PUBLISHED:
658656
include_self_link = True
657+
elif root.catalog_type != CatalogType.SELF_CONTAINED:
658+
root_link = self.get_root_link()
659+
if root_link and root_link.get_absolute_href() == self.get_self_href():
660+
include_self_link = True
659661

660662
self.save_object(include_self_link=include_self_link)
661-
662-
self.catalog_type = catalog_type
663+
if catalog_type is not None:
664+
self.catalog_type = catalog_type
663665

664666
def walk(self) -> Iterable[Tuple["Catalog", Iterable["Catalog"], Iterable["ItemType"]]]:
665667
"""Walks through children and items of catalogs.
@@ -702,7 +704,9 @@ def validate_all(self) -> None:
702704
def _object_links(self) -> List[str]:
703705
return ['child', 'item'] + (ps.STAC_EXTENSIONS.get_extended_object_links(self))
704706

705-
def map_items(self, item_mapper: Callable[["ItemType"], Union["ItemType", List["ItemType"]]]):
707+
def map_items(
708+
self, item_mapper: Callable[["ItemType"], Union["ItemType",
709+
List["ItemType"]]]) -> "Catalog":
706710
"""Creates a copy of a catalog, with each item passed through the
707711
item_mapper function.
708712
@@ -718,7 +722,7 @@ def map_items(self, item_mapper: Callable[["ItemType"], Union["ItemType", List["
718722

719723
new_cat = cast(Catalog, self.full_copy())
720724

721-
def process_catalog(catalog: Catalog):
725+
def process_catalog(catalog: Catalog) -> None:
722726
for child in catalog.get_children():
723727
process_catalog(child)
724728

@@ -742,9 +746,10 @@ def process_catalog(catalog: Catalog):
742746
process_catalog(new_cat)
743747
return new_cat
744748

745-
def map_assets(self, asset_mapper: Callable[[str, "AssetType"],
746-
Union["AssetType", Tuple[str, "AssetType"],
747-
Dict[str, "AssetType"]]]):
749+
def map_assets(
750+
self, asset_mapper: Callable[[str, "AssetType"], Union["AssetType", Tuple[str, "AssetType"],
751+
Dict[str, "AssetType"]]]
752+
) -> "Catalog":
748753
"""Creates a copy of a catalog, with each Asset for each Item passed
749754
through the asset_mapper function.
750755
@@ -758,7 +763,7 @@ def map_assets(self, asset_mapper: Callable[[str, "AssetType"],
758763
Catalog: A full copy of this catalog, with assets manipulated according
759764
to the asset_mapper function.
760765
"""
761-
def apply_asset_mapper(tup: Tuple[str, "AssetType"]):
766+
def apply_asset_mapper(tup: Tuple[str, "AssetType"]) -> List[Tuple[str, ps.Asset]]:
762767
k, v = tup
763768
result = asset_mapper(k, v)
764769
if result is None:
@@ -773,7 +778,7 @@ def apply_asset_mapper(tup: Tuple[str, "AssetType"]):
773778
raise Exception('asset_mapper must return a non-empty list')
774779
return assets
775780

776-
def item_mapper(item: ps.Item):
781+
def item_mapper(item: ps.Item) -> ps.Item:
777782
new_assets = [
778783
x for result in map(apply_asset_mapper, item.assets.items()) for x in result
779784
]
@@ -782,7 +787,7 @@ def item_mapper(item: ps.Item):
782787

783788
return self.map_items(item_mapper)
784789

785-
def describe(self, include_hrefs: bool = False, _indent: int = 0):
790+
def describe(self, include_hrefs: bool = False, _indent: int = 0) -> None:
786791
"""Prints out information about this Catalog and all contained
787792
STACObjects.
788793

0 commit comments

Comments
 (0)