earthengine-api 1.5.24__py3-none-any.whl → 1.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of earthengine-api might be problematic. Click here for more details.

Files changed (63) hide show
  1. {earthengine_api-1.5.24.dist-info → earthengine_api-1.6.0.dist-info}/METADATA +1 -1
  2. earthengine_api-1.6.0.dist-info/RECORD +107 -0
  3. ee/__init__.py +11 -10
  4. ee/_arg_types.py +2 -1
  5. ee/_cloud_api_utils.py +7 -6
  6. ee/_helpers.py +3 -2
  7. ee/apifunction.py +11 -9
  8. ee/apitestcase.py +2 -1
  9. ee/batch.py +46 -42
  10. ee/blob.py +2 -2
  11. ee/classifier.py +57 -59
  12. ee/cli/commands.py +9 -7
  13. ee/cli/utils.py +13 -9
  14. ee/clusterer.py +39 -41
  15. ee/collection.py +42 -42
  16. ee/computedobject.py +10 -10
  17. ee/confusionmatrix.py +8 -8
  18. ee/customfunction.py +2 -2
  19. ee/data.py +15 -14
  20. ee/daterange.py +9 -9
  21. ee/deprecation.py +13 -11
  22. ee/deserializer.py +5 -5
  23. ee/dictionary.py +11 -11
  24. ee/ee_array.py +17 -17
  25. ee/ee_date.py +22 -22
  26. ee/ee_list.py +15 -15
  27. ee/ee_number.py +5 -5
  28. ee/ee_string.py +6 -6
  29. ee/ee_types.py +2 -2
  30. ee/element.py +14 -14
  31. ee/errormargin.py +3 -3
  32. ee/feature.py +67 -70
  33. ee/featurecollection.py +30 -32
  34. ee/filter.py +88 -90
  35. ee/function.py +3 -3
  36. ee/geometry.py +61 -62
  37. ee/image.py +216 -209
  38. ee/image_converter.py +2 -2
  39. ee/imagecollection.py +23 -20
  40. ee/join.py +13 -15
  41. ee/kernel.py +55 -57
  42. ee/oauth.py +26 -20
  43. ee/pixeltype.py +5 -5
  44. ee/projection.py +4 -3
  45. ee/reducer.py +39 -41
  46. ee/serializer.py +4 -4
  47. ee/table_converter.py +3 -2
  48. ee/terrain.py +6 -8
  49. ee/tests/_cloud_api_utils_test.py +1 -1
  50. ee/tests/_helpers_test.py +1 -1
  51. ee/tests/batch_test.py +1 -1
  52. ee/tests/data_test.py +2 -2
  53. ee/tests/ee_test.py +3 -3
  54. ee/tests/errormargin_test.py +1 -1
  55. ee/tests/image_converter_test.py +2 -2
  56. ee/tests/pixeltype_test.py +1 -2
  57. ee/tests/projection_test.py +2 -3
  58. ee/tests/table_converter_test.py +2 -2
  59. earthengine_api-1.5.24.dist-info/RECORD +0 -107
  60. {earthengine_api-1.5.24.dist-info → earthengine_api-1.6.0.dist-info}/WHEEL +0 -0
  61. {earthengine_api-1.5.24.dist-info → earthengine_api-1.6.0.dist-info}/entry_points.txt +0 -0
  62. {earthengine_api-1.5.24.dist-info → earthengine_api-1.6.0.dist-info}/licenses/LICENSE +0 -0
  63. {earthengine_api-1.5.24.dist-info → earthengine_api-1.6.0.dist-info}/top_level.txt +0 -0
ee/collection.py CHANGED
@@ -6,7 +6,7 @@ This class is never intended to be instantiated by the user.
6
6
  from __future__ import annotations
7
7
 
8
8
  import datetime
9
- from typing import Any, Callable, Optional, Type, Union
9
+ from typing import Any, Callable
10
10
 
11
11
  from ee import _arg_types
12
12
  from ee import _utils
@@ -38,7 +38,7 @@ class Collection(element.Element):
38
38
  self,
39
39
  func: function.Function,
40
40
  args: dict[str, Any],
