earthengine-api 1.5.13rc0__py3-none-any.whl → 1.7.4__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 (102) hide show
  1. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/METADATA +3 -3
  2. earthengine_api-1.7.4.dist-info/RECORD +109 -0
  3. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/WHEEL +1 -1
  4. ee/__init__.py +29 -28
  5. ee/_arg_types.py +7 -6
  6. ee/_cloud_api_utils.py +95 -78
  7. ee/_helpers.py +17 -13
  8. ee/_state.py +105 -0
  9. ee/_utils.py +2 -1
  10. ee/apifunction.py +21 -19
  11. ee/apitestcase.py +33 -38
  12. ee/batch.py +87 -77
  13. ee/blob.py +10 -12
  14. ee/classifier.py +57 -59
  15. ee/cli/commands.py +178 -114
  16. ee/cli/eecli.py +1 -1
  17. ee/cli/utils.py +61 -42
  18. ee/clusterer.py +39 -41
  19. ee/collection.py +64 -54
  20. ee/computedobject.py +19 -16
  21. ee/confusionmatrix.py +9 -9
  22. ee/customfunction.py +13 -12
  23. ee/data.py +220 -322
  24. ee/daterange.py +10 -10
  25. ee/deprecation.py +21 -13
  26. ee/deserializer.py +25 -20
  27. ee/dictionary.py +11 -11
  28. ee/ee_array.py +22 -20
  29. ee/ee_date.py +23 -23
  30. ee/ee_list.py +15 -16
  31. ee/ee_number.py +11 -21
  32. ee/ee_string.py +24 -32
  33. ee/ee_types.py +4 -4
  34. ee/element.py +15 -15
  35. ee/encodable.py +7 -4
  36. ee/errormargin.py +4 -4
  37. ee/feature.py +68 -71
  38. ee/featurecollection.py +41 -40
  39. ee/filter.py +90 -92
  40. ee/function.py +8 -8
  41. ee/geometry.py +95 -93
  42. ee/image.py +238 -236
  43. ee/image_converter.py +4 -4
  44. ee/imagecollection.py +30 -27
  45. ee/join.py +13 -15
  46. ee/kernel.py +55 -57
  47. ee/mapclient.py +9 -9
  48. ee/model.py +29 -31
  49. ee/oauth.py +76 -63
  50. ee/pixeltype.py +6 -6
  51. ee/projection.py +5 -4
  52. ee/reducer.py +41 -41
  53. ee/serializer.py +14 -14
  54. ee/table_converter.py +7 -6
  55. ee/terrain.py +7 -9
  56. ee/tests/_cloud_api_utils_test.py +21 -6
  57. ee/tests/_helpers_test.py +57 -4
  58. ee/tests/_state_test.py +49 -0
  59. ee/tests/algorithms.json +85 -2
  60. ee/tests/apifunction_test.py +5 -5
  61. ee/tests/batch_test.py +135 -57
  62. ee/tests/blob_test.py +5 -5
  63. ee/tests/classifier_test.py +3 -3
  64. ee/tests/clusterer_test.py +3 -3
  65. ee/tests/collection_test.py +48 -13
  66. ee/tests/confusionmatrix_test.py +3 -3
  67. ee/tests/data_test.py +484 -55
  68. ee/tests/daterange_test.py +4 -4
  69. ee/tests/deprecation_test.py +6 -4
  70. ee/tests/deserializer_test.py +64 -5
  71. ee/tests/dictionary_test.py +12 -12
  72. ee/tests/ee_array_test.py +3 -3
  73. ee/tests/ee_date_test.py +4 -4
  74. ee/tests/ee_list_test.py +3 -3
  75. ee/tests/ee_number_test.py +75 -30
  76. ee/tests/ee_string_test.py +11 -3
  77. ee/tests/ee_test.py +40 -22
  78. ee/tests/element_test.py +2 -2
  79. ee/tests/errormargin_test.py +1 -1
  80. ee/tests/feature_test.py +10 -10
  81. ee/tests/featurecollection_test.py +3 -3
  82. ee/tests/filter_test.py +4 -4
  83. ee/tests/function_test.py +5 -5
  84. ee/tests/geometry_point_test.py +3 -3
  85. ee/tests/geometry_test.py +93 -52
  86. ee/tests/image_converter_test.py +1 -3
  87. ee/tests/image_test.py +3 -3
  88. ee/tests/imagecollection_test.py +3 -3
  89. ee/tests/join_test.py +3 -3
  90. ee/tests/kernel_test.py +7 -3
  91. ee/tests/model_test.py +17 -5
  92. ee/tests/oauth_test.py +189 -7
  93. ee/tests/pixeltype_test.py +6 -7
  94. ee/tests/projection_test.py +5 -6
  95. ee/tests/reducer_test.py +16 -3
  96. ee/tests/serializer_test.py +39 -12
  97. ee/tests/table_converter_test.py +51 -7
  98. ee/tests/terrain_test.py +11 -3
  99. earthengine_api-1.5.13rc0.dist-info/RECORD +0 -107
  100. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/entry_points.txt +0 -0
  101. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/licenses/LICENSE +0 -0
  102. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/top_level.txt +0 -0
