Skip to content

Commit 565fb01

Browse files
author
Patrick J. McNerthney
committed
Rework has Values type can be determined
1 parent e3bf500 commit 565fb01

File tree

6 files changed

+79
-54
lines changed

6 files changed

+79
-54
lines changed

examples/function-go-templating/inline/composition.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ spec:
2323
user = f"test-user-{ix}"
2424
r = self.resources[user]('iam.aws.upbound.io/v1beta1', 'User')
2525
r.metadata.labels['testing.upbound.io/example-name'] = user
26-
r.metadata.labels.dummy = r.observed.resource.metadata.labels.dummy or random.choice(['foo', 'bar', 'baz'])
26+
r.metadata.labels.dummy = r.observed.metadata.labels.dummy or random.choice(['foo', 'bar', 'baz'])
2727
r = self.resources[f"sample-access-key-{ix}"]('iam.aws.upbound.io/v1beta1', 'AccessKey')
2828
r.spec.forProvider.userSelector.matchLabels['testing.upbound.io/example-name'] = user
2929
r.spec.writeConnectionSecretToRef.namespace = 'crossplane.system'

function/composite.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def ready(self):
5454
def ready(self, ready):
5555
if ready:
5656
ready = fnv1.Ready.READY_TRUE
57-
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._type == function.protobuf.Values.Type.UNKNOWN):
57+
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._isUnknown):
5858
ready = fnv1.Ready.READY_UNSPECIFIED
5959
else:
6060
ready = fnv1.Ready.READY_FALSE
@@ -209,7 +209,7 @@ def ready(self):
209209
def ready(self, ready):
210210
if ready:
211211
ready = fnv1.Ready.READY_TRUE
212-
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._type == function.protobuf.Values.Type.UNKNOWN):
212+
elif ready == None or (isinstance(ready, function.protobuf.Values) and ready._isUnknown):
213213
ready = fnv1.Ready.READY_UNSPECIFIED
214214
else:
215215
ready = fnv1.Ready.READY_FALSE
@@ -415,7 +415,7 @@ def claim(self, claim):
415415
if bool(self):
416416
if claim:
417417
self._result.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
418-
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._type == function.protobuf.Values.Type.UNKNOWN):
418+
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._isUnknown):
419419
self._result.target = fnv1.Target.TARGET_UNSPECIFIED
420420
else:
421421
self._result.target = fnv1.Target.TARGET_COMPOSITE
@@ -502,7 +502,7 @@ def status(self, status):
502502
condition.status = fnv1.Status.STATUS_CONDITION_TRUE
503503
elif status == None:
504504
condition.status = fnv1.Status.STATUS_CONDITION_UNKNOWN
505-
elif isinstance(ready, function.protobuf.Values) and ready._type == function.protobuf.Values.Type.UNKNOWN:
505+
elif isinstance(status, function.protobuf.Values) and status._isUnknown:
506506
condition.status = fnv1.Status.STATUS_CONDITION_UNSPECIFIED
507507
else:
508508
condition.status = fnv1.Status.STATUS_CONDITION_FALSE
@@ -549,7 +549,7 @@ def claim(self, claim):
549549
condition = self._find_condition(True)
550550
if claim:
551551
condition.target = fnv1.Target.TARGET_COMPOSITE_AND_CLAIM
552-
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._type == function.protobuf.Values.Type.UNKNOWN):
552+
elif claim == None or (isinstance(claim, function.protobuf.Values) and claim._isUnknown):
553553
condition.target = fnv1.Target.TARGET_UNSPECIFIED
554554
else:
555555
condition.target = fnv1.Target.TARGET_COMPOSITE