41
- varName: Optional[str] = None, # pylint: disable=invalid-name
41
+ varName: str | None = None, # pylint: disable=invalid-name
42
42
  ):
43
43
  """Constructs a collection by initializing its ComputedObject."""
44
44
  super().__init__(func, args, varName)
@@ -320,8 +320,8 @@ class Collection(element.Element):
320
320
  def bounds(
321
321
  self,
322
322
  # pylint: disable-next=invalid-name
323
- maxError: Optional[_arg_types.ErrorMargin] = None,
324
- proj: Optional[_arg_types.Projection] = None,
323
+ maxError: _arg_types.ErrorMargin | None = None,
324
+ proj: _arg_types.Projection | None = None,
325
325
  ) -> ee_geometry.Geometry:
326
326
  """Returns the bounding rectangle of the geometry.
327
327
 
@@ -339,8 +339,8 @@ class Collection(element.Element):
339
339
  def distance(
340
340
  self,
341
341
  # pylint: disable=invalid-name
342
- searchRadius: Optional[_arg_types.Number] = None,
343
- maxError: Optional[_arg_types.Number] = None,
342
+ searchRadius: _arg_types.Number | None = None,
343
+ maxError: _arg_types.Number | None = None,
344
344
  # pylint: enable=invalid-name
345
345
  ) -> image.Image:
346
346
  """Returns a distance image for the collection.
@@ -368,7 +368,7 @@ class Collection(element.Element):
368
368
  )
369
369
 
370
370
  def distinct(
371
- self, properties: Union[_arg_types.String, _arg_types.List]
371
+ self, properties: _arg_types.String | _arg_types.List
372
372
  ) -> featurecollection.FeatureCollection:
373
373
  """Returns a collection with duplicates removed.
374
374
 
@@ -389,8 +389,8 @@ class Collection(element.Element):
389
389
  self,
390
390
  color: _arg_types.String,
391
391
  # pylint: disable=invalid-name
392
- pointRadius: Optional[_arg_types.Integer] = None,
393
- strokeWidth: Optional[_arg_types.Integer] = None,
392
+ pointRadius: _arg_types.Integer | None = None,
393
+ strokeWidth: _arg_types.Integer | None = None,
394
394
  # pylint: enable=invalid-name
395
395
  ) -> image.Image:
396
396
  """Returns a painted image of a vector collection for visualization.
@@ -409,7 +409,7 @@ class Collection(element.Element):
409
409
  )
410
410
 
411
411
  @staticmethod
412
- def elementType() -> Type[element.Element]:
412
+ def elementType() -> type[element.Element]:
413
413
  """Returns the type of the collection's elements."""
414
414
  return element.Element
415
415
 
@@ -417,7 +417,7 @@ class Collection(element.Element):
417
417
  self,
418
418
  actual: _arg_types.String,
419
419
  predicted: _arg_types.String,
420
- order: Optional[_arg_types.List] = None,
420
+ order: _arg_types.List | None = None,
421
421
  ) -> confusionmatrix.ConfusionMatrix:
422
422
  """Returns a 2D error matrix for a collection.
423
423
 
@@ -442,7 +442,7 @@ class Collection(element.Element):
442
442
  'Collection.errorMatrix', self, actual, predicted, order
443
443
  )
444
444
 
445
- def filter(self, new_filter: Union[str, ee_filter.Filter]) -> Any:
445
+ def filter(self, new_filter: str | ee_filter.Filter) -> Any:
446
446
  """Apply a filter to this collection.
447
447
 
448
448
  Args:
@@ -459,7 +459,7 @@ class Collection(element.Element):
459
459
 
460
460
  @deprecation.CanUseDeprecated
461
461
  def filterMetadata(
462
- self, name: str, operator: str, value: Union[int, str]
462
+ self, name: str, operator: str, value: int | str
463
463
  ) -> Any:
464
464
  """Shortcut to add a metadata filter to a collection.
465
465
 
@@ -480,7 +480,7 @@ class Collection(element.Element):
480
480
  return self.filter(ee_filter.Filter.metadata_(name, operator, value))
481
481
 
482
482
  def filterBounds(
483
- self, geometry: Union[dict[str, Any], ee_geometry.Geometry]
483
+ self, geometry: dict[str, Any] | ee_geometry.Geometry
484
484
  ) -> Any:
485
485
  """Shortcut to add a geometry filter to a collection.
