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/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, Dict, 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
 
@@ -58,7 +58,7 @@ class DateRange(computedobject.ComputedObject):
58
58
  super().__init__(start.func, start.args, start.varName)
59
59
  return
60
60
 
61
- args: Dict[str, Any] = {'start': start}
61
+ args: dict[str, Any] = {'start': start}
62
62
  if end is not None:
63
63
  args['end'] = end
64
64
  if timeZone is not None:
@@ -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
@@ -2,12 +2,13 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from collections.abc import Callable
5
6
  import dataclasses
6
7
  import datetime
7
8
  import functools
8
9
  import inspect
9
10
  import json
10
- from typing import Any, Callable, Dict, Optional
11
+ from typing import Any
11
12
  import urllib
12
13
  import warnings
13
14
 
@@ -15,7 +16,7 @@ _DEPRECATED_OBJECT = 'earthengine-stac/catalog/catalog_deprecated.json'
15
16
  _DEPRECATED_ASSETS_URL = f'https://storage.googleapis.com/{_DEPRECATED_OBJECT}'
16
17
 
17
18
  # Deprecation warnings are per-asset, per-initialization.
18
- deprecated_assets: Dict[str, DeprecatedAsset] = None
19
+ deprecated_assets: dict[str, DeprecatedAsset] = dict()
19
20
 
20
21
 
21
22
  def Deprecated(message: str):
@@ -36,7 +37,7 @@ def Deprecated(message: str):
36
37
  @functools.wraps(func)
37
38
  def Wrapper(*args, **kwargs):