ee/collection.py CHANGED
@@ -5,8 +5,9 @@ This class is never intended to be instantiated by the user.
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ from collections.abc import Callable
8
9
  import datetime
9
- from typing import Any, Callable, Dict, Optional, Type, Union
10
+ from typing import Any, Generic, TypeVar
10
11
 
11
12
  from ee import _arg_types
12
13
  from ee import _utils
@@ -26,8 +27,14 @@ from ee import function
26
27
  from ee import geometry as ee_geometry
27
28
  from ee import image
28
29
 
30
+ # TODO: Remove this TypeVar and replace with typing.Self once
31
+ # Python 3.11 is the minimum version.
32
+ T = TypeVar('T', bound='Collection')
29
33
 
30
- class Collection(element.Element):
34
+ ElementType = TypeVar('ElementType')
35
+
36
+
37
+ class Collection(Generic[ElementType], element.Element):
31
38
  """Base class for ImageCollection and FeatureCollection."""
32
39
 
33
40
  _initialized = False
@@ -37,8 +44,8 @@ class Collection(element.Element):
37
44
  def __init__(
38
45
  self,
39
46
  func: function.Function,
40
- args: Dict[str, Any],
41
- varName: Optional[str] = None, # pylint: disable=invalid-name
47
+ args: dict[str, Any],
48
+ varName: str | None = None, # pylint: disable=invalid-name
42
49
  ):
43
50
  """Constructs a collection by initializing its ComputedObject."""
44
51
  super().__init__(func, args, varName)
@@ -198,7 +205,7 @@ class Collection(element.Element):
198
205
 
199
206
  # pylint: disable-next=redefined-builtin
200
207
  def aggregate_product(self, property: _arg_types.String) -> ee_number.Number:
201
- """Returns the product of the values ofthe selected property.
208
+ """Returns the product of the values of the selected property.
202
209
 
203
210
  Aggregates over a given property of the objects in a collection, calculating
204
211
  the product of the values of the selected property.
@@ -320,8 +327,8 @@ class Collection(element.Element):
320
327
  def bounds(
321
328
  self,
322
329
  # pylint: disable-next=invalid-name
323
- maxError: Optional[_arg_types.ErrorMargin] = None,
324
- proj: Optional[_arg_types.Projection] = None,
330
+ maxError: _arg_types.ErrorMargin | None = None,
331
+ proj: _arg_types.Projection | None = None,
325
332
  ) -> ee_geometry.Geometry:
326
333
  """Returns the bounding rectangle of the geometry.
327
334
 
@@ -339,8 +346,8 @@ class Collection(element.Element):
339
346
  def distance(
340
347
  self,
341
348
  # pylint: disable=invalid-name
342
- searchRadius: Optional[_arg_types.Number] = None,
343
- maxError: Optional[_arg_types.Number] = None,
349
+ searchRadius: _arg_types.Number | None = None,
350
+ maxError: _arg_types.Number | None = None,
344
351
  # pylint: enable=invalid-name
345
352
  ) -> image.Image:
346
353
  """Returns a distance image for the collection.
@@ -368,7 +375,7 @@ class Collection(element.Element):
368
375
  )
369
376
 