486
486
 
@@ -506,10 +506,10 @@ class Collection(element.Element):
506
506
  @_utils.accept_opt_prefix('opt_end')
507
507
  def filterDate(
508
508
  self,
509
- start: Union[datetime.datetime, ee_date.Date, int, str, Any],
510
- end: Optional[
511
- Union[datetime.datetime, ee_date.Date, int, str, Any]
512
- ] = None,
509
+ start: datetime.datetime | ee_date.Date | int | str | Any,
510
+ end: None | (
511
+ datetime.datetime | ee_date.Date | int | str | Any
512
+ ) = None,
513
513
  ) -> Any:
514
514
  """Shortcut to filter a collection with a date range.
515
515
 
@@ -542,7 +542,7 @@ class Collection(element.Element):
542
542
  def geometry(
543
543
  self,
544
544
  # pylint: disable-next=invalid-name
545
- maxError: Optional[_arg_types.ErrorMargin] = None,
545
+ maxError: _arg_types.ErrorMargin | None = None,
546
546
  ) -> ee_geometry.Geometry:
547
547
  """Returns the geometry of a collection.
548
548
 
@@ -563,7 +563,7 @@ class Collection(element.Element):
563
563
  )
564
564
 
565
565
  # pylint: disable-next=useless-parent-delegation
566
- def getInfo(self) -> Optional[Any]:
566
+ def getInfo(self) -> Any | None:
567
567
  """Returns all the known information about this collection.
568
568
 
569
569
  This function makes a REST call to to retrieve all the known information
@@ -579,7 +579,7 @@ class Collection(element.Element):
579
579
  return super().getInfo()
580
580
 
581
581
  def iterate(
582
- self, algorithm: Callable[[Any, Any], Any], first: Optional[Any] = None
582
+ self, algorithm: Callable[[Any, Any], Any], first: Any | None = None
583
583
  ) -> Any:
584
584
  """Iterates over a collection with an algorithm.
585
585
 
@@ -610,8 +610,8 @@ class Collection(element.Element):
610
610
  def limit(
611
611
  self,
612
612
  maximum: int,
613
- prop: Optional[str] = None,
614
- ascending: Optional[bool] = None,
613
+ prop: str | None = None,
614
+ ascending: bool | None = None,
615
615
  ) -> Collection:
616
616
  """Limit a collection to the specified number of elements.
617
617
 
@@ -639,9 +639,9 @@ class Collection(element.Element):
639
639
  def loadTable(
640
640
  # pylint: disable=invalid-name
641
641
  tableId: _arg_types.String,
642
- geometryColumn: Optional[_arg_types.String] = None,
642
+ geometryColumn: _arg_types.String | None = None,
643
643
  # pylint: enable=invalid-name
644
- version: Optional[_arg_types.Integer] = None,
644
+ version: _arg_types.Integer | None = None,
645
645
  ) -> featurecollection.FeatureCollection:
646
646
  """Returns a Collection of features from a specified table.
647
647
 
@@ -662,7 +662,7 @@ class Collection(element.Element):
662
662
  def map(
663
663
  self,
664
664
  algorithm: Callable[[Any], Any],
665
- dropNulls: Optional[bool] = None, # pylint: disable=invalid-name
665
+ dropNulls: bool | None = None, # pylint: disable=invalid-name
666
666
  ) -> Any:
667
667
  """Maps an algorithm over a collection.
668
668
 
@@ -714,11 +714,11 @@ class Collection(element.Element):
714
714
  def randomColumn(
715
715
  self,
716
716
  # pylint: disable-next=invalid-name
717
- columnName: Optional[_arg_types.String] = None,
718
- seed: Optional[_arg_types.Integer] = None,
719
- distribution: Optional[_arg_types.String] = None,
717
+ columnName: _arg_types.String | None = None,
718
+ seed: _arg_types.Integer | None = None,
719
+ distribution: _arg_types.String | None = None,
720
720
  # pylint: disable-next=invalid-name
721
- rowKeys: Optional[_arg_types.List] = None,
721
+ rowKeys: _arg_types.List | None = None,
722
722
  ) -> featurecollection.FeatureCollection:
723
723
  """Returns a collection with a random column added to each feature.