function/protobuf.py

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -484,17 +484,17 @@ def __getitem__(self, key):
484484
self._cache[key] = value
485485
return value
486486
if isinstance(key, str):
487-
if self._type != self.Type.MAP:
488-
if self._type != self.Type.UNKNOWN:
487+
if not self._isMap:
488+
if not self._isUnknown:
489489
raise ValueError('Invalid key, must be a str for maps')
490490
self.__dict__['_type'] = self.Type.MAP
491491
if self._values is None or key not in self._values:
492492
struct_value = None
493493
else:
494494
struct_value = self._values.fields[key]
495495
elif isinstance(key, int):
496-
if self._type != self.Type.LIST:
497-
if self._type != self.Type.UNKNOWN:
496+
if not self._isList:
497+
if not self._isUnknown:
498498
raise ValueError('Invalid key, must be an int for lists')
499499
self.__dict__['_type'] = self.Type.LIST
500500
if self._values is None or key >= len(self._values):
@@ -536,24 +536,24 @@ def __len__(self):
536536

537537
def __contains__(self, item):
538538
if self._values is not None:
539-
if self._type == self.Type.MAP:
539+
if self._isMap:
540540
return item in self._values or item in self._unknowns
541-
if self._type == self.Type.LIST:
541+
if self._isList:
542542
for value in self:
543543
if item == value:
544544
return True
545-
if isinstance(item, Values) and item._type == Type.UNKNOWN:
545+
if isinstance(item, Values) and item._isUnknown:
546546
return bool(self._unknowns)
547547
return False
548548

549549
def __iter__(self):
550550
if self._values is not None:
551-
if self._type == self.Type.MAP:
551+
if self._isMap:
552552
for key in self._values:
553553
yield key, self[key]
554554
for key in self._unknowns:
555555
yield key, self[key]
556-
elif self._type == self.Type.LIST:
556+
elif self._isList:
557557
for ix in range(len(self._values)):
558558
yield self[ix]
559559
for ix in sorted(self._unknowns):
@@ -562,9 +562,9 @@ def __iter__(self):
562562

563563
def __hash__(self):
564564
if self._values is not None:
565-
if self._type == self.Type.MAP:
565+
if self._isMap:
566566
return hash(tuple(hash(item) for item in sorted(iter(self), key=lambda item: item[0])))
567-
if self._type == self.Type.LIST:
567+
if self._isList:
568568
return hash(tuple(hash(item) for item in self))
569569
return self._type
570570

@@ -579,13 +579,13 @@ def __eq__(self, other):
579579
return False
580580
if len(self) != len(other):
581581
return False
582-
if self._type == self.Type.MAP:
582+
if self._isMap:
583583
for key, value in self:
584584
if key not in other:
585585
return False
586586
if value != other[key]:
587587
return False
588-
if self._type == self.Type.LIST:
588+
if self._isList:
589589
for ix, value in enumerate(self):
590590
if value != other[ix]:
591591
return False
@@ -604,23 +604,23 @@ def _fullName(self):
604604
parent = self._parent._fullName
605605
if parent:
606606
return f"{parent}.{self._key}"
607-
return self._key
607+
return str(self._key)
608608
return ''
609609