370
377
  def distinct(
371
- self, properties: Union[_arg_types.String, _arg_types.List]
378
+ self, properties: _arg_types.String | _arg_types.List
372
379
  ) -> featurecollection.FeatureCollection:
373
380
  """Returns a collection with duplicates removed.
374
381
 
@@ -389,8 +396,8 @@ class Collection(element.Element):
389
396
  self,
390
397
  color: _arg_types.String,
391
398
  # pylint: disable=invalid-name
392
- pointRadius: Optional[_arg_types.Integer] = None,
393
- strokeWidth: Optional[_arg_types.Integer] = None,
399
+ pointRadius: _arg_types.Integer | None = None,
400
+ strokeWidth: _arg_types.Integer | None = None,
394
401
  # pylint: enable=invalid-name
395
402
  ) -> image.Image:
396
403
  """Returns a painted image of a vector collection for visualization.
@@ -409,7 +416,7 @@ class Collection(element.Element):
409
416
  )
410
417
 
411
418
  @staticmethod
412
- def elementType() -> Type[element.Element]:
419
+ def elementType() -> type[element.Element]:
413
420
  """Returns the type of the collection's elements."""
414
421
  return element.Element
415
422
 
@@ -417,7 +424,7 @@ class Collection(element.Element):
417
424
  self,
418
425
  actual: _arg_types.String,
419
426
  predicted: _arg_types.String,
420
- order: Optional[_arg_types.List] = None,
427
+ order: _arg_types.List | None = None,
421
428
  ) -> confusionmatrix.ConfusionMatrix:
422
429
  """Returns a 2D error matrix for a collection.
423
430
 
@@ -442,7 +449,7 @@ class Collection(element.Element):
442
449
  'Collection.errorMatrix', self, actual, predicted, order
443
450
  )
444
451
 
445
- def filter(self, new_filter: Union[str, ee_filter.Filter]) -> Any:
452
+ def filter(self: T, new_filter: str | ee_filter.Filter) -> T:
446
453
  """Apply a filter to this collection.
447
454
 
448
455
  Args:
@@ -459,8 +466,8 @@ class Collection(element.Element):
459
466
 
460
467
  @deprecation.CanUseDeprecated
461
468
  def filterMetadata(
462
- self, name: str, operator: str, value: Union[int, str]
463
- ) -> Any:
469
+ self: T, name: str, operator: str, value: int | str
470
+ ) -> T:
464
471
  """Shortcut to add a metadata filter to a collection.
465
472
 
466
473
  This is equivalent to self.filter(Filter().metadata(...)).
@@ -468,7 +475,7 @@ class Collection(element.Element):
468
475
  Args:
469
476
  name: Name of a property to filter.
470
477
  operator: Name of a comparison operator as defined
471
- by FilterCollection. Possible values are: "equals", "less_than",
478
+ by FilterCollection. Possible values are: "equals", "less_than",
472
479
  "greater_than", "not_equals", "not_less_than", "not_greater_than",
473
480
  "starts_with", "ends_with", "not_starts_with", "not_ends_with",
474
481
  "contains", "not_contains".
@@ -480,8 +487,13 @@ class Collection(element.Element):
480
487
  return self.filter(ee_filter.Filter.metadata_(name, operator, value))
481
488
 
482
489
  def filterBounds(
483
- self, geometry: Union[Dict[str, Any], ee_geometry.Geometry]
484
- ) -> Any:
490
+ self: T,
491
+ geometry: (
492
+ dict[str, Any]
493
+ | ee_geometry.Geometry
494
+ | featurecollection.FeatureCollection
495
+ ),
496
+ ) -> T:
485
497
  """Shortcut to add a geometry filter to a collection.
486
498
 
487
499
  Items in the collection with a footprint that fails to intersect
@@ -505,12 +517,10 @@ class Collection(element.Element):
505
517
  # TODO(user): Any --> DateRange
506
518
  @_utils.accept_opt_prefix('opt_end')
507
519
  def filterDate(
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,
513
- ) -> Any:
520
+ self: T,
521
+ start: datetime.datetime | ee_date.Date | int | str | Any,
522
+ end: None | (datetime.datetime | ee_date.Date | int | str | Any) = None,
523
+ ) -> T:
514
524
  """Shortcut to filter a collection with a date range.
515
525
 
516
526
  Items in the collection with a system:time_start property that doesn't
@@ -529,7 +539,7 @@ class Collection(element.Element):
529
539
  """