724
724
 
@@ -747,7 +747,7 @@ class Collection(element.Element):
747
747
  reducer: _arg_types.Reducer,
748
748
  selectors: _arg_types.List,
749
749
  # pylint: disable=invalid-name
750
- weightSelectors: Optional[_arg_types.List] = None,
750
+ weightSelectors: _arg_types.List | None = None,
751
751
  ) -> dictionary.Dictionary:
752
752
  """Returns a dictionary of results, keyed with the output names.
753
753
 
@@ -822,7 +822,7 @@ class Collection(element.Element):
822
822
 
823
823
  # TODO(user): Make ascending default to True
824
824
  @_utils.accept_opt_prefix('opt_ascending')
825
- def sort(self, prop: str, ascending: Optional[bool] = None) -> Any:
825
+ def sort(self, prop: str, ascending: bool | None = None) -> Any:
826
826
  """Sort a collection by the specified property.
827
827
 
828
828
  Args:
@@ -841,19 +841,19 @@ class Collection(element.Element):
841
841
 
842
842
  def style(
843
843
  self,
844
- color: Optional[_arg_types.String] = None,
844
+ color: _arg_types.String | None = None,
845
845
  # pylint: disable=invalid-name
846
- pointSize: Optional[_arg_types.Integer] = None,
847
- pointShape: Optional[_arg_types.String] = None,
846
+ pointSize: _arg_types.Integer | None = None,
847
+ pointShape: _arg_types.String | None = None,
848
848
  # pylint: enable=invalid-name
849
- width: Optional[_arg_types.Number] = None,
849
+ width: _arg_types.Number | None = None,
850
850
  # pylint: disable=invalid-name
851
- fillColor: Optional[_arg_types.String] = None,
852
- styleProperty: Optional[_arg_types.String] = None,
851
+ fillColor: _arg_types.String | None = None,
852
+ styleProperty: _arg_types.String | None = None,
853
853
  # pylint: enable=invalid-name
854
- neighborhood: Optional[_arg_types.Integer] = None,
854
+ neighborhood: _arg_types.Integer | None = None,
855
855
  # pylint: disable-next=invalid-name
856
- lineType: Optional[_arg_types.String] = None,
856
+ lineType: _arg_types.String | None = None,
857
857
  ) -> image.Image:
858
858
  """Draw a vector collection for visualization using a simple style language.
859
859
 
@@ -900,7 +900,7 @@ class Collection(element.Element):
900
900
  def toList(
901
901
  self,
902
902
  count: _arg_types.Integer,
903
- offset: Optional[_arg_types.Integer] = None,
903
+ offset: _arg_types.Integer | None = None,
904
904
  ) -> ee_list.List:
905
905
  """Returns the elements of a collection as a list.
906
906
 
@@ -918,7 +918,7 @@ class Collection(element.Element):
918
918
  def union(
919
919
  self,
920
920
  # pylint: disable-next=invalid-name
921
- maxError: Optional[_arg_types.ErrorMargin] = None,
921
+ maxError: _arg_types.ErrorMargin | None = None,
922
922
  ) -> featurecollection.FeatureCollection:
923
923
  """Returns a collection containing a single feature with a unioned geometry.
924
924
 
ee/computedobject.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable, Optional
5
+ from typing import Any, Callable
6
6
 
7
7
  from ee import _utils
8
8
  from ee import data
@@ -47,9 +47,9 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
47
47
  deterministic variable names for mapped functions, ensuring that nested
48
48
  mapping calls do not use the same variable name.
49
49
  """
50
- func: Optional[Any]
51
- args: Optional[dict[str, Any]]
52
- varName: Optional[str] # pylint: disable=g-bad-name
50
+ func: Any | None
51
+ args: dict[str, Any] | None
52
+ varName: str | None # pylint: disable=g-bad-name
53
53
 
54
54
  # Tell pytype not to worry about dynamic attributes.
55
55
  _HAS_DYNAMIC_ATTRIBUTES: bool = True
@@ -60,9 +60,9 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
60
60
  @_utils.accept_opt_prefix('opt_varName')