610610
def _create_child(self, key, type):
611611
if self._readOnly:
612612
raise ValueError(f"{self._readOnly} is read only")
613613
if isinstance(key, str):
614-
if self._type != self.Type.MAP:
615-
if self._type != self.Type.UNKNOWN:
614+
if not self._isMap:
615+
if not self._isUnknown:
616616
raise ValueError('Invalid key, must be a str for maps')
617617
self.__dict__['_type'] = self.Type.MAP
618618
if self._values is None:
619619
self.__dict__['_values'] = self._parent._create_child(self._key, self._type)
620620
struct_value = self._values.fields[key]
621621
elif isinstance(key, int):
622-
if self._type != self.Type.LIST:
623-
if self._type != self.Type.UNKNOWN:
622+
if not self._isList:
623+
if not self._isUnknown:
624624
raise ValueError('Invalid key, must be an int for lists')
625625
self.__dict__['_type'] = self.Type.LIST
626626
if self._values is None:
@@ -646,8 +646,8 @@ def __call__(self, *args, **kwargs):
646646
self._cache.clear()
647647
self._unknowns.clear()
648648
if len(kwargs):
649-
if self._type != self.Type.MAP:
650-
if self._type != self.Type.UNKNOWN:
649+
if not self._isMap:
650+
if not self._isUnknown:
651651
raise ValueError('Cannot specify kwargs on lists')
652652
self.__dict__['_type'] = self.Type.MAP
653653
if len(args):
@@ -658,8 +658,8 @@ def __call__(self, *args, **kwargs):
658658
for key, value in kwargs.items():
659659
self[key] = value
660660
elif len(args):
661-
if self._type != self.Type.LIST:
662-
if self._type != self.Type.UNKNOWN:
661+
if not self._isList:
662+
if not self._isUnknown:
663663
raise ValueError('Cannot specify args on maps')
664664
self.__dict__['_type'] = self.Type.LIST
665665
if len(kwargs):
@@ -670,8 +670,8 @@ def __call__(self, *args, **kwargs):
670670
for key in range(len(args)):
671671
self[key] = args[key]
672672
else:
673-
if self._type != self.Type.MAP:
674-
if self._type != self.Type.UNKNOWN:
673+
if not self._isMap:
674+
if not self._isUnknown:
675675
self.__dict__['_type'] = self.Type.MAP # Assume a map is wanted
676676
if self._values is None:
677677
self.__dict__['_values'] = self._parent._create_child(self._key, self._type)
@@ -685,16 +685,16 @@ def __setitem__(self, key, value):
685685
if self._readOnly:
686686
raise ValueError(f"{self._readOnly} is read only")
687687
if isinstance(key, str):
688-
if self._type != self.Type.MAP:
689-
if self._type != self.Type.UNKNOWN:
688+
if not self._isMap:
689+
if not self._isUnknown:
690690
raise ValueError('Invalid key, must be a str for maps')
691691
self.__dict__['_type'] = self.Type.MAP
692692
if self._values is None:
693693
self.__dict__['_values'] = self._parent._create_child(self._key, self._type)
694694
values = self._values.fields
695695
elif isinstance(key, int):
696-
if self._type != self.Type.LIST:
697-
if self._type != self.Type.UNKNOWN:
696+
if not self._isList:
697+
if not self._isUnknown:
698698
raise ValueError('Invalid key, must be an int for lists')
699699
self.__dict__['_type'] = self.Type.LIST
700700
if self._values is None:
@@ -727,24 +727,28 @@ def __setitem__(self, key, value):
727727
for k, v in enumerate(value):
728728
sv[k] = v
729729
elif isinstance(value, Values):
730-
if value._type == value.Type.MAP:
730+
if value._isMap:
731731
values[key].struct_value.Clear()
732732
sv = self[key]
733733
for k, v in value:
734734
sv[k] = v
735-
elif value._type == value.Type.LIST:
735+
elif value._isList:
736736
values[key].list_value.Clear()
737737
sv = self[key]
738738
for k, v in enumerate(value):
739739
sv[k] = v
740740
else:
741741
self._unknowns.add(key)
742-
if self._type == self.Type.MAP:
742+
if self._isMap:
743743
if key in values:
744744
del values[key]
745-
else:
745+
elif self._isList:
746746
if key < len(values):
747-
del values[key]
747+
values[key].Clear()
748+
for ix in reversed(range(len(values))):
749+
if ix not in self._unknowns:
750+
break
751+
del values[ix]
748752
else:
749753
raise ValueError('Unexpected type')
750754