530
540
  return self.filter(ee_filter.Filter.date(start, end))
531
541
 
532
- def first(self) -> element.Element:
542
+ def first(self) -> ElementType:
533
543
  """Returns the first entry from a given collection."""
534
544
 
535
545
  return apifunction.ApiFunction.call_('Collection.first', self)
@@ -542,7 +552,7 @@ class Collection(element.Element):
542
552
  def geometry(
543
553
  self,
544
554
  # pylint: disable-next=invalid-name
545
- maxError: Optional[_arg_types.ErrorMargin] = None,
555
+ maxError: _arg_types.ErrorMargin | None = None,
546
556
  ) -> ee_geometry.Geometry:
547
557
  """Returns the geometry of a collection.
548
558
 
@@ -563,7 +573,7 @@ class Collection(element.Element):
563
573
  )
564
574
 
565
575
  # pylint: disable-next=useless-parent-delegation
566
- def getInfo(self) -> Optional[Any]:
576
+ def getInfo(self) -> Any | None:
567
577
  """Returns all the known information about this collection.
568
578
 
569
579
  This function makes a REST call to to retrieve all the known information
@@ -579,7 +589,7 @@ class Collection(element.Element):
579
589
  return super().getInfo()
580
590
 
581
591
  def iterate(
582
- self, algorithm: Callable[[Any, Any], Any], first: Optional[Any] = None
592
+ self, algorithm: Callable[[Any, Any], Any], first: Any | None = None
583
593
  ) -> Any:
584
594
  """Iterates over a collection with an algorithm.
585
595
 
@@ -610,8 +620,8 @@ class Collection(element.Element):
610
620
  def limit(
611
621
  self,
612
622
  maximum: int,
613
- prop: Optional[str] = None,
614
- ascending: Optional[bool] = None,
623
+ prop: str | None = None,
624
+ ascending: bool | None = None,
615
625
  ) -> Collection:
616
626
  """Limit a collection to the specified number of elements.
617
627
 
@@ -639,9 +649,9 @@ class Collection(element.Element):
639
649
  def loadTable(
640
650
  # pylint: disable=invalid-name
641
651
  tableId: _arg_types.String,
642
- geometryColumn: Optional[_arg_types.String] = None,
652
+ geometryColumn: _arg_types.String | None = None,
643
653
  # pylint: enable=invalid-name
644
- version: Optional[_arg_types.Integer] = None,
654
+ version: _arg_types.Integer | None = None,
645
655
  ) -> featurecollection.FeatureCollection:
646
656
  """Returns a Collection of features from a specified table.
647
657
 
@@ -660,10 +670,10 @@ class Collection(element.Element):
660
670
  # TODO(user): Can dropNulls default to False?
661
671
  @_utils.accept_opt_prefix('opt_dropNulls')
662
672
  def map(
663
- self,
673
+ self: T,
664
674
  algorithm: Callable[[Any], Any],
665
- dropNulls: Optional[bool] = None, # pylint: disable=invalid-name
666
- ) -> Any:
675
+ dropNulls: bool | None = None, # pylint: disable=invalid-name
676
+ ) -> T:
667
677
  """Maps an algorithm over a collection.
668
678
 
669
679
  Args:
@@ -714,11 +724,11 @@ class Collection(element.Element):
714
724
  def randomColumn(
715
725
  self,
716
726
  # 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,
727
+ columnName: _arg_types.String | None = None,
728
+ seed: _arg_types.Integer | None = None,
729
+ distribution: _arg_types.String | None = None,
720
730
  # pylint: disable-next=invalid-name
721
- rowKeys: Optional[_arg_types.List] = None,
731
+ rowKeys: _arg_types.List | None = None,
722
732
  ) -> featurecollection.FeatureCollection:
723
733
  """Returns a collection with a random column added to each feature.
724
734
 
@@ -747,7 +757,7 @@ class Collection(element.Element):
747
757
  reducer: _arg_types.Reducer,
748
758
  selectors: _arg_types.List,
749
759
  # pylint: disable=invalid-name
750
- weightSelectors: Optional[_arg_types.List] = None,
760
+ weightSelectors: _arg_types.List | None = None,
751
761
  ) -> dictionary.Dictionary:
752
762
  """Returns a dictionary of results, keyed with the output names.