61
61
  def __init__(
62
62
  self,
63
- func: Optional[Any],
64
- args: Optional[dict[str, Any]],
65
- varName: Optional[str] = None, # pylint: disable=g-bad-name
63
+ func: Any | None,
64
+ args: dict[str, Any] | None,
65
+ varName: str | None = None, # pylint: disable=g-bad-name
66
66
  ):
67
67
  """Creates a computed object.
68
68
 
@@ -98,7 +98,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
98
98
  return hash(ComputedObject.freeze(self.__dict__))
99
99
 
100
100
  # pylint: disable-next=useless-parent-delegation
101
- def getInfo(self) -> Optional[Any]:
101
+ def getInfo(self) -> Any | None:
102
102
  """Fetch and return information about this object.
103
103
 
104
104
  Returns:
@@ -106,7 +106,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
106
106
  """
107
107
  return data.computeValue(self)
108
108
 
109
- def encode(self, encoder: Optional[Callable[..., Any]]) -> dict[str, Any]:
109
+ def encode(self, encoder: Callable[..., Any] | None) -> dict[str, Any]:
110
110
  """Encodes the object in a format compatible with Serializer."""
111
111
  if self.isVariable():
112
112
  return {
@@ -184,7 +184,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
184
184
 
185
185
  def __str__(self) -> str:
186
186
  """Writes out the object in a human-readable form."""
187
- return 'ee.%s(%s)' % (self.name(), serializer.toReadableJSON(self))
187
+ return 'ee.{}({})'.format(self.name(), serializer.toReadableJSON(self))
188
188
 
189
189
  def isVariable(self) -> bool:
190
190
  """Returns whether this computed object is a variable reference."""
ee/confusionmatrix.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """A wrapper for ConfusionMatrices."""
2
2
  from __future__ import annotations
3
3
 
4
- from typing import Any, Optional, Union
4
+ from typing import Any
5
5
 
6
6
  from ee import _arg_types
7
7
  from ee import apifunction
@@ -30,12 +30,12 @@ class ConfusionMatrix(computedobject.ComputedObject):
30
30
 
31
31
  def __init__(
32
32
  self,
33
- array: Union[
34
- ee_array.Array,
35
- _arg_types.ConfusionMatrix,
36
- computedobject.ComputedObject,
37
- ],
38
- order: Optional[_arg_types.List] = None,
33
+ array: (
34
+ ee_array.Array |
35
+ _arg_types.ConfusionMatrix |
36
+ computedobject.ComputedObject
37
+ ),
38
+ order: _arg_types.List | None = None,
39
39
  ):
40
40
  """Creates a ConfusionMatrix wrapper.
41
41
 
@@ -102,7 +102,7 @@ class ConfusionMatrix(computedobject.ComputedObject):
102
102
  self.name() + '.consumersAccuracy', self
103
103
  )
104
104
 
105
- def fscore(self, beta: Optional[_arg_types.Number] = None) -> ee_array.Array:
105
+ def fscore(self, beta: _arg_types.Number | None = None) -> ee_array.Array:
106
106
  """Returns the F-beta score for the confusion matrix.
107
107
 
108
108
  Args:
ee/customfunction.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable, Optional
5
+ from typing import Any, Callable
6
6
 
7
7
  from ee import computedobject
8
8
  from ee import ee_exception
@@ -75,7 +75,7 @@ class CustomFunction(function.Function, encodable.Encodable):
75
75
  return self._signature
76
76
 
77
77
  @staticmethod
78
- def variable(type_name: Optional[str], name: str) -> Any:
78
+ def variable(type_name: str | None, name: str) -> Any:
79
79
  """Returns a placeholder variable with a given name and EE type.
80
80
 
81
81
  Args:
ee/data.py CHANGED
@@ -3,13 +3,14 @@
3
3
  # Using lowercase function naming to match the JavaScript names.
4
4
  # pylint: disable=g-bad-name
5
5
 
6
+ from collections.abc import Iterator, Sequence
6
7
  import contextlib
7
8
  import json
8
9
  import platform
9
10
  import re
10
11
  import sys
11
12
  import threading