@@ -755,8 +759,8 @@ def __delitem__(self, key):
755759
if self._readOnly:
756760
raise ValueError(f"{self._readOnly} is read only")
757761
if isinstance(key, str):
758-
if self._type != self.Type.MAP:
759-
if self._type != self.Type.UNKNOWN:
762+
if not self._isMap:
763+
if not self._isUnknown:
760764
raise ValueError('Invalid key, must be a str for maps')
761765
self.__dict__['_type'] = self.Type.MAP
762766
if self._values is not None:
@@ -765,27 +769,48 @@ def __delitem__(self, key):
765769
self._cache.pop(key, None)
766770
self._unknowns.discard(key)
767771
elif isinstance(key, int):
768-
if self._type != self.Type.LIST:
769-
if self._type != self.Type.UNKNOWN:
772+
if not self._isList:
773+
if not self._isUnknown:
770774
raise ValueError('Invalid key, must be an int for lists')
771775
self.__dict__['_type'] = self.Type.LIST
772776
if self._values is not None:
773777
if key < len(self._values):
774-
self._values.values[key].Clear()
778+
del self._values[key]
775779
self._cache.pop(key, None)
776780
self._unknowns.discard(key)
781+
for ix in sorted([ix in self._unknowns]):
782+
if ix > key:
783+
self._cache.pop(ix, None)
784+
self._unknowns.add(ix - 1)
785+
self._unknowns.disacard(ix)
786+
for ix in reversed(range(len(self._values))):
787+
if ix not in self._unknowns:
788+
break
789+
del self._values[ix]
777790
else:
778791
raise ValueError('Unexpected key type')
779792

793+
@property
794+
def _isUnknown(self):
795+
return self._type == self.Type.UNKNOWN
796+
797+
@property
798+
def _isMap(self):
799+
return self._type == self.Type.MAP
800+
801+
@property
802+
def _isList(self):
803+
return self._type == self.Type.LIST
804+
780805
@property
781806
def _hasUnknowns(self):
782807
if self._unknowns:
783808
return True
784-
if self._type == self.Type.MAP:
809+
if self._isMap:
785810
for key, value in self:
786811
if isinstance(value, Values) and value._hasUnknowns:
787812
return True
788-
elif self._type == self.Type.LIST:
813+
elif self._isList:
789814
for value in self:
790815
if isinstance(value, Values) and value._hasUnknowns:
791816
return True
@@ -794,13 +819,13 @@ def _hasUnknowns(self):
794819
def _patchUnknowns(self, patches):
795820
for key in [key for key in self._unknowns]:
796821
self[key] = patches[key]
797-
if self._type == self.Type.MAP:
822+
if self._isMap:
798823
for key, value in self:
799824
if isinstance(value, Values) and len(value):
800825
patch = patches[key]
801826
if isinstance(patch, Values) and patch._type == value._type and len(patch):
802827
value._patchUnknowns(patch)
803-
elif self._type == self.Type.LIST:
828+
elif self._isList:
804829
for ix, value in enumerate(self):
805830
if isinstance(value, Values) and len(value):
806831
patch = patches[ix]
@@ -835,11 +860,11 @@ def default(self, object):
835860
return [value for value in object]
836861
return None
837862
if isinstance(object, Values):
838-
if object._type == Values.Type.MAP:
863+
if object._isMap:
839864
return {key: value for key, value in object}
840-
if object._type == Values.Type.LIST:
865+
if object._isList:
841866
return [value for value in object]
842-
if object._type == Values.Type.UNKNOWN:
867+
if object._isUnknown:
843868
return '<<UNKNOWN>>'
844869
return '<<UNEXPECTED>>'
845870
if isinstance(object, datetime.datetime):
@@ -859,11 +884,11 @@ def represent_message_list(self, messages):
859884
return self.represent_list([value for value in messages])
860885

861886
def represent_values(self, values):
862-
if values._type == Values.Type.MAP:
887+
if values._isMap:
863888
return self.represent_dict({key: value for key, value in values})
864-
if values._type == Values.Type.LIST:
889+
if values._isList:
865890
return self.represent_list([value for value in values])
866-
if values._type == Values.Type.UNKNOWN:
891+
if values._isUnknown:
867892
return self.represent_scalar('tag:yaml.org,2002:str', '<<UNKNOWN>>')
868893
return self.represent_scalar('tag:yaml.org,2002:str', '<<UNEXPECTED>>')
869894

0 commit comments

Comments
 (0)