753
763
 
@@ -822,12 +832,12 @@ class Collection(element.Element):
822
832
 
823
833
  # TODO(user): Make ascending default to True
824
834
  @_utils.accept_opt_prefix('opt_ascending')
825
- def sort(self, prop: str, ascending: Optional[bool] = None) -> Any:
835
+ def sort(self: T, prop: str, ascending: bool | None = None) -> T:
826
836
  """Sort a collection by the specified property.
827
837
 
828
838
  Args:
829
839
  prop: The property to sort by.
830
- ascending: Whether to sort in ascending or descending order. The default
840
+ ascending: Whether to sort in ascending or descending order. The default
831
841
  is true (ascending).
832
842
 
833
843
  Returns:
@@ -841,19 +851,19 @@ class Collection(element.Element):
841
851
 
842
852
  def style(
843
853
  self,
844
- color: Optional[_arg_types.String] = None,
854
+ color: _arg_types.String | None = None,
845
855
  # pylint: disable=invalid-name
846
- pointSize: Optional[_arg_types.Integer] = None,
847
- pointShape: Optional[_arg_types.String] = None,
856
+ pointSize: _arg_types.Integer | None = None,
857
+ pointShape: _arg_types.String | None = None,
848
858
  # pylint: enable=invalid-name
849
- width: Optional[_arg_types.Number] = None,
859
+ width: _arg_types.Number | None = None,
850
860
  # pylint: disable=invalid-name
851
- fillColor: Optional[_arg_types.String] = None,
852
- styleProperty: Optional[_arg_types.String] = None,
861
+ fillColor: _arg_types.String | None = None,
862
+ styleProperty: _arg_types.String | None = None,
853
863
  # pylint: enable=invalid-name
854
- neighborhood: Optional[_arg_types.Integer] = None,
864
+ neighborhood: _arg_types.Integer | None = None,
855
865
  # pylint: disable-next=invalid-name
856
- lineType: Optional[_arg_types.String] = None,
866
+ lineType: _arg_types.String | None = None,
857
867
  ) -> image.Image:
858
868
  """Draw a vector collection for visualization using a simple style language.
859
869
 
@@ -900,7 +910,7 @@ class Collection(element.Element):
900
910
  def toList(
901
911
  self,
902
912
  count: _arg_types.Integer,
903
- offset: Optional[_arg_types.Integer] = None,
913
+ offset: _arg_types.Integer | None = None,
904
914
  ) -> ee_list.List:
905
915
  """Returns the elements of a collection as a list.
906
916
 
@@ -918,7 +928,7 @@ class Collection(element.Element):
918
928
  def union(
919
929
  self,
920
930
  # pylint: disable-next=invalid-name
921
- maxError: Optional[_arg_types.ErrorMargin] = None,
931
+ maxError: _arg_types.ErrorMargin | None = None,
922
932
  ) -> featurecollection.FeatureCollection:
923
933
  """Returns a collection containing a single feature with a unioned geometry.
924
934
 
ee/computedobject.py CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable, Dict, Optional
5
+ from collections.abc import Callable
6
+ from typing import Any
6
7
 
7
8
  from ee import _utils
8
9
  from ee import data
@@ -38,18 +39,18 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
38
39
  necessary to interact well with the rest of the API.
39
40
 
40
41
  ComputedObjects come in two flavors:
41
- 1. If func != null and args != null, the ComputedObject is encoded as an
42
- invocation of func with args.
43
- 2. If func == null and args == null, the ComputedObject is a variable
42
+ 1. If func is not None and args is not None, the ComputedObject is encoded as
43
+ an invocation of func with args.
44
+ 2. If func is None and args is None, the ComputedObject is a variable
44
45
  reference. The variable name is stored in its varName member. Note that
45
- in this case, varName may still be null; this allows the name to be
46
+ in this case, varName may still be None; this allows the name to be
46
47
  deterministically generated at a later time. This is used to generate
47
48
  deterministic variable names for mapped functions, ensuring that nested