12
- from typing import Any, Callable, Iterator, Optional, Sequence, Union
13
+ from typing import Any, Callable, Optional, Union
13
14
  import uuid
14
15
  import warnings
15
16
 
@@ -254,7 +255,7 @@ def get_persistent_credentials() -> credentials_lib.Credentials:
254
255
  args = {}
255
256
  try:
256
257
  args = oauth.get_credentials_arguments()
257
- except IOError:
258
+ except OSError:
258
259
  pass
259
260
 
260
261
  if args.get('refresh_token'):
@@ -826,8 +827,7 @@ def _generate(func, list_key: str, **kwargs) -> Iterator[Any]:
826
827
  args = kwargs.copy()
827
828
  while True:
828
829
  response = func(**args)
829
- for obj in response.get(list_key, []):
830
- yield obj
830
+ yield from response.get(list_key, [])
831
831
  if _NEXT_PAGE_TOKEN_KEY not in response:
832
832
  break
833
833
  args['params'].update({'pageToken': response[_NEXT_PAGE_TOKEN_KEY]})
@@ -1262,8 +1262,9 @@ def makeThumbUrl(thumbId: dict[str, str]) -> str:
1262
1262
  Returns:
1263
1263
  A URL from which the thumbnail can be obtained.
1264
1264
  """
1265
- url = '%s/%s/%s:getPixels' % (_tile_base_url, _cloud_api_utils.VERSION,
1266
- thumbId['thumbid'])
1265
+ url = '{}/{}/{}:getPixels'.format(
1266
+ _tile_base_url, _cloud_api_utils.VERSION, thumbId['thumbid']
1267
+ )
1267
1268
  if _cloud_api_key:
1268
1269
  url += '?key=%s' % _cloud_api_key
1269
1270
  return url
@@ -1394,8 +1395,9 @@ def makeDownloadUrl(downloadId: dict[str, str]) -> str:
1394
1395
  Returns:
1395
1396
  A URL from which the download can be obtained.
1396
1397
  """
1397
- return '%s/%s/%s:getPixels' % (_tile_base_url, _cloud_api_utils.VERSION,
1398
- downloadId['docid'])
1398
+ return '{}/{}/{}:getPixels'.format(
1399
+ _tile_base_url, _cloud_api_utils.VERSION, downloadId['docid']
1400
+ )
1399
1401
 
1400
1402
 
1401
1403
  def getTableDownloadId(params: dict[str, Any]) -> dict[str, str]:
@@ -1456,8 +1458,9 @@ def makeTableDownloadUrl(downloadId: dict[str, str]) -> str:
1456
1458
  Returns:
1457
1459
  A Url from which the download can be obtained.
1458
1460
  """
1459
- return '%s/%s/%s:getFeatures' % (
1460
- _tile_base_url, _cloud_api_utils.VERSION, downloadId['docid'])
1461
+ return '{}/{}/{}:getFeatures'.format(
1462
+ _tile_base_url, _cloud_api_utils.VERSION, downloadId['docid']
1463
+ )
1461
1464
 
1462
1465
 
1463
1466
  def getAlgorithms() -> Any:
@@ -1941,9 +1944,7 @@ def _startIngestion(
1941
1944
  project=_get_projects_path(), body=request
1942
1945
  )
1943
1946
  else:
1944
- raise ee_exception.EEException(
1945
- '{} is not a valid import mode'.format(import_mode)
1946
- )
1947
+ raise ee_exception.EEException(f'{import_mode} is not a valid import mode')
1947
1948
 
1948
1949
  result = _execute_cloud_call(
1949
1950
  import_request,
@@ -2123,7 +2124,7 @@ def getAssetRootQuota(rootId: str) -> dict[str, Any]:
2123
2124
  """
2124
2125
  asset = getAsset(rootId)
2125
2126
  if 'quota' not in asset:
2126
- raise ee_exception.EEException('{} is not a root folder.'.format(rootId))
2127
+ raise ee_exception.EEException(f'{rootId} is not a root folder.')
2127
2128
  quota = asset['quota']
2128
2129
  # The quota fields are int64s, and int64s are represented as strings in
2129
2130
  # JSON. Turn them back.
ee/daterange.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """A wrapper for DateRanges."""
2
2
  from __future__ import annotations
