crossplane-function-pythonic 0.6.2__py3-none-any.whl → 0.7.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.
@@ -1,5 +1,9 @@
1
-
2
1
  import datetime
2
+ import logging
3
+ import types
4
+ import typing
5
+ from typing import cast
6
+
3
7
  from google.protobuf.duration_pb2 import Duration
4
8
 
5
9
  from . import (
@@ -8,55 +12,63 @@ from . import (
8
12
  )
9
13
  from .proto.v1 import run_function_pb2 as fnv1
10
14
 
11
-
12
- _notset = object()
15
+ _notset = sentinel("_notset")
13
16
 
14
17
 
15
18
  class ConnectionSecret:
16
- def __get__(self, composite, objtype=None):
19
+ def __get__(self, composite: BaseComposite, objtype=None) -> protobuf.Value:
17
20
  if composite.crossplane_v1:
18
21
  return composite.spec.writeConnectionSecretToRef
19
- secret = getattr(composite, '_connectionSecret', None)
20
- if not secret:
21
- secret = protobuf.Map()
22
+ if not composite._connectionSecret:
23
+ composite._connectionSecret = protobuf.Map()
22
24
  for key, value in composite.request.input.writeConnectionSecretToRef:
23
- secret[key] = value
24
- composite._connectionSecret = secret
25
- return secret
25
+ composite._connectionSecret[key] = value
26
+ return composite._connectionSecret
26
27
 
27
- def __set__(self, composite, values):
28
+ def __set__(
29
+ self, composite: BaseComposite, values: typing.Mapping | protobuf.Value
30
+ ) -> None:
28
31
  if composite.crossplane_v1:
29
32
  if values != composite.spec.writeConnectionSecretToRef:
30
- raise NotImplementedError('Connection Secret cannot be set in Crossplane V1')
33
+ raise NotImplementedError(
34
+ "Connection Secret cannot be set in Crossplane V1"
35
+ )
31
36
  return
32
- secret = protobuf.Map()
33
- for key, value in values:
34
- secret[key] = value
35
- composite._connectionSecret = secret
37
+ composite._connectionSecret = protobuf.Map()
38
+ for entry in values:
39
+ if isinstance(entry, str):
40
+ composite._connectionSecret[entry] = values[entry]
41
+ elif isinstance(entry, (tuple, list)):
42
+ composite._connectionSecret[entry[0]] = entry[1]
36
43
 
37
44
 
38
45
  class Connection:
39
- def __get__(self, composite, objtype=None):
40
- connection = getattr(composite, '_connection', None)
41
- if not connection:
42
- connection = _Connection(composite)
43
- composite._connection = connection
44
- return connection
45
-
46
- def __set__(self, composite, values):
46
+ def __get__(self, composite: BaseComposite, objtype=None) -> _Connection:
47
+ if not composite._connection:
48
+ composite._connection = _Connection(composite)
49
+ return composite._connection
50
+
51
+ def __set__(
52
+ self, composite: BaseComposite, values: typing.Mapping | protobuf.Value
53
+ ) -> None:
47
54
  connection = self.__get__(composite)
48
55
  connection()
49
- for key, value in values:
50
- connection[key] = value
56
+ for entry in values:
57
+ if isinstance(entry, str):
58
+ connection[entry] = values[entry]
59
+ elif isinstance(entry, (tuple, list)):
60
+ connection[entry[0]] = entry[1]
51
61
 
52
62
 
53
63
  class TTL:
54
- def __get__(self, composite, objtype=None):
55
- if composite.response.meta.ttl.nanos:
56
- return float(composite.response.meta.ttl.seconds) + (float(composite.response.meta.ttl.nanos) / 1000000000.0)
57
- return int(composite.response.meta.ttl.seconds)
64
+ def __get__(self, composite: BaseComposite, objtype=None) -> int | float:
65
+ if composite.response.meta.ttl.nanos == 0:
66
+ return int(composite.response.meta.ttl.seconds)
67
+ return float(composite.response.meta.ttl.seconds) + (
68
+ float(composite.response.meta.ttl.nanos) / 1000000000.0
69
+ )
58
70
 
59
- def __set__(self, composite, ttl):
71
+ def __set__(self, composite: BaseComposite, ttl: float) -> None:
60
72
  if isinstance(ttl, int):
61
73
  composite.response.meta.ttl.seconds = ttl
62
74
  composite.response.meta.ttl.nanos = 0
@@ -65,35 +77,58 @@ class TTL:
65
77
  if ttl.is_integer():
66
78
  composite.response.meta.ttl.nanos = 0
67
79
  else:
68
- composite.response.meta.ttl.nanos = int((ttl - int(composite.response.meta.ttl.seconds)) * 1000000000)
80
+ composite.response.meta.ttl.nanos = int(
81
+ (ttl - int(composite.response.meta.ttl.seconds)) * 1000000000
82
+ )
69
83
  else:
70
- raise ValueError('ttl must be an int or float')
84
+ raise TypeError("ttl must be an int or float")
71
85
 
72
86
 
73
87
  class Ready:
74
- def __get__(self, composite, objtype=None):
75
- if hasattr(composite, '_ready'):
88
+ def __get__(
89
+ self, composite: BaseComposite, objtype=None
90
+ ) -> bool | protobuf.Value | None:
91
+ if composite._ready is not None:
76
92
  return composite._ready
77
- if composite.desired._parent.ready == fnv1.Ready.READY_TRUE:
93
+ if (
94
+ cast(protobuf.Message, composite.desired._parent).ready
95
+ == fnv1.Ready.READY_TRUE
96
+ ):
78
97
  return True
79
- if composite.desired._parent.ready == fnv1.Ready.READY_FALSE:
98
+ if (
99
+ cast(protobuf.Message, composite.desired._parent).ready
100
+ == fnv1.Ready.READY_FALSE
101
+ ):
80
102
  return False
81
103
  return None
82
104
 
83
- def __set__(self, composite, ready):
105
+ def __set__(self, composite: BaseComposite, ready: protobuf.Value | bool | None):
84
106
  composite._ready = ready
85
107
  if ready:
86
- composite.desired._parent.ready = fnv1.Ready.READY_TRUE
108
+ cast(
109
+ protobuf.Message, composite.desired._parent
110
+ ).ready = fnv1.Ready.READY_TRUE
87
111
  elif ready is None:
88
- composite.desired._parent.ready = fnv1.Ready.READY_UNSPECIFIED
112
+ cast(
113
+ protobuf.Message, composite.desired._parent
114
+ ).ready = fnv1.Ready.READY_UNSPECIFIED
89
115
  else:
90
- composite.desired._parent.ready = fnv1.Ready.READY_FALSE
116
+ cast(
117
+ protobuf.Message, composite.desired._parent
118
+ ).ready = fnv1.Ready.READY_FALSE
91
119
 
92
120
 
93
121
  class BaseComposite:
94
- def __init__(self, crossplane_v1, request, logger):
122
+ def __init__(
123
+ self,
124
+ crossplane_v1: bool,
125
+ request: fnv1.RunFunctionRequest,
126
+ logger: logging.Logger,
127
+ ) -> None:
95
128
  self.crossplane_v1 = crossplane_v1
96
- self.request = protobuf.Message(None, 'request', request.DESCRIPTOR, request, 'Function Request')
129
+ self.request = protobuf.Message(
130
+ None, "request", request.DESCRIPTOR, request, "Function Request"
131
+ )
97
132
  response = fnv1.RunFunctionResponse(
98
133
  meta=fnv1.ResponseMeta(
99
134
  tag=request.meta.tag,
@@ -104,286 +139,346 @@ class BaseComposite:
104
139
  desired=request.desired,
105
140
  context=request.context,
106
141
  )
107
- self.response = protobuf.Message(None, 'response', response.DESCRIPTOR, response)
108
- self.logger = logger
109
- self.capabilities = Capabilities(self.request.meta.capabilities)
110
- self.parameters = self.request.input.parameters
111
- self.credentials = Credentials(self.request)
112
- self.context = self.response.context
113
- self.environment = self.context['apiextensions.crossplane.io/environment']
114
- self.requireds = Requireds(self)
115
- self.watched = self.requireds['ops.crossplane.io/watched-resource'][0]
116
- self.schemas = Schemas(self)
117
- self.resources = Resources(self)
118
- self.autoReady = True
119
- self.usages = False
120
- self.unknownsFatal = False
121
-
122
- observed = self.request.observed.composite
123
- desired = self.response.desired.composite
124
- self.observed = observed.resource
125
- self.desired = desired.resource
126
- self.apiVersion = self.observed.apiVersion
127
- self.kind = self.observed.kind
128
- self.metadata = self.observed.metadata
129
- self.spec = self.observed.spec
130
- self.status = self.desired.status
131
- self.output = self.response.output
132
- self.conditions = Conditions(observed, self.response)
133
- self.results = Results(self.response)
134
- self.events = Results(self.response) # Deprecated, use self.results
135
-
136
- ttl = TTL()
137
- connectionSecret = ConnectionSecret()
138
- connection = Connection()
139
- ready = Ready()
140
-
141
- async def compose(self):
142
+ self.response = protobuf.Message(
143
+ None, "response", response.DESCRIPTOR, response
144
+ )
145
+ self.logger: logging.Logger = logger
146
+ self.capabilities: Capabilities = Capabilities(
147
+ cast(protobuf.RepeatedMessage, self.request.meta.capabilities)
148
+ )
149
+ self.parameters: protobuf.Value = cast(
150
+ protobuf.Value, self.request.input.parameters
151
+ )
152
+ self.credentials: Credentials = Credentials(self.request)
153
+ self.context: protobuf.Value = cast(protobuf.Value, self.response.context)
154
+ self.environment: protobuf.Value = self.context[
155
+ "apiextensions.crossplane.io/environment"
156
+ ]
157
+ self.requireds: Requireds = Requireds(self)
158
+ self.watched: RequiredResource = self.requireds[
159
+ "ops.crossplane.io/watched-resource"
160
+ ][0]
161
+ self.schemas: Schemas = Schemas(self)
162
+ self.resources: Resources = Resources(self)
163
+ self.autoReady: bool = True
164
+ self.usages: bool = False
165
+ self.unknownsFatal: bool = False
166
+
167
+ observed: protobuf.Message = cast(
168
+ protobuf.Message, self.request.observed.composite
169
+ )
170
+ desired: protobuf.Message = cast(
171
+ protobuf.Message, self.response.desired.composite
172
+ )
173
+ self.observed: protobuf.Value = cast(protobuf.Value, observed.resource)
174
+ self.desired: protobuf.Value = cast(protobuf.Value, desired.resource)
175
+ self.apiVersion: protobuf.Value = cast(protobuf.Value, self.observed.apiVersion)
176
+ self.kind: protobuf.Value = self.observed.kind
177
+ self.metadata: protobuf.Value = self.observed.metadata
178
+ self.spec: protobuf.Value = self.observed.spec
179
+ self.status: protobuf.Value = self.desired.status
180
+ self.output: protobuf.Value = cast(protobuf.Value, self.response.output)
181
+ self.conditions: Conditions = Conditions(observed, self.response)
182
+ self.results: Results = Results(self.response)
183
+
184
+ self._connectionSecret: protobuf.Value | None = None
185
+ self._connection: _Connection | None = None
186
+ self._ready: protobuf.Value | bool | None = None
187
+
188
+ ttl: TTL = TTL()
189
+ connectionSecret: ConnectionSecret = ConnectionSecret()
190
+ connection: Connection = Connection()
191
+ ready: Ready = Ready()
192
+
193
+ async def compose(self) -> None:
142
194
  raise NotImplementedError()
143
195
 
144
196
 
145
197
  class Capabilities:
146
- def __init__(self, capabilities):
147
- self._capabilities = capabilities
198
+ def __init__(self, capabilities: protobuf.RepeatedMessage):
199
+ self._capabilities: protobuf.RepeatedMessage = capabilities
148
200
 
149
201
  def __bool__(self):
150
202
  return fnv1.CAPABILITY_CAPABILITIES in self._capabilities
151
203
 
152
204
  @property
153
- def requireds(self):
154
- return fnv1.CAPABILITY_REQUIRED_RESOURCES in self._capabilities if self else None
205
+ def requireds(self) -> bool | None:
206
+ return (
207
+ fnv1.CAPABILITY_REQUIRED_RESOURCES in self._capabilities if self else None
208
+ )
155
209
 
156
210
  @property
157
- def credentials(self):
211
+ def credentials(self) -> bool | None:
158
212
  return fnv1.CAPABILITY_CREDENTIALS in self._capabilities if self else None
159
213
 
160
214
  @property
161
- def conditions(self):
215
+ def conditions(self) -> bool | None:
162
216
  return fnv1.CAPABILITY_CONDITIONS in self._capabilities if self else None
163
217
 
164
218
  @property
165
- def schemas(self):
219
+ def schemas(self) -> bool | None:
166
220
  return fnv1.CAPABILITY_REQUIRED_SCHEMAS in self._capabilities if self else None
167
221
 
168
222
 
169
223
  class Credentials:
170
- def __init__(self, request):
171
- self.__dict__['_request'] = request
224
+ _request: protobuf.Message
225
+
226
+ def __init__(self, request: protobuf.Message):
227
+ self._request: protobuf.Message = request
172
228
 
173
- def __getattr__(self, key):
229
+ def __getattr__(self, key: protobuf.TypeString) -> Credential:
174
230
  return self[key]
175
231
 
176
- def __getitem__(self, key):
177
- return Credential(self._request.credentials[key])
232
+ def __getitem__(self, key: protobuf.TypeString) -> Credential:
233
+ return Credential(cast(protobuf.Message, self._request.credentials[key]))
178
234
 
179
- def __bool__(self):
180
- return bool(self._request.credentials)
235
+ def __bool__(self) -> bool:
236
+ return bool(len(self))
181
237
 
182
- def __len__(self):
238
+ def __len__(self) -> int:
183
239
  return len(self._request.credentials)
184
240
 
185
- def __contains__(self, key):
241
+ def __contains__(self, key: protobuf.TypeString) -> bool:
186
242
  return key in self._request.credentials
187
243
 
188
- def __iter__(self):
244
+ def __iter__(self) -> typing.Generator[tuple[str, Credential]]:
189
245
  for key, resource in self._request.credentials:
190
246
  yield key, self[key]
191
247
 
192
248
 
193
249
  class Credential:
194
- def __init__(self, credential):
195
- self.__dict__['_credential'] = credential
250
+ def __init__(self, credential: protobuf.Message):
251
+ self._credential: protobuf.Message = credential
196
252
 
197
- def __getattr__(self, key):
253
+ def __getattr__(self, key: protobuf.TypeString) -> str:
198
254
  return self[key]
199
255
 
200
- def __getitem__(self, key):
201
- return self._credential.credential_data.data[key]
256
+ def __getitem__(self, key: protobuf.TypeString) -> str:
257
+ return str(self._credential.credential_data.data[key])
202
258
 
203
- def __bool__(self):
204
- return bool(self._credential.credential_data.data)
259
+ def __bool__(self) -> bool:
260
+ return bool(len(self))
205
261
 
206
- def __len__(self):
262
+ def __len__(self) -> int:
207
263
  return len(self._credential.credential_data.data)
208
264
 
209
- def __contains__(self, key):
265
+ def __contains__(self, key: protobuf.TypeString) -> bool:
210
266
  return key in self._credential.credential_data.data
211
267
 
212
- def __iter__(self):
268
+ def __iter__(self) -> typing.Generator[tuple[str, str]]:
213
269
  for key, resource in self._credential.credential_data.data:
214
270
  yield key, self[key]
215
271
 
216
272
 
217
273
  class Resources:
218
- def __init__(self, composite):
219
- self.__dict__['_composite'] = composite
220
- self.__dict__['_cache'] = {}
274
+ def __init__(self, composite: BaseComposite):
275
+ self._composite: BaseComposite = composite
276
+ self._cache: dict[protobuf.TypeString, Resource] = {}
221
277
 
222
- def __getattr__(self, key):
278
+ def __getattr__(self, key: protobuf.TypeString) -> Resource:
223
279
  return self[key]
224
280
 
225
- def __getitem__(self, key):
281
+ def __getitem__(self, key: protobuf.TypeString) -> Resource:
226
282
  resource = self._cache.get(key)
227
283
  if not resource:
228
284
  resource = Resource(self._composite, key)
229
285
  self._cache[key] = resource
230
286
  return resource
231
287
 
232
- def __bool__(self):
233
- return bool(self._composite.response.desired.resources)
288
+ def __bool__(self) -> bool:
289
+ return bool(len(self))
234
290
 
235
- def __len__(self):
291
+ def __len__(self) -> int:
236
292
  return len(self._composite.response.desired.resources)
237
293
 
238
- def __contains__(self, key):
294
+ def __contains__(self, key: protobuf.TypeString) -> bool:
239
295
  return key in self._composite.response.desired.resources
240
296
 
241
- def __iter__(self):
297
+ def __iter__(self) -> typing.Generator[tuple[str, Resource]]:
242
298
  for name, resource in self._composite.response.desired.resources:
243
299
  yield name, self[name]
244
300
 
245
- def __setattr__(self, key, resource):
246
- self[key] = resource
301
+ def __setattr__(
302
+ self,
303
+ key: protobuf.TypeString,
304
+ resource: typing.Mapping | protobuf.Value,
305
+ ) -> None:
306
+ if key in ("_composite", "_cache"):
307
+ self.__dict__[str(key)] = resource
308
+ else:
309
+ self[key] = resource
247
310
 
248
- def __setitem__(self, key, resource):
311
+ def __setitem__(
312
+ self,
313
+ key: protobuf.TypeString,
314
+ resource: typing.Mapping | protobuf.Value,
315
+ ) -> None:
249
316
  self._composite.response.desired.resources[key].resource = resource
250
317
  self._cache.pop(key, None)
251
318
 
252
- def __delattr__(self, key):
319
+ def __delattr__(self, key: protobuf.TypeString) -> None:
253
320
  del self[key]
254
321
 
255
- def __delitem__(self, key):
322
+ def __delitem__(self, key: protobuf.TypeString) -> None:
256
323
  if key in self._composite.response.desired.resources:
257
324
  del self._composite.response.desired.resources[key]
258
325
  self._cache.pop(key, None)
259
326
 
260
327
 
261
328
  class Resource:
262
- def __init__(self, composite, name):
263
- self._composite = composite
264
- self.name = name
265
- observed = composite.request.observed.resources[name]
266
- desired = composite.response.desired.resources[name]
267
- self.observed = observed.resource
268
- self.desired = desired.resource
269
- self.conditions = Conditions(observed)
270
- self.connection = observed.connection_details
271
- self.autoReady = None
272
- self.usages = None
273
- self.unknownsFatal = None
274
-
275
- def __call__(self, kind=_notset, apiVersion=_notset, namespace=_notset, name=_notset):
329
+ def __init__(
330
+ self,
331
+ composite: BaseComposite,
332
+ name: protobuf.TypeString,
333
+ ):
334
+ self._composite: BaseComposite = composite
335
+ self.name: protobuf.TypeString = name
336
+ observed: protobuf.Message = cast(
337
+ protobuf.Message, composite.request.observed.resources[name]
338
+ )
339
+ desired: protobuf.Message = cast(
340
+ protobuf.Message, composite.response.desired.resources[name]
341
+ )
342
+ self.observed: protobuf.Value = cast(protobuf.Value, observed.resource)
343
+ self.desired: protobuf.Value = cast(protobuf.Value, desired.resource)
344
+ self.conditions: Conditions = Conditions(observed)
345
+ self.connection: protobuf.MapMessage = cast(
346
+ protobuf.MapMessage, observed.connection_details
347
+ )
348
+ self.autoReady: bool | None = None
349
+ self.usages: bool | None = None
350
+ self.unknownsFatal: bool | None = None
351
+
352
+ def __call__(
353
+ self,
354
+ kind: str | _notset = _notset,
355
+ apiVersion: str | _notset = _notset,
356
+ namespace: str | _notset = _notset,
357
+ name: str | _notset = _notset,
358
+ ) -> typing.Self:
276
359
  self.desired()
277
- if kind != _notset:
360
+ if kind is not _notset:
278
361
  # Allow for apiVersion in the first arg and kind in the second arg
279
- if '/' in kind or kind == 'v1':
280
- if apiVersion != _notset:
362
+ if "/" in kind or kind == "v1":
363
+ if apiVersion is not _notset:
281
364
  self.kind = apiVersion
282
365
  apiVersion = kind
283
366
  else:
284
367
  self.kind = kind
285
- if apiVersion != _notset:
368
+ if apiVersion is not _notset:
286
369
  self.apiVersion = apiVersion
287
- if namespace != _notset:
370
+ if namespace is not _notset:
288
371
  self.metadata.namespace = namespace
289
- if name != _notset:
372
+ if name is not _notset:
290
373
  self.metadata.name = name
291
374
  return self
292
375
 
293
376
  @property
294
- def apiVersion(self):
377
+ def apiVersion(self) -> protobuf.Value:
295
378
  return self.desired.apiVersion
296
379
 
297
380
  @apiVersion.setter
298
- def apiVersion(self, apiVersion):
381
+ def apiVersion(self, apiVersion: protobuf.TypeString) -> None:
299
382
  self.desired.apiVersion = apiVersion
300
383
 
301
384
  @property
302
- def kind(self):
385
+ def kind(self) -> protobuf.Value:
303
386
  return self.desired.kind
304
387
 
305
388
  @kind.setter
306
- def kind(self, kind):
389
+ def kind(self, kind: protobuf.TypeString) -> None:
307
390
  self.desired.kind = kind
308
391
 
309
392
  @property
310
- def externalName(self):
311
- name = self.metadata.annotations['crossplane.io/external-name']
393
+ def externalName(self) -> protobuf.Value:
394
+ name = self.metadata.annotations["crossplane.io/external-name"]
312
395
  if not name:
313
- name = self.observed.metadata.annotations['crossplane.io/external-name']
396
+ name = self.observed.metadata.annotations["crossplane.io/external-name"]
314
397
  if name:
315
398
  self.externalName = name
316
399
  return name
317
400
 
318
401
  @externalName.setter
319
- def externalName(self, name):
320
- self.metadata.annotations['crossplane.io/external-name'] = name
402
+ def externalName(self, name: protobuf.TypeString) -> None:
403
+ self.metadata.annotations["crossplane.io/external-name"] = name
321
404
 
322
405
  @property
323
- def metadata(self):
406
+ def metadata(self) -> protobuf.Value:
324
407
  return self.desired.metadata
325
408
 
326
409
  @metadata.setter
327
- def metadata(self, metadata):
410
+ def metadata(self, metadata: typing.Mapping | protobuf.Value) -> None:
328
411
  self.desired.metadata = metadata
329
412
 
330
413
  @property
331
- def spec(self):
414
+ def spec(self) -> protobuf.Value:
332
415
  return self.desired.spec
333
416
 
334
417
  @spec.setter
335
- def spec(self, spec):
418
+ def spec(self, spec: typing.Mapping | protobuf.Value) -> None:
336
419
  self.desired.spec = spec
337
420
 
338
421
  # Used by Secret:v1
339
422
  @property
340
- def type(self):
423
+ def type(self) -> protobuf.Value:
341
424
  return self.desired.type
342
425
 
343
426
  @type.setter
344
- def type(self, type):
427
+ def type(self, type: str | protobuf.Value) -> None:
345
428
  self.desired.type = type
346
429
 
347
430
  @property
348
- def data(self):
431
+ def data(self) -> protobuf.Value:
349
432
  return self.desired.data
350
433
 
351
434
  @data.setter
352
- def data(self, data):
435
+ def data(self, data: typing.Mapping | protobuf.Value) -> None:
353
436
  self.desired.data = data
354
437
 
355
438
  @property
356
- def status(self):
439
+ def status(self) -> protobuf.Value:
357
440
  return self.observed.status
358
441
 
359
442
  @property
360
- def ready(self):
361
- if not hasattr(self, '_ready'):
362
- if self.desired._parent.ready == fnv1.Ready.READY_TRUE:
363
- self._ready = True
364
- elif self.desired._parent.ready == fnv1.Ready.READY_FALSE:
443
+ def ready(self) -> protobuf.Value | bool | None:
444
+ if not hasattr(self, "_ready"):
445
+ if (
446
+ cast(protobuf.Message, self.desired._parent).ready
447
+ == fnv1.Ready.READY_TRUE
448
+ ):
449
+ self._ready = True
450
+ elif (
451
+ cast(protobuf.Message, self.desired._parent).ready
452
+ == fnv1.Ready.READY_FALSE
453
+ ):
365
454
  self._ready = False
366
455
  else:
367
456
  self._ready = None
368
- if self.autoReady or (self.autoReady is None and self._composite.autoReady):
457
+ if self.autoReady or (
458
+ self.autoReady is None and self._composite.autoReady
459
+ ):
369
460
  ready = auto_ready.resource_ready(self)
370
461
  if ready:
371
462
  self._ready = ready
372
- self.desired._parent.ready = fnv1.Ready.READY_TRUE
463
+ cast(
464
+ protobuf.Message, self.desired._parent
465
+ ).ready = fnv1.Ready.READY_TRUE
373
466
  return self._ready
374
467
 
375
468
  @ready.setter
376
- def ready(self, ready):
469
+ def ready(self, ready: protobuf.Value | bool | None) -> None:
377
470
  self._ready = ready
378
471
  if ready:
379
- self.desired._parent.ready = fnv1.Ready.READY_TRUE
472
+ cast(protobuf.Message, self.desired._parent).ready = fnv1.Ready.READY_TRUE
380
473
  elif ready is None:
381
- self.desired._parent.ready = fnv1.Ready.READY_UNSPECIFIED
474
+ cast(
475
+ protobuf.Message, self.desired._parent
476
+ ).ready = fnv1.Ready.READY_UNSPECIFIED
382
477
  else:
383
- self.desired._parent.ready = fnv1.Ready.READY_FALSE
478
+ cast(protobuf.Message, self.desired._parent).ready = fnv1.Ready.READY_FALSE
384
479
 
385
- def setReadyCondition(self, type='Ready'):
386
- condition = self.conditions[type]
480
+ def setReadyCondition(self, type: str = "Ready"):
481
+ condition: Condition = self.conditions[type]
387
482
  if condition.status:
388
483
  self.ready = self.observed.metadata.name
389
484
  else:
@@ -393,45 +488,53 @@ class Resource:
393
488
  else:
394
489
  self.ready = self.status[error]
395
490
 
396
- def addDependency(self, resource, field=_notset):
491
+ def addDependency(
492
+ self,
493
+ resource: Resource,
494
+ field: protobuf.FieldMessage | protobuf.Value | None | _notset = _notset,
495
+ ):
496
+ dependency: protobuf.FieldMessage | protobuf.Value | bool | None = None
397
497
  if field is _notset:
398
- field = resource.ready
399
- if field is None:
400
- field = auto_ready.resource_ready(resource)
401
- if field is None:
402
- field = False
403
- resource.ready = field
498
+ dependency = resource.ready
499
+ if dependency is None:
500
+ dependency = auto_ready.resource_ready(resource)
501
+ if dependency is None:
502
+ dependency = False
503
+ resource.ready = dependency
404
504
  elif field is None:
405
- field = True
406
- if not isinstance(field, (protobuf.FieldMessage, protobuf.Value)):
505
+ field = _notset
506
+ else:
507
+ dependency = field
508
+ if not isinstance(dependency, (protobuf.FieldMessage, protobuf.Value)):
407
509
  if field:
408
- field = resource.observed.metadata.name
510
+ dependency = resource.observed.metadata.name
409
511
  else:
410
512
  if not resource.observed.metadata.name:
411
- field = resource.observed.metadata.name
513
+ dependency = resource.observed.metadata.name
412
514
  else:
413
- field = resource.status.notReady
414
- self.metadata.annotations[f"pythonic.dependency/{resource.name}"] = field
515
+ dependency = resource.status.notReady
516
+ self.metadata.annotations[f"pythonic.dependency/{resource.name}"] = dependency
517
+
415
518
 
416
519
  class Requireds:
417
- def __init__(self, composite):
418
- self._composite = composite
419
- self._cache = {}
520
+ def __init__(self, composite: BaseComposite):
521
+ self._composite: BaseComposite = composite
522
+ self._cache: dict[protobuf.TypeString, RequiredResources] = {}
420
523
 
421
- def __getattr__(self, key):
524
+ def __getattr__(self, key: protobuf.TypeString) -> RequiredResources:
422
525
  return self[key]
423
526
 
424
- def __getitem__(self, key):
527
+ def __getitem__(self, key: protobuf.TypeString) -> RequiredResources:
425
528
  required = self._cache.get(key)
426
529
  if not required:
427
530
  required = RequiredResources(self._composite, key)
428
531
  self._cache[key] = required
429
532
  return required
430
533
 
431
- def __bool__(self):
534
+ def __bool__(self) -> bool:
432
535
  return bool(len(self))
433
536
 
434
- def __len__(self):
537
+ def __len__(self) -> int:
435
538
  names = set()
436
539
  if self._composite.crossplane_v1:
437
540
  for name, resource in self._composite.request.extra_resources:
@@ -445,7 +548,7 @@ class Requireds:
445
548
  names.add(name)
446
549
  return len(names)
447
550
 
448
- def __contains__(self, key):
551
+ def __contains__(self, key: protobuf.TypeString) -> bool:
449
552
  if self._composite.crossplane_v1:
450
553
  if key in self._composite.request.extra_resources:
451
554
  return True
@@ -458,8 +561,8 @@ class Requireds:
458
561
  return True
459
562
  return False
460
563
 
461
- def __iter__(self):
462
- names = set()
564
+ def __iter__(self) -> typing.Generator[tuple[str, RequiredResources]]:
565
+ names: set[str] = set()
463
566
  if self._composite.crossplane_v1:
464
567
  for name, resource in self._composite.request.extra_resources:
465
568
  names.add(name)
@@ -475,74 +578,97 @@ class Requireds:
475
578
 
476
579
 
477
580
  class RequiredResources:
478
- def __init__(self, composite, name):
581
+ def __init__(
582
+ self,
583
+ composite: BaseComposite,
584
+ name: protobuf.TypeString,
585
+ ):
479
586
  self.name = name
480
587
  if composite.crossplane_v1:
481
- self._selector = composite.response.requirements.extra_resources[name]
482
- self._resources = composite.request.extra_resources[name]
588
+ self._selector: protobuf.MapMessage = cast(
589
+ protobuf.MapMessage,
590
+ composite.response.requirements.extra_resources[name],
591
+ )
592
+ self._resources: protobuf.MapMessage = cast(
593
+ protobuf.MapMessage, composite.request.extra_resources[name]
594
+ )
483
595
  else:
484
- self._selector = composite.response.requirements.resources[name]
485
- self._resources = composite.request.required_resources[name]
486
- self._cache = {}
487
-
488
- def __call__(self, kind=_notset, apiVersion=_notset, namespace=_notset, name=_notset, labels=_notset):
596
+ self._selector: protobuf.MapMessage = cast(
597
+ protobuf.MapMessage, composite.response.requirements.resources[name]
598
+ )
599
+ self._resources: protobuf.MapMessage = cast(
600
+ protobuf.MapMessage, composite.request.required_resources[name]
601
+ )
602
+ self._cache: dict[int, RequiredResource] = {}
603
+
604
+ def __call__(
605
+ self,
606
+ kind: str | _notset = _notset,
607
+ apiVersion: str | _notset = _notset,
608
+ namespace: str | _notset = _notset,
609
+ name: str | _notset = _notset,
610
+ labels: typing.Mapping[str, str] | _notset = _notset,
611
+ ) -> typing.Self:
489
612
  self._selector()
490
- if kind != _notset:
613
+ if kind is not _notset:
491
614
  # Allow for apiVersion in the first arg and kind in the second arg
492
- if '/' in kind or kind == 'v1':
493
- if apiVersion != _notset:
615
+ if "/" in kind or kind == "v1":
616
+ if apiVersion is not _notset:
494
617
  self.kind = apiVersion
495
618
  apiVersion = kind
496
619
  else:
497
620
  self.kind = kind
498
- if apiVersion != _notset:
621
+ if apiVersion is not _notset:
499
622
  self.apiVersion = apiVersion
500
- if namespace != _notset:
623
+ if namespace is not _notset:
501
624
  self.namespace = namespace
502
- if name != _notset:
625
+ if name is not _notset:
503
626
  self.matchName = name
504
- if labels != _notset:
627
+ if labels is not _notset:
505
628
  self.matchLabels = labels
506
629
  return self
507
630
 
508
631
  @property
509
- def apiVersion(self):
632
+ def apiVersion(self) -> protobuf.FieldMessage:
510
633
  return self._selector.api_version
511
634
 
512
635
  @apiVersion.setter
513
- def apiVersion(self, apiVersion):
636
+ def apiVersion(self, apiVersion: protobuf.TypeString):
514
637
  self._selector.api_version = apiVersion
515
638
 
516
639
  @property
517
- def kind(self):
640
+ def kind(self) -> protobuf.FieldMessage:
518
641
  return self._selector.kind
519
642
 
520
643
  @kind.setter
521
- def kind(self, kind):
644
+ def kind(self, kind: protobuf.TypeString):
522
645
  self._selector.kind = kind
523
646
 
524
647
  @property
525
- def namespace(self):
648
+ def namespace(self) -> protobuf.FieldMessage:
526
649
  return self._selector.namespace
527
650
 
528
651
  @namespace.setter
529
- def namespace(self, namespace):
652
+ def namespace(self, namespace: protobuf.TypeString):
530
653
  self._selector.namespace = namespace
531
654
 
532
655
  @property
533
- def matchName(self):
656
+ def matchName(self) -> protobuf.FieldMessage:
534
657
  return self._selector.match_name
535
658
 
536
659
  @matchName.setter
537
- def matchName(self, name):
660
+ def matchName(self, name: protobuf.TypeString):
538
661
  self._selector.match_name = name
539
662
 
540
663
  @property
541
- def matchLabels(self):
664
+ def matchLabels(self) -> protobuf.MapMessage:
542
665
  return self._selector.match_labels.labels
543
666
 
544
667
  @matchLabels.setter
545
- def matchLabels(self, labels):
668
+ def matchLabels(
669
+ self,
670
+ labels: typing.Mapping[str, str] | protobuf.Value | None,
671
+ ):
546
672
  self._selector.match_labels.labels()
547
673
  if labels:
548
674
  for entry in labels:
@@ -551,62 +677,67 @@ class RequiredResources:
551
677
  elif isinstance(entry, (list, tuple)):
552
678
  self._selector.match_labels.labels[entry[0]] = entry[1]
553
679
 
554
- def __getitem__(self, ix):
680
+ def __getitem__(self, ix: int) -> RequiredResource:
555
681
  resource = self._cache.get(ix)
556
682
  if not resource:
557
683
  resource = RequiredResource(self.name, ix, self._resources.items[ix])
558
684
  self._cache[ix] = resource
559
685
  return resource
560
686
 
561
- def __bool__(self):
562
- return bool(self._resources.items)
687
+ def __bool__(self) -> bool:
688
+ return bool(len(self))
563
689
 
564
- def __len__(self):
690
+ def __len__(self) -> int:
565
691
  return len(self._resources.items)
566
692
 
567
- def __iter__(self):
693
+ def __iter__(self) -> typing.Generator[RequiredResource]:
568
694
  for ix in range(len(self)):
569
695
  yield self[ix]
570
696
 
571
697
 
572
698
  class RequiredResource:
573
- def __init__(self, name, ix, resource):
574
- self.name = name
575
- self.ix = ix
576
- self.observed = resource.resource
577
- self.apiVersion = self.observed.apiVersion
578
- self.kind = self.observed.kind
579
- self.metadata = self.observed.metadata
580
- self.spec = self.observed.spec
581
- self.type = self.observed.type
582
- self.data = self.observed.data
583
- self.status = self.observed.status
584
- self.conditions = Conditions(resource)
585
- self.connection = self.observed.connection_details
586
-
587
- def __bool__(self):
699
+ def __init__(
700
+ self,
701
+ name: protobuf.TypeString,
702
+ ix: int,
703
+ resource: protobuf.Message,
704
+ ):
705
+ self.name: protobuf.TypeString = name
706
+ self.ix: int = ix
707
+ self.observed: protobuf.Value = cast(protobuf.Value, resource.resource)
708
+ self.apiVersion: protobuf.Value = self.observed.apiVersion
709
+ self.kind: protobuf.Value = self.observed.kind
710
+ self.metadata: protobuf.Value = self.observed.metadata
711
+ self.spec: protobuf.Value = self.observed.spec
712
+ self.type: protobuf.Value = self.observed.type
713
+ self.data: protobuf.Value = self.observed.data
714
+ self.status: protobuf.Value = self.observed.status
715
+ self.conditions: Conditions = Conditions(resource)
716
+ self.connection: protobuf.MapMessage = self.observed.connection_details
717
+
718
+ def __bool__(self) -> bool:
588
719
  return bool(self.observed)
589
720
 
590
721
 
591
722
  class Schemas:
592
- def __init__(self, composite):
593
- self._composite = composite
594
- self._cache = {}
723
+ def __init__(self, composite: BaseComposite):
724
+ self._composite: BaseComposite = composite
725
+ self._cache: dict[protobuf.TypeString, Schema] = {}
595
726
 
596
- def __getattr__(self, key):
727
+ def __getattr__(self, key: protobuf.TypeString) -> Schema:
597
728
  return self[key]
598
729
 
599
- def __getitem__(self, key):
600
- schema = self._cache.get(key)
730
+ def __getitem__(self, key: protobuf.TypeString) -> Schema:
731
+ schema: Schema | None = self._cache.get(key)
601
732
  if not schema:
602
733
  schema = Schema(self._composite, key)
603
734
  self._cache[key] = schema
604
735
  return schema
605
736
 
606
- def __bool__(self):
737
+ def __bool__(self) -> bool:
607
738
  return bool(len(self))
608
739
 
609
- def __len__(self):
740
+ def __len__(self) -> int:
610
741
  names = set()
611
742
  for name, schema in self._composite.request.required_schemas:
612
743
  names.add(name)
@@ -614,15 +745,13 @@ class Schemas:
614
745
  names.add(name)
615
746
  return len(names)
616
747
 
617
- def __contains__(self, key):
748
+ def __contains__(self, key: protobuf.TypeString) -> bool:
618
749
  if key in self._composite.request.required_schemas:
619
750
  return True
620
- if key in self._composite.response.requirements.schemas:
621
- return True
622
- return False
751
+ return key in self._composite.response.requirements.schemas
623
752
 
624
- def __iter__(self):
625
- names = set()
753
+ def __iter__(self) -> typing.Generator[tuple[str, Schema]]:
754
+ names: set[str] = set()
626
755
  for name, schema in self._composite.request.required_schemas:
627
756
  names.add(name)
628
757
  for name, selector in self._composite.response.requirements.schemas:
@@ -632,110 +761,128 @@ class Schemas:
632
761
 
633
762
 
634
763
  class Schema:
635
- def __init__(self, composite, name):
636
- self.name = name
637
- self._selector = composite.response.requirements.schemas[name]
638
- self._schema = composite.request.required_schemas[name].openapi_v3
764
+ def __init__(
765
+ self,
766
+ composite: BaseComposite,
767
+ name: protobuf.TypeString,
768
+ ):
769
+ self.name: protobuf.TypeString = name
770
+ self._selector: protobuf.Message = cast(
771
+ protobuf.Message, composite.response.requirements.schemas[name]
772
+ )
773
+ self._schema: protobuf.Value = cast(
774
+ protobuf.Value, composite.request.required_schemas[name].openapi_v3
775
+ )
639
776
 
640
- def __call__(self, kind=_notset, apiVersion=_notset):
777
+ def __call__(
778
+ self, kind: str | _notset = _notset, apiVersion: str | _notset = _notset
779
+ ) -> typing.Self:
641
780
  self._selector()
642
- if kind != _notset:
781
+ if kind is not _notset:
643
782
  # Allow for apiVersion in the first arg and kind in the second arg
644
- if '/' in kind or kind == 'v1':
645
- if apiVersion != _notset:
783
+ if "/" in kind or kind == "v1":
784
+ if apiVersion is not _notset:
646
785
  self.kind = apiVersion
647
786
  apiVersion = kind
648
787
  else:
649
788
  self.kind = kind
650
- if apiVersion != _notset:
789
+ if apiVersion is not _notset:
651
790
  self.apiVersion = apiVersion
652
791
  return self
653
792
 
654
793
  @property
655
- def apiVersion(self):
656
- return self._selector.api_version
794
+ def apiVersion(self) -> protobuf.FieldMessage:
795
+ return cast(protobuf.FieldMessage, self._selector.api_version)
657
796
 
658
797
  @apiVersion.setter
659
- def apiVersion(self, apiVersion):
798
+ def apiVersion(self, apiVersion: protobuf.TypeString) -> None:
660
799
  self._selector.api_version = apiVersion
661
800
 
662
801
  @property
663
- def kind(self):
664
- return self._selector.kind
802
+ def kind(self) -> protobuf.FieldMessage:
803
+ return cast(protobuf.FieldMessage, self._selector.kind)
665
804
 
666
805
  @kind.setter
667
- def kind(self, kind):
806
+ def kind(self, kind: protobuf.TypeString) -> None:
668
807
  self._selector.kind = kind
669
808
 
670
- def __enter__(self):
809
+ def __enter__(self) -> typing.Self:
671
810
  return self
672
811
 
673
- def __exit__(self, exc_type, exc_value, traceback):
812
+ def __exit__(
813
+ self,
814
+ exc_type: type[BaseException] | None,
815
+ exc_value: BaseException | None,
816
+ traceback: types.TracebackType | None,
817
+ ) -> None:
674
818
  pass
675
819
 
676
- def __aenter__(self):
820
+ def __aenter__(self) -> typing.Self:
677
821
  return self
678
822
 
679
- def __aexit__(self, exc_type, exc_value, traceback):
823
+ def __aexit__(
824
+ self,
825
+ exc_type: type[BaseException] | None,
826
+ exc_value: BaseException | None,
827
+ traceback: types.TracebackType | None,
828
+ ):
680
829
  pass
681
830
 
682
- def __getattr__(self, key):
831
+ def __getattr__(self, key: protobuf.TypeString) -> protobuf.Value:
683
832
  return self[key]
684
833
 
685
- def __getitem__(self, key):
834
+ def __getitem__(self, key: protobuf.TypeString) -> protobuf.Value:
686
835
  return self._schema[key]
687
836
 
688
- def __bool__(self):
689
- return bool(self._schema)
837
+ def __bool__(self) -> bool:
838
+ return bool(len(self))
690
839
 
691
- def __len__(self):
840
+ def __len__(self) -> int:
692
841
  return len(self._schema)
693
842
 
694
- def __contains__(self, item):
843
+ def __contains__(self, item: protobuf.TypeString) -> bool:
695
844
  return item in self._schema
696
845
 
697
- def __iter__(self):
698
- for key, value in self._schema:
699
- yield key, value
846
+ def __iter__(self) -> typing.Generator[str, protobuf.Value]:
847
+ yield from self._schema
700
848
 
701
- def __hash__(self):
849
+ def __hash__(self) -> int:
702
850
  return hash(self._schema)
703
851
 
704
- def __eq__(self, other):
705
- if instance(other, Schema):
852
+ def __eq__(self, other: object) -> bool:
853
+ if isinstance(other, Schema):
706
854
  other = other._schema
707
855
  return self._schema == other
708
856
 
709
- def __str__(self):
857
+ def __str__(self) -> str:
710
858
  return str(self._schema)
711
859
 
712
- def __format__(self, spec='yaml'):
713
- return format(self,_schema, spec)
860
+ def __format__(self, spec: str = "yaml") -> str:
861
+ return format(self._schema, spec)
714
862
 
715
863
 
716
864
  class Conditions:
717
- def __init__(self, observed, response=None):
718
- self._observed = observed
719
- self._response = response
865
+ def __init__(
866
+ self, observed: protobuf.Message, response: protobuf.Message | None = None
867
+ ):
868
+ self._observed: protobuf.Message = observed
869
+ self._response: protobuf.Message | None = response
720
870
 
721
- def __getattr__(self, type):
871
+ def __getattr__(self, type: str) -> Condition:
722
872
  return self[type]
723
873
 
724
- def __getitem__(self, type):
874
+ def __getitem__(self, type: str) -> Condition:
725
875
  return Condition(self, type)
726
876
 
727
- def __bool__(self):
728
- if self._response is not None:
729
- if self._response.conditions:
730
- return True
731
- if self._observed.resource.status.conditions:
877
+ def __bool__(self) -> bool:
878
+ if self._response is not None and len(self._response.conditions):
732
879
  return True
733
- return False
880
+ return bool(len(self))
734
881
 
735
- def __len__(self):
882
+ def __len__(self) -> int:
736
883
  return len(self._types())
737
884
 
738
- def __iter__(self):
885
+ def __iter__(self) -> typing.Generator[Condition]:
739
886
  for type in self._types():
740
887
  yield self[type]
741
888
 
@@ -752,49 +899,55 @@ class Conditions:
752
899
 
753
900
 
754
901
  class Condition(protobuf.ProtobufValue):
755
- def __init__(self, conditions, type):
756
- self._conditions = conditions
757
- self.type = type
902
+ def __init__(self, conditions: Conditions, type: str):
903
+ self._conditions: Conditions = conditions
904
+ self.type: str = type
758
905
 
759
906
  @property
760
- def _protobuf_value(self):
907
+ def _protobuf_value(self) -> dict[str, protobuf.FieldMessage | str]:
761
908
  status = self.status
762
- value = {
763
- 'type': self.type,
764
- 'status': 'Unknown' if status is None else str(status),
765
- 'reason': self.reason or '',
766
- 'message': self.message or '',
909
+ value: dict[str, protobuf.FieldMessage | str] = {
910
+ "type": self.type,
911
+ "status": "Unknown" if status is None else str(status),
912
+ "reason": self.reason or "",
913
+ "message": self.message or "",
767
914
  }
768
915
  time = self.lastTransitionTime
769
916
  if time:
770
- value['lastTransitionTime'] = time.isoformat().replace('+00:00', 'Z')
917
+ value["lastTransitionTime"] = time.isoformat().replace("+00:00", "Z")
771
918
  return value
772
919
 
773
- def __call__(self, reason=_notset, message=_notset, status=_notset, claim=_notset):
774
- self._find_condition(True)
775
- if reason != _notset:
920
+ def __call__(
921
+ self,
922
+ reason: protobuf.TypeString | _notset = _notset,
923
+ message: protobuf.TypeString | _notset = _notset,
924
+ status: bool | protobuf.Value | None | _notset = _notset,
925
+ claim: bool | protobuf.Value | None | _notset = _notset,
926
+ ) -> typing.Self:
927
+ self._ensure_condition()
928
+ if reason is not _notset:
776
929
  self.reason = reason
777
- if message != _notset:
930
+ if message is not _notset:
778
931
  self.message = message
779
- if status != _notset:
932
+ if status is not _notset:
780
933
  self.status = status
781
- if claim != _notset:
934
+ if claim is not _notset:
782
935
  self.claim = claim
783
936
  return self
784
937
 
785
938
  @property
786
- def status(self):
787
- condition = self._find_condition()
939
+ def status(self) -> bool | None:
940
+ condition = self._get_condition()
788
941
  if condition:
789
- if condition.status in (fnv1.Status.STATUS_CONDITION_TRUE, 'True', True):
942
+ if condition.status in (fnv1.Status.STATUS_CONDITION_TRUE, "True", True):
790
943
  return True
791
- if condition.status in (fnv1.Status.STATUS_CONDITION_FALSE, 'False', False):
944
+ if condition.status in (fnv1.Status.STATUS_CONDITION_FALSE, "False", False):
792
945
  return False
793
946
  return None
794
947
 
795
948
  @status.setter
796
- def status(self, status):
797
- condition = self._find_condition(True)
949
+ def status(self, status: bool | protobuf.Value | None) -> None:
950
+ condition = self._ensure_condition()
798
951
  if status:
799
952
  condition.status = fnv1.Status.STATUS_CONDITION_TRUE
800
953
  elif status == None:
@@ -804,31 +957,30 @@ class Condition(protobuf.ProtobufValue):
804
957
  else:
805
958
  condition.status = fnv1.Status.STATUS_CONDITION_FALSE
806
959
 
807
-
808
960
  @property
809
- def reason(self):
810
- condition = self._find_condition()
961
+ def reason(self) -> protobuf.FieldMessage | None:
962
+ condition = self._get_condition()
811
963
  if condition:
812
- return condition.reason
964
+ return cast(protobuf.FieldMessage, condition.reason)
813
965
  return None
814
966
 
815
967
  @reason.setter
816
- def reason(self, reason):
817
- self._find_condition(True).reason = reason
968
+ def reason(self, reason: protobuf.TypeString) -> None:
969
+ self._ensure_condition().reason = reason
818
970
 
819
971
  @property
820
- def message(self):
821
- condition = self._find_condition()
972
+ def message(self) -> protobuf.FieldMessage | None:
973
+ condition = self._get_condition()
822
974
  if condition:
823
- return condition.message
975
+ return cast(protobuf.FieldMessage, condition.message)
824
976
  return None
825
977
 
826
978
  @message.setter
827
- def message(self, message):
828
- self._find_condition(True).message = message
979
+ def message(self, message: protobuf.TypeString) -> None:
980
+ self._ensure_condition().message = message
829
981
 
830
982
  @property
831
- def lastTransitionTime(self):
983
+ def lastTransitionTime(self) -> datetime.datetime | None:
832
984
  for observed in self._conditions._observed.resource.status.conditions:
833
985
  if observed.type == self.type:
834
986
  time = observed.lastTransitionTime
@@ -837,13 +989,16 @@ class Condition(protobuf.ProtobufValue):
837
989
  return None
838
990
 
839
991
  @property
840
- def claim(self):
841
- condition = self._find_condition()
842
- return condition and condition.target == fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
992
+ def claim(self) -> bool:
993
+ condition = self._get_condition()
994
+ return (
995
+ bool(condition)
996
+ and condition.target == fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
997
+ )
843
998
 
844
999
  @claim.setter
845
- def claim(self, claim):
846
- condition = self._find_condition(True)
1000
+ def claim(self, claim: bool | protobuf.Value | None) -> None:
1001
+ condition = self._ensure_condition()
847
1002
  if claim:
848
1003
  condition.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
849
1004
  elif claim == None or (isinstance(claim, protobuf.Value) and claim._isUnknown):
@@ -851,191 +1006,249 @@ class Condition(protobuf.ProtobufValue):
851
1006
  else:
852
1007
  condition.target = fnv1.Target.TARGET_COMPOSITE
853
1008
 
854
- def _find_condition(self, create=False):
1009
+ def _get_condition(self, ensure: bool = False) -> protobuf.Message | None:
855
1010
  if self._conditions._response is not None:
856
1011
  for condition in self._conditions._response.conditions:
857
1012
  if condition.type == self.type:
858
1013
  return condition
859
- if not create:
1014
+ if not ensure:
860
1015
  for observed in self._conditions._observed.resource.status.conditions:
861
1016
  if observed.type == self.type:
862
1017
  return observed
863
- return None
1018
+ return None
1019
+
1020
+ def _ensure_condition(self) -> protobuf.Message:
1021
+ condition = self._get_condition(True)
1022
+ if condition:
1023
+ return condition
864
1024
  if self._conditions._response is None:
865
- raise ValueError('Condition is read only')
1025
+ raise ValueError("Condition is read only")
866
1026
  condition = fnv1.Condition()
867
1027
  condition.type = self.type
868
- return self._conditions._response.conditions.append(condition)
1028
+ self._conditions._response.conditions.append(condition)
1029
+ return cast(protobuf.Message, self._conditions._response.conditions[-1])
869
1030
 
870
1031
 
871
1032
  class Results:
872
- def __init__(self, response):
873
- self._results = response.results
1033
+ def __init__(self, response: protobuf.Message):
1034
+ self._results: protobuf.RepeatedMessage = cast(
1035
+ protobuf.RepeatedMessage, response.results
1036
+ )
874
1037
 
875
- def info(self, reason=_notset, message=_notset, claim=_notset):
876
- result = Result(self._results.append())
1038
+ def info(
1039
+ self,
1040
+ reason: protobuf.TypeString | _notset = _notset,
1041
+ message: protobuf.TypeString | _notset = _notset,
1042
+ claim: bool | protobuf.Value | None | _notset = _notset,
1043
+ ) -> Result:
1044
+ self._results.append()
1045
+ result = Result(self._results[-1])
877
1046
  result.info = True
878
- if reason != _notset:
1047
+ if reason is not _notset:
879
1048
  result.reason = reason
880
- if message != _notset:
1049
+ if message is not _notset:
881
1050
  result.message = message
882
- if claim != _notset:
1051
+ if claim is not _notset:
883
1052
  result.claim = claim
884
1053
  return result
885
1054
 
886
- def warning(self, reason=_notset, message=_notset, claim=_notset):
887
- result = Result(self._results.append())
1055
+ def warning(
1056
+ self,
1057
+ reason: protobuf.TypeString | _notset = _notset,
1058
+ message: protobuf.TypeString | _notset = _notset,
1059
+ claim: bool | protobuf.Value | None | _notset = _notset,
1060
+ ) -> Result:
1061
+ self._results.append()
1062
+ result = Result(self._results[-1])
888
1063
  result.warning = True
889
- if reason != _notset:
1064
+ if reason is not _notset:
890
1065
  result.reason = reason
891
- if message != _notset:
1066
+ if message is not _notset:
892
1067
  result.message = message
893
- if claim != _notset:
1068
+ if claim is not _notset:
894
1069
  result.claim = claim
895
1070
  return result
896
1071
 
897
- def fatal(self, reason=_notset, message=_notset, claim=_notset):
898
- result = Result(self._results.append())
1072
+ def fatal(
1073
+ self,
1074
+ reason: protobuf.TypeString | _notset = _notset,
1075
+ message: protobuf.TypeString | _notset = _notset,
1076
+ claim: bool | protobuf.Value | None | _notset = _notset,
1077
+ ) -> Result:
1078
+ self._results.append()
1079
+ result = Result(self._results[-1])
899
1080
  result.fatal = True
900
- if reason != _notset:
1081
+ if reason is not _notset:
901
1082
  result.reason = reason
902
- if message != _notset:
1083
+ if message is not _notset:
903
1084
  result.message = message
904
- if claim != _notset:
1085
+ if claim is not _notset:
905
1086
  result.claim = claim
906
1087
  return result
907
1088
 
908
- def __bool__(self):
909
- return len(self) > 0
1089
+ def __bool__(self) -> bool:
1090
+ return bool(len(self))
910
1091
 
911
- def __len__(self):
1092
+ def __len__(self) -> int:
912
1093
  return len(self._results)
913
1094
 
914
- def __getitem__(self, key):
1095
+ def __getitem__(self, key: int) -> Result:
915
1096
  if key >= len(self._results):
916
1097
  return Result()
917
1098
  return Result(self._results[key])
918
1099
 
919
- def __iter__(self):
1100
+ def __iter__(self) -> typing.Generator[Result]:
920
1101
  for ix in range(len(self._results)):
921
1102
  yield self[ix]
922
1103
 
923
1104
 
924
1105
  class Result:
925
- def __init__(self, result=None):
926
- self._result = result
1106
+ def __init__(self, result: protobuf.Message | None = None):
1107
+ self._result: protobuf.Message | None = result
927
1108
 
928
- def __bool__(self):
1109
+ def __bool__(self) -> bool:
929
1110
  return self._result is not None
930
1111
 
931
1112
  @property
932
- def info(self):
933
- return bool(self) and self._result.severity == fnv1.Severity.SEVERITY_NORMAL
1113
+ def info(self) -> bool:
1114
+ return (
1115
+ self._result is not None
1116
+ and self._result.severity == fnv1.Severity.SEVERITY_NORMAL
1117
+ )
934
1118
 
935
1119
  @info.setter
936
- def info(self, info):
937
- if bool(self):
1120
+ def info(self, info: bool | protobuf.Value | protobuf.FieldMessage | None) -> None:
1121
+ if self._result is not None:
938
1122
  if info:
939
1123
  self._result.severity = fnv1.Severity.SEVERITY_NORMAL
940
1124
  else:
941
1125
  self._result.severity = fnv1.Severity.SEVERITY_UNSPECIFIED
942
1126
 
943
1127
  @property
944
- def warning(self):
945
- return bool(self) and self._result.severity == fnv1.Severity.SEVERITY_WARNING
1128
+ def warning(self) -> bool:
1129
+ return (
1130
+ self._result is not None
1131
+ and self._result.severity == fnv1.Severity.SEVERITY_WARNING
1132
+ )
946
1133
 
947
1134
  @warning.setter
948
- def warning(self, warning):
949
- if bool(self):
1135
+ def warning(
1136
+ self, warning: bool | protobuf.Value | protobuf.FieldMessage | None
1137
+ ) -> None:
1138
+ if self._result is not None:
950
1139
  if warning:
951
1140
  self._result.severity = fnv1.Severity.SEVERITY_WARNING
952
1141
  else:
953
1142
  self._result.severity = fnv1.Severity.SEVERITY_NORMAL
954
1143
 
955
1144
  @property
956
- def fatal(self):
957
- return bool(self) and self._result.severity == fnv1.Severity.SEVERITY_FATAL
1145
+ def fatal(self) -> bool:
1146
+ return (
1147
+ self._result is not None
1148
+ and self._result.severity == fnv1.Severity.SEVERITY_FATAL
1149
+ )
958
1150
 
959
1151
  @fatal.setter
960
- def fatal(self, fatal):
961
- if bool(self):
1152
+ def fatal(
1153
+ self, fatal: bool | protobuf.Value | protobuf.FieldMessage | None
1154
+ ) -> None:
1155
+ if self._result is not None:
962
1156
  if fatal:
963
1157
  self._result.severity = fnv1.Severity.SEVERITY_FATAL
964
1158
  else:
965
1159
  self._result.severity = fnv1.Severity.SEVERITY_NORMAL
966
1160
 
967
1161
  @property
968
- def reason(self):
969
- return self._result.reason if bool(self) else None
1162
+ def reason(self) -> protobuf.FieldMessage | None:
1163
+ return (
1164
+ cast(protobuf.FieldMessage, self._result.reason)
1165
+ if self._result is not None
1166
+ else None
1167
+ )
970
1168
 
971
1169
  @reason.setter
972
- def reason(self, reason):
973
- if bool(self):
1170
+ def reason(self, reason: protobuf.TypeString):
1171
+ if self._result is not None:
974
1172
  self._result.reason = reason
975
1173
 
976
1174
  @property
977
- def message(self):
978
- return self._result.message if bool(self) else None
1175
+ def message(self) -> protobuf.FieldMessage | None:
1176
+ return (
1177
+ cast(protobuf.FieldMessage, self._result.message)
1178
+ if self._result is not None
1179
+ else None
1180
+ )
979
1181
 
980
1182
  @message.setter
981
- def message(self, message):
982
- if bool(self):
1183
+ def message(self, message: protobuf.TypeString):
1184
+ if self._result is not None:
983
1185
  self._result.message = message
984
1186
 
985
1187
  @property
986
- def claim(self):
987
- return bool(self) and self._result.target == fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
1188
+ def claim(self) -> bool:
1189
+ return (
1190
+ self._result is not None
1191
+ and self._result.target == fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
1192
+ )
988
1193
 
989
1194
  @claim.setter
990
- def claim(self, claim):
991
- if bool(self):
1195
+ def claim(
1196
+ self, claim: bool | protobuf.Value | protobuf.FieldMessage | None
1197
+ ) -> None:
1198
+ if self._result is not None:
992
1199
  if claim:
993
1200
  self._result.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
994
- elif claim == None or (isinstance(claim, protobuf.Value) and claim._isUnknown):
1201
+ elif claim == None or (
1202
+ isinstance(claim, protobuf.Value) and claim._isUnknown
1203
+ ):
995
1204
  self._result.target = fnv1.Target.TARGET_UNSPECIFIED
996
1205
  else:
997
1206
  self._result.target = fnv1.Target.TARGET_COMPOSITE
998
1207
 
999
1208
 
1000
1209
  class _Connection:
1001
- def __init__(self, composite):
1002
- self._set_attribute('_composite', composite)
1003
-
1004
- def _set_attribute(self, key, value):
1005
- self.__dict__[key] = value
1210
+ def __init__(self, composite: BaseComposite):
1211
+ self._composite: BaseComposite = composite
1006
1212
 
1007
1213
  @property
1008
- def _resource_name(self):
1009
- return self._composite.connectionSecret.resourceName or 'connection-secret'
1214
+ def _resource_name(self) -> protobuf.Value | str:
1215
+ return self._composite.connectionSecret.resourceName or "connection-secret"
1010
1216
 
1011
1217
  @property
1012
- def observed(self):
1013
- return self._composite.response.observed.composite.connection_details
1218
+ def observed(self) -> protobuf.MapMessage:
1219
+ return cast(
1220
+ protobuf.MapMessage,
1221
+ self._composite.request.observed.composite.connection_details,
1222
+ )
1014
1223
 
1015
- def __getattr__(self, key):
1224
+ def __getattr__(self, key: protobuf.TypeString) -> protobuf.FieldMessage:
1016
1225
  return self[key]
1017
1226
 
1018
- def __getitem__(self, key):
1019
- return self._composite.response.desired.composite.connection_details[key]
1227
+ def __getitem__(self, key: protobuf.TypeString) -> protobuf.FieldMessage:
1228
+ return cast(
1229
+ protobuf.FieldMessage,
1230
+ self._composite.response.desired.composite.connection_details[key],
1231
+ )
1020
1232
 
1021
- def __bool__(self):
1022
- return bool(self._composite.response.desired.composite.connection_details)
1233
+ def __bool__(self) -> bool:
1234
+ return bool(len(self))
1023
1235
 
1024
- def __len__(self):
1236
+ def __len__(self) -> int:
1025
1237
  return len(self._composite.response.desired.composite.connection_details)
1026
1238
 
1027
- def __contains__(self, key):
1239
+ def __contains__(self, key: protobuf.TypeString) -> bool:
1028
1240
  return key in self._composite.response.desired.composite.connection_details
1029
1241
 
1030
- def __iter__(self):
1031
- for key, value in self._composite.response.desired.composite.connection_details:
1032
- yield key, value
1242
+ def __iter__(self) -> typing.Generator[tuple[str, protobuf.FieldMessage]]:
1243
+ yield from self._composite.response.desired.composite.connection_details
1033
1244
 
1034
- def __str__(self):
1245
+ def __str__(self) -> str:
1035
1246
  return format(self)
1036
1247
 
1037
- def __format__(self, spec='yaml'):
1038
- return format(self._composite.response.desired.composite.connection_details, spec)
1248
+ def __format__(self, spec: str = "yaml") -> str:
1249
+ return format(
1250
+ self._composite.response.desired.composite.connection_details, spec
1251
+ )
1039
1252
 
1040
1253
  def __call__(self, **kwargs):
1041
1254
  self._composite.response.desired.composite.connection_details(**kwargs)
@@ -1045,16 +1258,26 @@ class _Connection:
1045
1258
  for key, value in kwargs.items():
1046
1259
  self[key] = value
1047
1260
 
1048
- def __setattr__(self, key, value):
1049
- self[key] = value
1261
+ def __setattr__(
1262
+ self,
1263
+ key: protobuf.TypeString,
1264
+ value: protobuf.TypeString,
1265
+ ) -> None:
1266
+ if key == "_composite":
1267
+ self.__dict__[str(key)] = value
1268
+ else:
1269
+ self[key] = value
1050
1270
 
1051
- def __setitem__(self, key, value):
1271
+ def __setitem__(
1272
+ self,
1273
+ key: protobuf.TypeString,
1274
+ value: protobuf.TypeString,
1275
+ ) -> None:
1052
1276
  if not isinstance(value, str):
1053
1277
  if value is None:
1054
1278
  return
1055
- if isinstance(value, (protobuf.FieldMessage, protobuf.Value)):
1056
- if not value:
1057
- return
1279
+ if isinstance(value, (protobuf.FieldMessage, protobuf.Value)) and not value:
1280
+ return
1058
1281
  value = str(value)
1059
1282
  self._composite.response.desired.composite.connection_details[key] = value
1060
1283
  if self._composite.crossplane_v1 or not self._composite.connectionSecret.name:
@@ -1062,21 +1285,26 @@ class _Connection:
1062
1285
  if self._resource_name in self._composite.resources:
1063
1286
  secret = self._composite.resources[self._resource_name]
1064
1287
  else:
1065
- secret = self._composite.resources[self._resource_name]('v1', 'Secret')
1066
- if self._composite.connectionSecret.name and len(self._composite.connectionSecret.name):
1288
+ secret = self._composite.resources[self._resource_name]("v1", "Secret")
1289
+ if self._composite.connectionSecret.name and len(
1290
+ self._composite.connectionSecret.name
1291
+ ):
1067
1292
  secret.metadata.name = self._composite.connectionSecret.name
1068
1293
  if not self._composite.metadata.namespace:
1069
1294
  if not self._composite.connectionSecret.namespace:
1070
- self._composite.results.fatal('ConnectionNoNamespace', 'Cluster scoped XR must specify connection secret namespace')
1295
+ self._composite.results.fatal(
1296
+ "ConnectionNoNamespace",
1297
+ "Cluster scoped XR must specify connection secret namespace",
1298
+ )
1071
1299
  return
1072
1300
  secret.metadata.namespace = self._composite.connectionSecret.namespace
1073
- secret.type = 'connection.crossplane.io/v1alpha1'
1301
+ secret.type = "connection.crossplane.io/v1alpha1"
1074
1302
  secret.data[key] = protobuf.B64Encode(value)
1075
1303
 
1076
- def __delattr__(self, key):
1304
+ def __delattr__(self, key: protobuf.TypeString):
1077
1305
  del self[key]
1078
1306
 
1079
- def __delitem__(self, key):
1307
+ def __delitem__(self, key: protobuf.TypeString):
1080
1308
  del self._composite.response.desired.composite.connection_details[key]
1081
1309
  if self._composite.crossplane_v1:
1082
1310
  return