48
49
  mapping calls do not use the same variable name.
49
50
  """
50
- func: Optional[Any]
51
- args: Optional[Dict[str, Any]]
52
- varName: Optional[str] # pylint: disable=g-bad-name
51
+ func: Any | None
52
+ args: dict[str, Any] | None
53
+ varName: str | None # pylint: disable=g-bad-name
53
54
 
54
55
  # Tell pytype not to worry about dynamic attributes.
55
56
  _HAS_DYNAMIC_ATTRIBUTES: bool = True
@@ -60,9 +61,9 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
60
61
  @_utils.accept_opt_prefix('opt_varName')
61
62
  def __init__(
62
63
  self,
63
- func: Optional[Any],
64
- args: Optional[Dict[str, Any]],
65
- varName: Optional[str] = None, # pylint: disable=g-bad-name
64
+ func: Any | None,
65
+ args: dict[str, Any] | None,
66
+ varName: str | None = None, # pylint: disable=g-bad-name
66
67
  ):
67
68
  """Creates a computed object.
68
69
 
@@ -98,7 +99,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
98
99
  return hash(ComputedObject.freeze(self.__dict__))
99
100
 
100
101
  # pylint: disable-next=useless-parent-delegation
101
- def getInfo(self) -> Optional[Any]:
102
+ def getInfo(self) -> Any | None:
102
103
  """Fetch and return information about this object.
103
104
 
104
105
  Returns:
@@ -106,7 +107,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
106
107
  """
107
108
  return data.computeValue(self)
108
109
 
109
- def encode(self, encoder: Optional[Callable[..., Any]]) -> Dict[str, Any]:
110
+ def encode(self, encoder: Callable[..., Any] | None) -> dict[str, Any]:
110
111
  """Encodes the object in a format compatible with Serializer."""
111
112
  if self.isVariable():
112
113
  return {
@@ -135,7 +136,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
135
136
  key: func
136
137
  }
137
138
 
138
- def encode_cloud_value(self, encoder: Any) -> Dict[str, Any]:
139
+ def encode_cloud_value(self, encoder: Any) -> dict[str, Any]:
139
140
  if self.isVariable():
140
141
  ref = self.varName