3
3
 
4
- from typing import Any, Optional, Union
4
+ from typing import Any
5
5
 
6
6
  from ee import _arg_types
7
7
  from ee import apifunction
@@ -29,10 +29,10 @@ class DateRange(computedobject.ComputedObject):
29
29
 
30
30
  def __init__(
31
31
  self,
32
- start: Union[_arg_types.Date, _arg_types.DateRange],
33
- end: Optional[_arg_types.Date] = None,
32
+ start: _arg_types.Date | _arg_types.DateRange,
33
+ end: _arg_types.Date | None = None,
34
34
  # pylint: disable-next=invalid-name
35
- timeZone: Optional[_arg_types.String] = None,
35
+ timeZone: _arg_types.String | None = None,
36
36
  ):
37
37
  """Creates a DateRange wrapper.
38
38
 
@@ -85,7 +85,7 @@ class DateRange(computedobject.ComputedObject):
85
85
  return 'DateRange'
86
86
 
87
87
  def contains(
88
- self, other: Union[_arg_types.Date, _arg_types.DateRange]
88
+ self, other: _arg_types.Date | _arg_types.DateRange
89
89
  ) -> computedobject.ComputedObject:
90
90
  """Returns true if the given Date or DateRange is within this DateRange.
91
91
 
@@ -104,8 +104,8 @@ class DateRange(computedobject.ComputedObject):
104
104
  return apifunction.ApiFunction.call_(self.name() + '.end', self)
105
105
 
106
106
  def intersection(
107
- self, other: Union[_arg_types.Date, _arg_types.DateRange]
108
- ) -> 'DateRange':
107
+ self, other: _arg_types.Date | _arg_types.DateRange
108
+ ) -> DateRange:
109
109
  """Returns a DateRange that contains all the timespan of this and other.
110
110
 
111
111
  Args:
@@ -123,7 +123,7 @@ class DateRange(computedobject.ComputedObject):
123
123
  )
124
124
 
125
125
  def intersects(
126
- self, other: Union[_arg_types.Date, _arg_types.DateRange]
126
+ self, other: _arg_types.Date | _arg_types.DateRange
127
127
  ) -> computedobject.ComputedObject:
128
128
  """Returns true if the other DateRange has at least one time in common.
129
129
 
@@ -160,7 +160,7 @@ class DateRange(computedobject.ComputedObject):
160
160
  return apifunction.ApiFunction.call_('DateRange.unbounded')
161
161
 
162
162
  def union(
163
- self, other: Union[_arg_types.Date, _arg_types.DateRange]
163
+ self, other: _arg_types.Date | _arg_types.DateRange
164
164
  ) -> DateRange:
165
165
  """Returns a DateRange that contains all points in this and other.
166
166
 
ee/deprecation.py CHANGED
@@ -7,7 +7,7 @@ import datetime
7
7
  import functools
8
8
  import inspect
9
9
  import json
10
- from typing import Any, Callable, Optional
10
+ from typing import Any, Callable
11
11
  import urllib
12
12
  import warnings
13
13
 
@@ -15,7 +15,7 @@ _DEPRECATED_OBJECT = 'earthengine-stac/catalog/catalog_deprecated.json'
15
15
  _DEPRECATED_ASSETS_URL = f'https://storage.googleapis.com/{_DEPRECATED_OBJECT}'
16
16
 
17
17
  # Deprecation warnings are per-asset, per-initialization.
18
- deprecated_assets: dict[str, DeprecatedAsset] = None
18
+ deprecated_assets: dict[str, DeprecatedAsset] = dict()
19
19
 
20
20
 
21
21
  def Deprecated(message: str):
@@ -36,7 +36,7 @@ def Deprecated(message: str):
36
36
  @functools.wraps(func)
37
37
  def Wrapper(*args, **kwargs):
38
38
  warnings.warn_explicit(
39
- '%s() is deprecated: %s' % (func.__name__, message),
39
+ '{}() is deprecated: {}'.format(func.__name__, message),
40
40
  category=DeprecationWarning,
41
41
  filename=func.__code__.co_filename,
42
42
  lineno=func.__code__.co_firstlineno + 1,
@@ -67,14 +67,14 @@ class DeprecatedAsset:
67
67
  """Class for keeping track of a single deprecated asset."""
68
68
 
69
69
  id: str
70
- replacement_id: Optional[str]
71
- removal_date: Optional[datetime.datetime]
72
- learn_more_url: Optional[str]
70
+ replacement_id: str | None
71
+ removal_date: datetime.datetime | None
72
+ learn_more_url: str | None
73
73
 
74
74
  has_warning_been_issued: bool = False
75
75
 
76
76
  @classmethod
77
- def _ParseDateString(cls, date_str: str) -> Optional[datetime.datetime]:
77
+ def _ParseDateString(cls, date_str: str) -> datetime.datetime | None:
78
78
  try:
79
79
  # We can't use `datetime.datetime.fromisoformat` because it's behavior
80
80
  # changes by Python version.
@@ -87,8 +87,10 @@ class DeprecatedAsset:
87
87
  removal_date = stac_link.get('gee:removal_date')
88
88
  if removal_date is not None:
89
89
  removal_date = cls._ParseDateString(removal_date)
90
+ title = stac_link.get('title')
91
+ assert isinstance(title, str)
90
92
  return DeprecatedAsset(
91
- id=stac_link.get('title'),
93
+ id=title,
92
94
  replacement_id=stac_link.get('gee:replacement_id'),
93
95
  removal_date=removal_date,
94
96
  learn_more_url=stac_link.get('gee:learn_more_url'),
@@ -139,7 +141,7 @@ def InitializeDeprecatedAssets() -> None:
139
141
 
140
142
  def _InitializeDeprecatedAssetsInternal() -> None:
141
143
  global deprecated_assets
142
- if deprecated_assets is not None:
144
+ if deprecated_assets:
143
145
  return
144
146
  _UnfilterDeprecationWarnings()
145
147
 
@@ -153,7 +155,7 @@ def _InitializeDeprecatedAssetsInternal() -> None:
153
155
 
154
156
  def Reset() -> None:
155
157
  global deprecated_assets
156
- deprecated_assets = None
158
+ deprecated_assets = dict()
157
159
 
158
160
 
159
161
  def _FetchDataCatalogStac() -> dict[str, Any]:
@@ -164,7 +166,7 @@ def _FetchDataCatalogStac() -> dict[str, Any]:
164
166
  return json.loads(response)
165
167
 
166
168
 
167
- def _GetStringFromObject(obj: Any) -> Optional[str]:
169
+ def _GetStringFromObject(obj: Any) -> str | None:
168
170
  if isinstance(obj, str):
169
171
  return obj
170
172
  return None
ee/deserializer.py CHANGED
@@ -107,14 +107,14 @@ def _decodeValue(json_obj: Any, named_values: dict[str, Any]) -> Any:
107
107
  else:
108
108
  func = _decodeValue(json_obj['function'], named_values)
109
109
  if 'arguments' in json_obj:
110
- args = dict((key, _decodeValue(value, named_values))
111
- for (key, value) in json_obj['arguments'].items())
110
+ args = {key: _decodeValue(value, named_values)
111
+ for (key, value) in json_obj['arguments'].items()}
112
112
  else:
113
113
  args = {}
114
114
  return _invocation(func, args)
115
115
  elif type_name == 'Dictionary':
116
- return dict((key, _decodeValue(value, named_values))
117
- for (key, value) in json_obj['value'].items())
116
+ return {key: _decodeValue(value, named_values)
117
+ for (key, value) in json_obj['value'].items()}
118
118
  elif type_name == 'Function':
119
119
  body = _decodeValue(json_obj['body'], named_values)
120
120
  signature = {
@@ -180,7 +180,7 @@ def decodeCloudApi(json_obj: dict[str, Any]) -> Any:
180
180
  def lookup(reference, kind):
181
181
  if reference not in decoded:
182
182
  if reference not in json_obj['values']:
183
- raise ee_exception.EEException('Cannot find %s %s' % (reference, kind))
183
+ raise ee_exception.EEException('Cannot find {} {}'.format(reference, kind))
184
184
  decoded[reference] = decode_node(json_obj['values'][reference])
185
185
  return decoded[reference]
186
186