38
39
  warnings.warn_explicit(
39
- '%s() is deprecated: %s' % (func.__name__, message),
40
+ f'{func.__name__}() is deprecated: {message}',
40
41
  category=DeprecationWarning,
41
42
  filename=func.__code__.co_filename,
42
43
  lineno=func.__code__.co_firstlineno + 1,
@@ -67,14 +68,14 @@ class DeprecatedAsset:
67
68
  """Class for keeping track of a single deprecated asset."""
68
69
 
69
70
  id: str
70
- replacement_id: Optional[str]
71
- removal_date: Optional[datetime.datetime]
72
- learn_more_url: Optional[str]
71
+ replacement_id: str | None
72
+ removal_date: datetime.datetime | None
73
+ learn_more_url: str | None
73
74
 
74
75
  has_warning_been_issued: bool = False
75
76
 
76
77
  @classmethod
77
- def _ParseDateString(cls, date_str: str) -> Optional[datetime.datetime]:
78
+ def _ParseDateString(cls, date_str: str) -> datetime.datetime | None:
78
79
  try:
79
80
  # We can't use `datetime.datetime.fromisoformat` because it's behavior
80
81
  # changes by Python version.
@@ -83,12 +84,14 @@ class DeprecatedAsset:
83
84
  return None
84
85
 
85
86
  @classmethod
86
- def FromStacLink(cls, stac_link: Dict[str, Any]) -> DeprecatedAsset:
87
+ def FromStacLink(cls, stac_link: dict[str, Any]) -> DeprecatedAsset:
87
88
  removal_date = stac_link.get('gee:removal_date')
88
89
  if removal_date is not None:
89
90
  removal_date = cls._ParseDateString(removal_date)
91
+ title = stac_link.get('title')
92
+ assert isinstance(title, str)
90
93
  return DeprecatedAsset(
91
- id=stac_link.get('title'),
94
+ id=title,
92
95
  replacement_id=stac_link.get('gee:replacement_id'),
93
96
  removal_date=removal_date,
94
97
  learn_more_url=stac_link.get('gee:learn_more_url'),
@@ -139,7 +142,7 @@ def InitializeDeprecatedAssets() -> None:
139
142
 
140
143
  def _InitializeDeprecatedAssetsInternal() -> None:
141
144
  global deprecated_assets
142
- if deprecated_assets is not None:
145
+ if deprecated_assets:
143
146
  return
144
147
  _UnfilterDeprecationWarnings()
145
148
 
@@ -153,10 +156,10 @@ def _InitializeDeprecatedAssetsInternal() -> None:
153
156
 
154
157
  def Reset() -> None:
155
158
  global deprecated_assets
156
- deprecated_assets = None
159
+ deprecated_assets = dict()
157
160
 
158
161
 
159
- def _FetchDataCatalogStac() -> Dict[str, Any]:
162
+ def _FetchDataCatalogStac() -> dict[str, Any]:
160
163
  try:
161
164
  response = urllib.request.urlopen(_DEPRECATED_ASSETS_URL).read()
162
165
  except (urllib.error.HTTPError, urllib.error.URLError):
@@ -164,7 +167,7 @@ def _FetchDataCatalogStac() -> Dict[str, Any]:
164
167
  return json.loads(response)
165
168
 
166
169
 
167
- def _GetStringFromObject(obj: Any) -> Optional[str]:
170
+ def _GetStringFromObject(obj: Any) -> str | None:
168
171
  if isinstance(obj, str):
169
172
  return obj
170
173
  return None
@@ -202,6 +205,11 @@ def _IssueAssetDeprecationWarning(asset: DeprecatedAsset) -> None:
202
205
  formatted_date = removal_date.strftime('%B %d, %Y').replace(' 0', ' ')
203
206
  warning += f' by {formatted_date}'
204
207
  warning += '.'
208
+ if asset.replacement_id:
209
+ warning = (
210
+ warning
211
+ + f'\nThis dataset has been superseded by {asset.replacement_id}\n'
212
+ )
205
213
  if asset.learn_more_url:
206
214
  warning = warning + f'\nLearn more: {asset.learn_more_url}\n'
207
215
  warnings.warn(warning, category=DeprecationWarning)
ee/deserializer.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """A deserializer that decodes EE object trees from JSON DAGs."""
2
2
 
3
3
  import json
4
+ from typing import Any
4
5
 
5
6
  from ee import apifunction
6
7
  from ee import computedobject
@@ -12,7 +13,7 @@ from ee import function
12
13
  from ee import geometry
13
14
 
14
15
 
15
- def fromJSON(json_obj): # pylint: disable=g-bad-name
16
+ def fromJSON(json_obj: bytes | str) -> Any: # pylint: disable=g-bad-name
16
17
  """Deserialize an object from a JSON string appropriate for API calls.
17
18
 
18
19
  Args:
@@ -24,7 +25,7 @@ def fromJSON(json_obj): # pylint: disable=g-bad-name
24
25
  return decode(json.loads(json_obj))
25
26
 
26
27
 
27
- def decode(json_obj):
28
+ def decode(json_obj: Any) -> Any:
28
29
  """Decodes an object previously encoded using the EE API v2 (DAG) format.
29
30
 
30
31
  Args:
@@ -50,7 +51,8 @@ def decode(json_obj):
50
51
  return _decodeValue(json_obj, named_values)
51
52
 
52
53
 
53
- def _decodeValue(json_obj, named_values): # pylint: disable=g-bad-name
54
+ # pylint: disable-next=g-bad-name
55
+ def _decodeValue(json_obj: Any, named_values: dict[str, Any]) -> Any:
54
56
  """Decodes an object previously encoded using the EE API v2 (DAG) format.
55
57
 
56
58
  This uses a provided scope for ValueRef lookup and does not allow the
@@ -74,7 +76,7 @@ def _decodeValue(json_obj, named_values): # pylint: disable=g-bad-name
74
76
 
75
77
  # Ensure that we've got a proper object at this point.
76
78
  if not isinstance(json_obj, dict):
77
- raise ee_exception.EEException('Cannot decode object: ' + json_obj)
79
+ raise ee_exception.EEException(f'Cannot decode object: {json_obj}')
78
80
 
79
81
  # Check for explicitly typed values.
80
82
  type_name = json_obj['type']
@@ -82,16 +84,16 @@ def _decodeValue(json_obj, named_values): # pylint: disable=g-bad-name
82
84
  if json_obj['value'] in named_values:
83
85
  return named_values[json_obj['value']]
84
86
  else:
85
- raise ee_exception.EEException('Unknown ValueRef: ' + json_obj)
87
+ raise ee_exception.EEException(f'Unknown ValueRef: {json_obj}')
86
88
  elif type_name == 'ArgumentRef':
87
89
  var_name = json_obj['value']
88
90
  if not isinstance(var_name, str):
89
- raise ee_exception.EEException('Invalid variable name: ' + var_name)
90
- return customfunction.CustomFunction.variable(None, var_name) # pylint: disable=protected-access
91
+ raise ee_exception.EEException(f'Invalid variable name: {var_name}')
92
+ return customfunction.CustomFunction.variable(None, var_name)
91
93
  elif type_name == 'Date':
92
94
  microseconds = json_obj['value']
93
95
  if not isinstance(microseconds, (float, int)):
94
- raise ee_exception.EEException('Invalid date value: ' + microseconds)
96
+ raise ee_exception.EEException(f'Invalid date value: {microseconds}')
95
97
  return ee_date.Date(microseconds / 1e3)
96
98
  elif type_name == 'Bytes':
97
99
  result = encodable.Encodable()
@@ -105,14 +107,14 @@ def _decodeValue(json_obj, named_values): # pylint: disable=g-bad-name
105
107
  else:
106
108
  func = _decodeValue(json_obj['function'], named_values)
107
109
  if 'arguments' in json_obj:
108
- args = dict((key, _decodeValue(value, named_values))
109
- for (key, value) in json_obj['arguments'].items())
110
+ args = {key: _decodeValue(value, named_values)
111
+ for (key, value) in json_obj['arguments'].items()}
110
112
  else:
111
113
  args = {}
112
114
  return _invocation(func, args)
113
115
  elif type_name == 'Dictionary':
114
- return dict((key, _decodeValue(value, named_values))
115
- for (key, value) in json_obj['value'].items())
116
+ return {key: _decodeValue(value, named_values)
117
+ for (key, value) in json_obj['value'].items()}
116
118
  elif type_name == 'Function':
117
119
  body = _decodeValue(json_obj['body'], named_values)
118
120
  signature = {
@@ -129,10 +131,10 @@ def _decodeValue(json_obj, named_values): # pylint: disable=g-bad-name
129
131
  elif type_name == 'CompoundValue':
130
132
  raise ee_exception.EEException('Nested CompoundValues are disallowed.')
131
133
  else:
132
- raise ee_exception.EEException('Unknown encoded object type: ' + type_name)
134
+ raise ee_exception.EEException(f'Unknown encoded object type: {type_name}')
133
135
 
134
136
 
135
- def _invocation(func, args):
137
+ def _invocation(func: Any, args: dict[str, Any]) -> Any:
136
138
  """Creates an EE object representing the application of `func` to `args`."""
137
139
  if isinstance(func, function.Function):
138
140
  return func.apply(args)
@@ -148,10 +150,10 @@ def _invocation(func, args):
148
150
  'returns': 'ComputedObject'
149
151
  }
150
152
  return function.SecondOrderFunction(func, signature).apply(args)
151
- raise ee_exception.EEException('Invalid function value: %s' % func)
153
+ raise ee_exception.EEException(f'Invalid function value: {func}')
152
154
 
153
155
 
154
- def fromCloudApiJSON(json_obj): # pylint: disable=g-bad-name
156
+ def fromCloudApiJSON(json_obj: str | bytes) -> Any: # pylint: disable=g-bad-name
155
157
  """Deserializes an object from the JSON string used in Cloud API calls.
156
158
 
157
159
  Args:
@@ -163,7 +165,8 @@ def fromCloudApiJSON(json_obj): # pylint: disable=g-bad-name
163
165
  return decodeCloudApi(json.loads(json_obj))
164
166
 
165
167
 
166
- def decodeCloudApi(json_obj): # pylint: disable=g-bad-name
168
+ # pylint: disable-next=g-bad-name
169
+ def decodeCloudApi(json_obj: dict[str, Any]) -> Any:
167
170
  """Decodes an object previously encoded using the EE Cloud API format.
168
171
 
169
172
  Args:
@@ -177,7 +180,7 @@ def decodeCloudApi(json_obj): # pylint: disable=g-bad-name
177
180
  def lookup(reference, kind):
178
181
  if reference not in decoded:
179
182
  if reference not in json_obj['values']:
180
- raise ee_exception.EEException('Cannot find %s %s' % (reference, kind))
183
+ raise ee_exception.EEException(f'Cannot find {reference} {kind}')
181
184
  decoded[reference] = decode_node(json_obj['values'][reference])
182
185
  return decoded[reference]
183
186
 
@@ -206,14 +209,16 @@ def decodeCloudApi(json_obj): # pylint: disable=g-bad-name
206
209
  return lookup(node['valueReference'], 'reference')
207
210
  return None
208
211
 
209
- def decode_function_definition(defined):
212
+ def decode_function_definition(
213
+ defined: dict[str, Any],
214
+ ) -> customfunction.CustomFunction:
210
215
  body = lookup(defined['body'], 'function body')
211
216
  signature_args = [{'name': name, 'type': 'Object', 'optional': False}
212
217
  for name in defined['argumentNames']]
213
218
  signature = {'args': signature_args, 'name': '', 'returns': 'Object'}
214
219
  return customfunction.CustomFunction(signature, lambda *args: body)
215
220
 
216
- def decode_function_invocation(invoked):
221
+ def decode_function_invocation(invoked: dict[str, Any]) -> Any:
217
222
  if 'functionReference' in invoked:
218
223
  func = lookup(invoked['functionReference'], 'function')
219
224
  else:
ee/dictionary.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """A wrapper for dictionaries."""
2
2
  from __future__ import annotations
3
3
 
4
- from typing import Any, Dict, Optional, Union
4
+ from typing import Any, Union
5
5
 
6
6
  from ee import _arg_types
7
7
  from ee import _utils
@@ -26,14 +26,14 @@ _StringListType = Union[Any, computedobject.ComputedObject]
26
26
  class Dictionary(computedobject.ComputedObject):
27
27
  """An object to represent dictionaries."""
28
28
 
29
- _dictionary: Optional[Dict[Any, Any]]
29
+ _dictionary: dict[Any, Any] | None
30
30
 
31
31
  _initialized = False
32
32
 
33
33
  # Tell pytype to not complain about dynamic attributes.
34
34
  _HAS_DYNAMIC_ATTRIBUTES = True
35
35
 
36
- def __init__(self, arg: Optional[_arg_types.Dictionary] = None):
36
+ def __init__(self, arg: _arg_types.Dictionary | None = None):
37
37
  """Construct a dictionary.
38
38
 
39
39
  Args:
@@ -91,7 +91,7 @@ class Dictionary(computedobject.ComputedObject):
91
91
  def combine(
92
92
  self,
93
93
  second: _arg_types.Dictionary,
94
- overwrite: Optional[_arg_types.Bool] = None,
94
+ overwrite: _arg_types.Bool | None = None,
95
95
  ) -> Dictionary:
96
96
  """Combines two dictionaries.
97
97
 
@@ -140,7 +140,7 @@ class Dictionary(computedobject.ComputedObject):
140
140
  self,
141
141
  key: _EeKeyType,
142
142
  # pylint: disable-next=invalid-name
143
- defaultValue: Optional[_arg_types.Any] = None,
143
+ defaultValue: _arg_types.Any | None = None,
144
144
  ) -> computedobject.ComputedObject:
145
145
  """Extracts a named value from a dictionary.
146
146
 
@@ -237,7 +237,7 @@ class Dictionary(computedobject.ComputedObject):
237
237
  self,
238
238
  selectors: _arg_types.Any,
239
239
  # pylint: disable-next=invalid-name
240
- ignoreMissing: Optional[_arg_types.Bool] = None,
240
+ ignoreMissing: _arg_types.Bool | None = None,
241
241
  ) -> Dictionary:
242
242
  """Returns a dictionary with the specified keys removed.
243
243
 
@@ -278,7 +278,7 @@ class Dictionary(computedobject.ComputedObject):
278
278
  self,
279
279
  selectors: _arg_types.Any,
280
280
  # pylint: disable-next=invalid-name
281
- ignoreMissing: Optional[_arg_types.Bool] = None,
281
+ ignoreMissing: _arg_types.Bool | None = None,
282
282
  ) -> Dictionary:
283
283
  """Returns a dictionary with only the specified keys.
284
284
 
@@ -315,8 +315,8 @@ class Dictionary(computedobject.ComputedObject):
315
315
 
316
316
  def toArray(
317
317
  self,
318
- keys: Optional[_EeKeyListType] = None,
319
- axis: Optional[_arg_types.Integer] = None,
318
+ keys: _EeKeyListType | None = None,
319
+ axis: _arg_types.Integer | None = None,
320
320
  ) -> ee_array.Array:
321
321
  """Returns numeric values of a dictionary as an array.
322
322
 
@@ -335,7 +335,7 @@ class Dictionary(computedobject.ComputedObject):
335
335
  self.name() + '.toArray', self, keys, axis
336
336
  )
337
337
 
338
- def toImage(self, names: Optional[_arg_types.Any] = None) -> image.Image:
338
+ def toImage(self, names: _arg_types.Any | None = None) -> image.Image:
339
339
  """Creates an image of constants from values in a dictionary.
340
340
 
341
341
  The bands of the image are ordered and named according to the names
@@ -351,7 +351,7 @@ class Dictionary(computedobject.ComputedObject):
351
351
 
352
352
  return apifunction.ApiFunction.call_(self.name() + '.toImage', self, names)
353
353
 
354
- def values(self, keys: Optional[_EeKeyListType] = None) -> ee_list.List:
354
+ def values(self, keys: _EeKeyListType | None = None) -> ee_list.List:
355
355
  """Returns the values of a dictionary as a list.
356
356
 
357
357
  If no keys are specified, all values are returned in the natural ordering of
ee/ee_array.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """A wrapper for Arrays."""
2
2
  from __future__ import annotations
3
3
 
4
- from typing import Any, Dict, Optional
4
+ from typing import Any
5
5
 
6
6
  from ee import _arg_types
7
7
  from ee import apifunction
@@ -37,7 +37,7 @@ class Array(computedobject.ComputedObject):
37
37
  self,
38
38
  values: _arg_types.Array,
39
39
  # pylint: disable-next=invalid-name
40
- pixelType: Optional[_arg_types.String] = None,
40
+ pixelType: _arg_types.String | None = None,
41
41
  ):
42
42
  """Creates an Array wrapper.
43
43
 
@@ -60,7 +60,7 @@ class Array(computedobject.ComputedObject):
60
60
  super().__init__(values.func, values.args, values.varName)
61
61
  return
62
62
 
63
- args: Dict[str, Any] = {'values': values}
63
+ args: dict[str, Any] = {'values': values}
64
64
  if pixelType is not None:
65
65
  args['pixelType'] = pixelType
66
66
 
@@ -92,7 +92,7 @@ class Array(computedobject.ComputedObject):
92
92
  def accum(
93
93
  self,
94
94
  axis: _arg_types.Integer,
95
- reducer: Optional[_arg_types.Reducer] = None,
95
+ reducer: _arg_types.Reducer | None = None,
96
96
  ) -> Array:
97
97
  """Accumulates elements of an array along the given axis.
98
98
 
@@ -189,6 +189,8 @@ class Array(computedobject.ComputedObject):
189
189
 
190
190
  return apifunction.ApiFunction.call_(self.name() + '.bitCount', self)
191
191
 
192
+ @staticmethod
193
+ # pylint: disable-next=redefined-builtin
192
194
  def bitsToArray(input: _arg_types.Integer) -> Array:
193
195
  """Returns an Array from the bits of an integer.
194
196
 
@@ -261,7 +263,7 @@ class Array(computedobject.ComputedObject):
261
263
 
262
264
  @staticmethod
263
265
  def cat(
264
- arrays: _arg_types.List, axis: Optional[_arg_types.Integer] = None
266
+ arrays: _arg_types.List, axis: _arg_types.Integer | None = None
265
267
  ) -> Array:
266
268
  """Returns an Array that is the concatenation of the given arrays.
267
269
 
@@ -748,8 +750,8 @@ class Array(computedobject.ComputedObject):
748
750
 
749
751
  def matrixTranspose(
750
752
  self,
751
- axis1: Optional[_arg_types.Integer] = None,
752
- axis2: Optional[_arg_types.Integer] = None,
753
+ axis1: _arg_types.Integer | None = None,
754
+ axis2: _arg_types.Integer | None = None,
753
755
  ) -> Array:
754
756
  """Transposes two dimensions of an array.
755
757
 
@@ -843,7 +845,7 @@ class Array(computedobject.ComputedObject):
843
845
  return apifunction.ApiFunction.call_(self.name() + '.or', self, right)
844
846
 
845
847
  def pad(
846
- self, lengths: _arg_types.Any, pad: Optional[_arg_types.Number] = None
848
+ self, lengths: _arg_types.Any, pad: _arg_types.Number | None = None
847
849
  ) -> Array:
848
850
  """Pad an array to a given length.
849
851
 
@@ -896,7 +898,7 @@ class Array(computedobject.ComputedObject):
896
898
  reducer: _arg_types.Reducer,
897
899
  axes: _arg_types.Any,
898
900
  # pylint: disable-next=invalid-name
899
- fieldAxis: Optional[_arg_types.Integer] = None,
901
+ fieldAxis: _arg_types.Integer | None = None,
900
902
  ) -> Array:
901
903
  """Returns the result of applying the reducer on the array.
902
904
 
@@ -934,8 +936,8 @@ class Array(computedobject.ComputedObject):
934
936
 
935
937
  def repeat(
936
938
  self,
937
- axis: Optional[_arg_types.Integer] = None,
938
- copies: Optional[_arg_types.Integer] = None,
939
+ axis: _arg_types.Integer | None = None,
940
+ copies: _arg_types.Integer | None = None,
939
941
  ) -> Array:
940
942
  """Repeats the array along the given axis.
941
943
 
@@ -1019,10 +1021,10 @@ class Array(computedobject.ComputedObject):
1019
1021
 
1020
1022
  def slice(
1021
1023
  self,
1022
- axis: Optional[_arg_types.Integer] = None,
1023
- start: Optional[_arg_types.Integer] = None,
1024
- end: Optional[_arg_types.Integer] = None,
1025
- step: Optional[_arg_types.Integer] = None,
1024
+ axis: _arg_types.Integer | None = None,
1025
+ start: _arg_types.Integer | None = None,
1026
+ end: _arg_types.Integer | None = None,
1027
+ step: _arg_types.Integer | None = None,
1026
1028
  ) -> Array:
1027
1029
  """Returns the result of slicing the array along the given axis.
1028
1030
 
@@ -1041,7 +1043,7 @@ class Array(computedobject.ComputedObject):
1041
1043
  start: The coordinate of the first slice (inclusive) along 'axis'.
1042
1044
  Negative numbers are used to position the start of slicing relative to
1043
1045
  the end of the array, where -1 starts at the last position on the axis,
1044
- -2 starts at the next to last position, etc. Defaults to 0.
1046
+ -2 starts at the next to last position, etc. Defaults to 0.
1045
1047
  end: The coordinate (exclusive) at which to stop taking slices. By default
1046
1048
  this will be the length of the given axis. Negative numbers are used to
1047
1049
  position the end of slicing relative to the end of the array, where -1
@@ -1049,7 +1051,7 @@ class Array(computedobject.ComputedObject):
1049
1051
  etc.
1050
1052
  step: The separation between slices along 'axis'; a slice will be taken at
1051
1053
  each whole multiple of 'step' from 'start' (inclusive) to 'end'
1052
- (exclusive). Must be positive. Defaults to 1.
1054
+ (exclusive). Must be positive. Defaults to 1.
1053
1055
 
1054
1056
  Returns:
1055
1057
  An ee.Array.
@@ -1059,7 +1061,7 @@ class Array(computedobject.ComputedObject):
1059
1061
  self.name() + '.slice', self, axis, start, end, step
1060
1062
  )
1061
1063
 
1062
- def sort(self, keys: Optional[_arg_types.Any] = None) -> Array:
1064
+ def sort(self, keys: _arg_types.Any | None = None) -> Array:
1063
1065
  """Sorts elements of the array along one axis.
1064
1066
 
1065
1067
  Args:
@@ -1172,8 +1174,8 @@ class Array(computedobject.ComputedObject):
1172
1174
 
1173
1175
  def transpose(
1174
1176
  self,
1175
- axis1: Optional[_arg_types.Integer] = None,
1176
- axis2: Optional[_arg_types.Integer] = None,
1177
+ axis1: _arg_types.Integer | None = None,
1178
+ axis2: _arg_types.Integer | None = None,
1177
1179
  ) -> Array:
1178
1180
  """Transposes two dimensions of an array.
1179
1181