141
142
  if ref is None and isinstance(
@@ -160,7 +161,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
160
161
  invocation = self.func.encode_cloud_invocation(encoder)
161
162
 
162
163
  # Encode all arguments recursively.
163
- encoded_args: Dict[str, Any] = {}
164
+ encoded_args: dict[str, Any] = {}
164
165
  for name in sorted(self.args):
165
166
  value = self.args[name]
166
167
  if value is not None:
@@ -184,7 +185,7 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
184
185
 
185
186
  def __str__(self) -> str:
186
187
  """Writes out the object in a human-readable form."""
187
- return 'ee.%s(%s)' % (self.name(), serializer.toReadableJSON(self))
188
+ return f'ee.{self.name()}({serializer.toReadableJSON(self)})'
188
189
 
189
190
  def isVariable(self) -> bool:
190
191
  """Returns whether this computed object is a variable reference."""
@@ -233,9 +234,11 @@ class ComputedObject(encodable.Encodable, metaclass=ComputedObjectMetaclass):
233
234
  return obj
234
235
  else:
235
236
  result = cls.__new__(cls) # pylint: disable=no-value-for-parameter
237
+ # pylint: disable=attribute-error
236
238
  result.func = obj.func
237
239
  result.args = obj.args
238
240
  result.varName = obj.varName
241
+ # pylint: enable=attribute-error
239
242
  return result
240
243
 
241
244
  @staticmethod
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, Dict, 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
 
@@ -57,7 +57,7 @@ class ConfusionMatrix(computedobject.ComputedObject):
57
57
  super().__init__(array.func, array.args, array.varName)
58
58
  return
59
59
 
60
- args: Dict[str, Any] = {'array': array}
60
+ args: dict[str, Any] = {'array': array}
61
61
  if order is not None:
62
62
  args['order'] = order
63
63
 
@@ -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,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable, Dict, Optional
5
+ from collections.abc import Callable
6
+ from typing import Any
6
7
 
7
8
  from ee import computedobject
8
9
  from ee import ee_exception
@@ -20,9 +21,9 @@ from ee import serializer
20
21
  class CustomFunction(function.Function, encodable.Encodable):
21
22
  """An object representing a custom EE Function."""
22
23
  _body: Any
23
- _signature: Dict[str, Any]
24
+ _signature: dict[str, Any]
24
25
 
25
- def __init__(self, signature: Dict[str, Any], body: Any):
26
+ def __init__(self, signature: dict[str, Any], body: Any):
26
27
  """Creates a function defined by a given expression with unbound variables.
27
28
 
28
29
  The expression is created by evaluating the given function
@@ -47,14 +48,14 @@ class CustomFunction(function.Function, encodable.Encodable):
47
48
  # The expression to evaluate.
48
49
  self._body = body(*variables)
49
50
 
50
- def encode(self, encoder: Callable[[Any], Any]) -> Dict[str, Any]:
51
+ def encode(self, encoder: Callable[[Any], Any]) -> dict[str, Any]:
51
52
  return {
52
53
  'type': 'Function',
53
54
  'argumentNames': [x['name'] for x in self._signature['args']],
54
55
  'body': encoder(self._body)
55
56
  }
56
57
 
57
- def encode_cloud_value(self, encoder: Callable[[Any], Any]) -> Dict[str, Any]:
58
+ def encode_cloud_value(self, encoder: Callable[[Any], Any]) -> dict[str, Any]:
58
59
  return {
59
60
  'functionDefinitionValue': {
60
61
  'argumentNames': [x['name'] for x in self._signature['args']],
@@ -62,20 +63,20 @@ class CustomFunction(function.Function, encodable.Encodable):
62
63
  }
63
64
  }
64
65
 
65
- def encode_invocation(self, encoder: Callable[[Any], Any]) -> Dict[str, Any]:
66
+ def encode_invocation(self, encoder: Callable[[Any], Any]) -> dict[str, Any]:
66
67
  return self.encode(encoder)
67
68
 
68
69
  def encode_cloud_invocation(
69
70
  self, encoder: Callable[[Any], Any]
70
- ) -> Dict[str, Any]:
71
+ ) -> dict[str, Any]:
71
72
  return {'functionReference': encoder(self)}
72
73
 
73
- def getSignature(self) -> Dict[str, Any]:
74
+ def getSignature(self) -> dict[str, Any]:
74
75
  """Returns a description of the interface provided by this function."""
75
76
  return self._signature
76
77
 
77
78
  @staticmethod
78
- def variable(type_name: Optional[str], name: str) -> Any:
79
+ def variable(type_name: str | None, name: str) -> Any:
79
80
  """Returns a placeholder variable with a given name and EE type.
80
81
 
81
82
  Args:
@@ -171,19 +172,19 @@ class CustomFunction(function.Function, encodable.Encodable):
171
172
  return CountNodes(expression['values'].values())
172
173
 
173
174
  # There are three function building phases, which each call body():
174
- # 1 - Check Return. The constructor verifies that body() returns a result,
175
+ # 1 - Check Return. The constructor verifies that body() returns a result,
175
176
  # but does not try to serialize the result. If the function tries to use
176
177
  # unbound variables (e.g., using .getInfo() or print()), ComputedObject will
177
178
  # throw an exception when these calls try to serialize themselves, so that
178
179
  # unbound variables are not passed in server calls.
179
- # 2 - Count Functions. We serialize the result here. At this point all
180
+ # 2 - Count Functions. We serialize the result here. At this point all
180
181
  # variables must have names for serialization to succeed, but we don't yet
181
182
  # know the correct function depth. So we serialize with unbound_name set to
182
183
  # '<unbound>', which should silently succeed. If this does end up in server
183
184
  # calls, the function is very unusual: the first call doesn't use unbound
184
185
  # variables but the second call does. In this rare case we will return
185
186
  # server errors complaining about <unbound>.
186
- # 3 - Final Serialize. Finally, the constructor calls body() with the
187
+ # 3 - Final Serialize. Finally, the constructor calls body() with the
187
188
  # correct, depth-dependent names, which are used when the CustomFunction
188
189
  # is serialized and sent to the server.
189
190
  serialized_body = serializer.encode(