localstack-core 4.4.1.dev62__py3-none-any.whl → 4.4.1.dev64__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.
@@ -23,6 +23,9 @@ class NothingType:
23
23
  cls._singleton = super().__new__(cls)
24
24
  return cls._singleton
25
25
 
26
+ def __eq__(self, other):
27
+ return is_nothing(other)
28
+
26
29
  def __str__(self):
27
30
  return repr(self)
28
31
 
@@ -35,11 +38,46 @@ class NothingType:
35
38
  def __iter__(self):
36
39
  return iter(())
37
40
 
41
+ def __contains__(self, item):
42
+ return False
43
+
38
44
 
39
45
  Maybe = Union[T, NothingType]
40
46
  Nothing = NothingType()
41
47
 
42
48
 
49
+ def is_nothing(value: Any) -> bool:
50
+ return isinstance(value, NothingType)
51
+
52
+
53
+ def is_created(before: Maybe[Any], after: Maybe[Any]) -> bool:
54
+ return is_nothing(before) and not is_nothing(after)
55
+
56
+
57
+ def is_removed(before: Maybe[Any], after: Maybe[Any]) -> bool:
58
+ return not is_nothing(before) and is_nothing(after)
59
+
60
+
61
+ def parent_change_type_of(children: list[Maybe[ChangeSetEntity]]):
62
+ change_types = [c.change_type for c in children if not is_nothing(c)]
63
+ if not change_types:
64
+ return ChangeType.UNCHANGED
65
+ first_type = change_types[0]
66
+ if all(ct == first_type for ct in change_types):
67
+ return first_type
68
+ return ChangeType.MODIFIED
69
+
70
+
71
+ def change_type_of(before: Maybe[Any], after: Maybe[Any], children: list[Maybe[ChangeSetEntity]]):
72
+ if is_created(before, after):
73
+ change_type = ChangeType.CREATED
74
+ elif is_removed(before, after):
75
+ change_type = ChangeType.REMOVED
76
+ else:
77
+ change_type = parent_change_type_of(children)
78
+ return change_type
79
+
80
+
43
81
  class Scope(str):
44
82
  _ROOT_SCOPE: Final[str] = str()
45
83
  _SEPARATOR: Final[str] = "/"
@@ -66,14 +104,6 @@ class ChangeType(enum.Enum):
66
104
  def __str__(self):
67
105
  return self.value
68
106
 
69
- def for_child(self, child_change_type: ChangeType) -> ChangeType:
70
- if child_change_type == self:
71
- return self
72
- elif self == ChangeType.UNCHANGED:
73
- return child_change_type
74
- else:
75
- return ChangeType.MODIFIED
76
-
77
107
 
78
108
  class ChangeSetEntity(abc.ABC):
79
109
  scope: Final[Scope]
@@ -122,13 +152,13 @@ class NodeTemplate(ChangeSetNode):
122
152
  def __init__(
123
153
  self,
124
154
  scope: Scope,
125
- change_type: ChangeType,
126
155
  mappings: NodeMappings,
127
156
  parameters: NodeParameters,
128
157
  conditions: NodeConditions,
129
158
  resources: NodeResources,
130
159
  outputs: NodeOutputs,
131
160
  ):
161
+ change_type = parent_change_type_of([resources, outputs])
132
162
  super().__init__(scope=scope, change_type=change_type)
133
163
  self.mappings = mappings
134
164
  self.parameters = parameters
@@ -151,17 +181,17 @@ class NodeParameter(ChangeSetNode):
151
181
  name: Final[str]
152
182
  type_: Final[ChangeSetEntity]
153
183
  dynamic_value: Final[ChangeSetEntity]
154
- default_value: Final[Optional[ChangeSetEntity]]
184
+ default_value: Final[Maybe[ChangeSetEntity]]
155
185
 
156
186
  def __init__(
157
187
  self,
158
188
  scope: Scope,
159
- change_type: ChangeType,
160
189
  name: str,
161
190
  type_: ChangeSetEntity,
162
191
  dynamic_value: ChangeSetEntity,
163
- default_value: Optional[ChangeSetEntity],
192
+ default_value: Maybe[ChangeSetEntity],
164
193
  ):
194
+ change_type = parent_change_type_of([type_, default_value, dynamic_value])
165
195
  super().__init__(scope=scope, change_type=change_type)
166
196
  self.name = name
167
197
  self.type_ = type_
@@ -172,7 +202,8 @@ class NodeParameter(ChangeSetNode):
172
202
  class NodeParameters(ChangeSetNode):
173
203
  parameters: Final[list[NodeParameter]]
174
204
 
175
- def __init__(self, scope: Scope, change_type: ChangeType, parameters: list[NodeParameter]):
205
+ def __init__(self, scope: Scope, parameters: list[NodeParameter]):
206
+ change_type = parent_change_type_of(parameters)
176
207
  super().__init__(scope=scope, change_type=change_type)
177
208
  self.parameters = parameters
178
209
 
@@ -181,8 +212,8 @@ class NodeMapping(ChangeSetNode):
181
212
  name: Final[str]
182
213
  bindings: Final[NodeObject]
183
214
 
184
- def __init__(self, scope: Scope, change_type: ChangeType, name: str, bindings: NodeObject):
185
- super().__init__(scope=scope, change_type=change_type)
215
+ def __init__(self, scope: Scope, name: str, bindings: NodeObject):
216
+ super().__init__(scope=scope, change_type=bindings.change_type)
186
217
  self.name = name
187
218
  self.bindings = bindings
188
219
 
@@ -190,7 +221,8 @@ class NodeMapping(ChangeSetNode):
190
221
  class NodeMappings(ChangeSetNode):
191
222
  mappings: Final[list[NodeMapping]]
192
223
 
193
- def __init__(self, scope: Scope, change_type: ChangeType, mappings: list[NodeMapping]):
224
+ def __init__(self, scope: Scope, mappings: list[NodeMapping]):
225
+ change_type = parent_change_type_of(mappings)
194
226
  super().__init__(scope=scope, change_type=change_type)
195
227
  self.mappings = mappings
196
228
 
@@ -198,18 +230,18 @@ class NodeMappings(ChangeSetNode):
198
230
  class NodeOutput(ChangeSetNode):
199
231
  name: Final[str]
200
232
  value: Final[ChangeSetEntity]
201
- export: Final[Optional[ChangeSetEntity]]
202
- condition_reference: Final[Optional[TerminalValue]]
233
+ export: Final[Maybe[ChangeSetEntity]]
234
+ condition_reference: Final[Maybe[TerminalValue]]
203
235
 
204
236
  def __init__(
205
237
  self,
206
238
  scope: Scope,
207
- change_type: ChangeType,
208
239
  name: str,
209
240
  value: ChangeSetEntity,
210
- export: Optional[ChangeSetEntity],
211
- conditional_reference: Optional[TerminalValue],
241
+ export: Maybe[ChangeSetEntity],
242
+ conditional_reference: Maybe[TerminalValue],
212
243
  ):
244
+ change_type = parent_change_type_of([value, export, conditional_reference])
213
245
  super().__init__(scope=scope, change_type=change_type)
214
246
  self.name = name
215
247
  self.value = value
@@ -220,7 +252,8 @@ class NodeOutput(ChangeSetNode):
220
252
  class NodeOutputs(ChangeSetNode):
221
253
  outputs: Final[list[NodeOutput]]
222
254
 
223
- def __init__(self, scope: Scope, change_type: ChangeType, outputs: list[NodeOutput]):
255
+ def __init__(self, scope: Scope, outputs: list[NodeOutput]):
256
+ change_type = parent_change_type_of(outputs)
224
257
  super().__init__(scope=scope, change_type=change_type)
225
258
  self.outputs = outputs
226
259
 
@@ -229,8 +262,8 @@ class NodeCondition(ChangeSetNode):
229
262
  name: Final[str]
230
263
  body: Final[ChangeSetEntity]
231
264
 
232
- def __init__(self, scope: Scope, change_type: ChangeType, name: str, body: ChangeSetEntity):
233
- super().__init__(scope=scope, change_type=change_type)
265
+ def __init__(self, scope: Scope, name: str, body: ChangeSetEntity):
266
+ super().__init__(scope=scope, change_type=body.change_type)
234
267
  self.name = name
235
268
  self.body = body
236
269
 
@@ -238,7 +271,8 @@ class NodeCondition(ChangeSetNode):
238
271
  class NodeConditions(ChangeSetNode):
239
272
  conditions: Final[list[NodeCondition]]
240
273
 
241
- def __init__(self, scope: Scope, change_type: ChangeType, conditions: list[NodeCondition]):
274
+ def __init__(self, scope: Scope, conditions: list[NodeCondition]):
275
+ change_type = parent_change_type_of(conditions)
242
276
  super().__init__(scope=scope, change_type=change_type)
243
277
  self.conditions = conditions
244
278
 
@@ -246,7 +280,8 @@ class NodeConditions(ChangeSetNode):
246
280
  class NodeResources(ChangeSetNode):
247
281
  resources: Final[list[NodeResource]]
248
282
 
249
- def __init__(self, scope: Scope, change_type: ChangeType, resources: list[NodeResource]):
283
+ def __init__(self, scope: Scope, resources: list[NodeResource]):
284
+ change_type = parent_change_type_of(resources)
250
285
  super().__init__(scope=scope, change_type=change_type)
251
286
  self.resources = resources
252
287
 
@@ -254,9 +289,9 @@ class NodeResources(ChangeSetNode):
254
289
  class NodeResource(ChangeSetNode):
255
290
  name: Final[str]
256
291
  type_: Final[ChangeSetTerminal]
257
- condition_reference: Final[Optional[TerminalValue]]
258
292
  properties: Final[NodeProperties]
259
- depends_on: Final[Optional[NodeDependsOn]]
293
+ condition_reference: Final[Maybe[TerminalValue]]
294
+ depends_on: Final[Maybe[NodeDependsOn]]
260
295
 
261
296
  def __init__(
262
297
  self,
@@ -265,8 +300,8 @@ class NodeResource(ChangeSetNode):
265
300
  name: str,
266
301
  type_: ChangeSetTerminal,
267
302
  properties: NodeProperties,
268
- condition_reference: Optional[TerminalValue],
269
- depends_on: Optional[NodeDependsOn],
303
+ condition_reference: Maybe[TerminalValue],
304
+ depends_on: Maybe[NodeDependsOn],
270
305
  ):
271
306
  super().__init__(scope=scope, change_type=change_type)
272
307
  self.name = name
@@ -279,7 +314,8 @@ class NodeResource(ChangeSetNode):
279
314
  class NodeProperties(ChangeSetNode):
280
315
  properties: Final[list[NodeProperty]]
281
316
 
282
- def __init__(self, scope: Scope, change_type: ChangeType, properties: list[NodeProperty]):
317
+ def __init__(self, scope: Scope, properties: list[NodeProperty]):
318
+ change_type = parent_change_type_of(properties)
283
319
  super().__init__(scope=scope, change_type=change_type)
284
320
  self.properties = properties
285
321
 
@@ -287,8 +323,8 @@ class NodeProperties(ChangeSetNode):
287
323
  class NodeDependsOn(ChangeSetNode):
288
324
  depends_on: Final[NodeArray]
289
325
 
290
- def __init__(self, scope: Scope, change_type: ChangeType, depends_on: NodeArray):
291
- super().__init__(scope=scope, change_type=change_type)
326
+ def __init__(self, scope: Scope, depends_on: NodeArray):
327
+ super().__init__(scope=scope, change_type=depends_on.change_type)
292
328
  self.depends_on = depends_on
293
329
 
294
330
 
@@ -296,8 +332,8 @@ class NodeProperty(ChangeSetNode):
296
332
  name: Final[str]
297
333
  value: Final[ChangeSetEntity]
298
334
 
299
- def __init__(self, scope: Scope, change_type: ChangeType, name: str, value: ChangeSetEntity):
300
- super().__init__(scope=scope, change_type=change_type)
335
+ def __init__(self, scope: Scope, name: str, value: ChangeSetEntity):
336
+ super().__init__(scope=scope, change_type=value.change_type)
301
337
  self.name = name
302
338
  self.value = value
303
339
 
@@ -442,9 +478,9 @@ class ChangeSetModel:
442
478
  terminal_value = self._visited_scopes.get(scope)
443
479
  if isinstance(terminal_value, TerminalValue):
444
480
  return terminal_value
445
- if self._is_created(before=before_value, after=after_value):
481
+ if is_created(before=before_value, after=after_value):
446
482
  terminal_value = TerminalValueCreated(scope=scope, value=after_value)
447
- elif self._is_removed(before=before_value, after=after_value):
483
+ elif is_removed(before=before_value, after=after_value):
448
484
  terminal_value = TerminalValueRemoved(scope=scope, value=before_value)
449
485
  elif before_value == after_value:
450
486
  terminal_value = TerminalValueUnchanged(scope=scope, value=before_value)
@@ -468,9 +504,9 @@ class ChangeSetModel:
468
504
  arguments = self._visit_value(
469
505
  scope=scope, before_value=before_arguments, after_value=after_arguments
470
506
  )
471
- if self._is_created(before=before_arguments, after=after_arguments):
507
+ if is_created(before=before_arguments, after=after_arguments):
472
508
  change_type = ChangeType.CREATED
473
- elif self._is_removed(before=before_arguments, after=after_arguments):
509
+ elif is_removed(before=before_arguments, after=after_arguments):
474
510
  change_type = ChangeType.REMOVED
475
511
  else:
476
512
  function_name = intrinsic_function.replace("::", "_")
@@ -588,8 +624,7 @@ class ChangeSetModel:
588
624
  )
589
625
  if not isinstance(node_condition, NodeCondition):
590
626
  raise RuntimeError()
591
- change_types = [node_condition.change_type, *arguments.array[1:]]
592
- change_type = self._change_type_for_parent_of(change_types=change_types)
627
+ change_type = parent_change_type_of([node_condition, *arguments[1:]])
593
628
  return change_type
594
629
 
595
630
  def _visit_array(
@@ -604,12 +639,7 @@ class ChangeSetModel:
604
639
  scope=value_scope, before_value=before_value, after_value=after_value
605
640
  )
606
641
  array.append(value)
607
- if self._is_created(before=before_array, after=after_array):
608
- change_type = ChangeType.CREATED
609
- elif self._is_removed(before=before_array, after=after_array):
610
- change_type = ChangeType.REMOVED
611
- else:
612
- change_type = self._change_type_for_parent_of([value.change_type for value in array])
642
+ change_type = change_type_of(before_array, after_array, array)
613
643
  return NodeArray(scope=scope, change_type=change_type, array=array)
614
644
 
615
645
  def _visit_object(
@@ -618,12 +648,6 @@ class ChangeSetModel:
618
648
  node_object = self._visited_scopes.get(scope)
619
649
  if isinstance(node_object, NodeObject):
620
650
  return node_object
621
- if self._is_created(before=before_object, after=after_object):
622
- change_type = ChangeType.CREATED
623
- elif self._is_removed(before=before_object, after=after_object):
624
- change_type = ChangeType.REMOVED
625
- else:
626
- change_type = ChangeType.UNCHANGED
627
651
  binding_names = self._safe_keys_of(before_object, after_object)
628
652
  bindings: dict[str, ChangeSetEntity] = dict()
629
653
  for binding_name in binding_names:
@@ -634,7 +658,7 @@ class ChangeSetModel:
634
658
  scope=binding_scope, before_value=before_value, after_value=after_value
635
659
  )
636
660
  bindings[binding_name] = value
637
- change_type = change_type.for_child(value.change_type)
661
+ change_type = change_type_of(before_object, after_object, list(bindings.values()))
638
662
  node_object = NodeObject(scope=scope, change_type=change_type, bindings=bindings)
639
663
  self._visited_scopes[scope] = node_object
640
664
  return node_object
@@ -662,9 +686,9 @@ class ChangeSetModel:
662
686
  unset = object()
663
687
  if before_type_name == after_type_name:
664
688
  dominant_value = before_value
665
- elif self._is_created(before=before_value, after=after_value):
689
+ elif is_created(before=before_value, after=after_value):
666
690
  dominant_value = after_value
667
- elif self._is_removed(before=before_value, after=after_value):
691
+ elif is_removed(before=before_value, after=after_value):
668
692
  dominant_value = before_value
669
693
  else:
670
694
  dominant_value = unset
@@ -715,9 +739,7 @@ class ChangeSetModel:
715
739
  value = self._visit_value(
716
740
  scope=scope, before_value=before_property, after_value=after_property
717
741
  )
718
- node_property = NodeProperty(
719
- scope=scope, change_type=value.change_type, name=property_name, value=value
720
- )
742
+ node_property = NodeProperty(scope=scope, name=property_name, value=value)
721
743
  self._visited_scopes[scope] = node_property
722
744
  return node_property
723
745
 
@@ -727,10 +749,8 @@ class ChangeSetModel:
727
749
  node_properties = self._visited_scopes.get(scope)
728
750
  if isinstance(node_properties, NodeProperties):
729
751
  return node_properties
730
- # TODO: double check we are sure not to have this be a NodeObject
731
752
  property_names: list[str] = self._safe_keys_of(before_properties, after_properties)
732
753
  properties: list[NodeProperty] = list()
733
- change_type = ChangeType.UNCHANGED
734
754
  for property_name in property_names:
735
755
  property_scope, (before_property, after_property) = self._safe_access_in(
736
756
  scope, property_name, before_properties, after_properties
@@ -742,10 +762,7 @@ class ChangeSetModel:
742
762
  after_property=after_property,
743
763
  )
744
764
  properties.append(property_)
745
- change_type = change_type.for_child(property_.change_type)
746
- node_properties = NodeProperties(
747
- scope=scope, change_type=change_type, properties=properties
748
- )
765
+ node_properties = NodeProperties(scope=scope, properties=properties)
749
766
  self._visited_scopes[scope] = node_properties
750
767
  return node_properties
751
768
 
@@ -767,13 +784,6 @@ class ChangeSetModel:
767
784
  if isinstance(node_resource, NodeResource):
768
785
  return node_resource
769
786
 
770
- if self._is_created(before=before_resource, after=after_resource):
771
- change_type = ChangeType.CREATED
772
- elif self._is_removed(before=before_resource, after=after_resource):
773
- change_type = ChangeType.REMOVED
774
- else:
775
- change_type = ChangeType.UNCHANGED
776
-
777
787
  scope_type, (before_type, after_type) = self._safe_access_in(
778
788
  scope, TypeKey, before_resource, after_resource
779
789
  )
@@ -781,7 +791,7 @@ class ChangeSetModel:
781
791
  scope=scope_type, before_type=before_type, after_type=after_type
782
792
  )
783
793
 
784
- condition_reference = None
794
+ condition_reference = Nothing
785
795
  scope_condition, (before_condition, after_condition) = self._safe_access_in(
786
796
  scope, ConditionKey, before_resource, after_resource
787
797
  )
@@ -790,7 +800,7 @@ class ChangeSetModel:
790
800
  scope_condition, before_condition, after_condition
791
801
  )
792
802
 
793
- depends_on = None
803
+ depends_on = Nothing
794
804
  scope_depends_on, (before_depends_on, after_depends_on) = self._safe_access_in(
795
805
  scope, DependsOnKey, before_resource, after_resource
796
806
  )
@@ -807,10 +817,10 @@ class ChangeSetModel:
807
817
  before_properties=before_properties,
808
818
  after_properties=after_properties,
809
819
  )
810
- if properties.properties:
811
- # Properties were defined in the before or after template, thus must play a role
812
- # in affecting the change type of this resource.
813
- change_type = change_type.for_child(properties.change_type)
820
+
821
+ change_type = change_type_of(
822
+ before_resource, after_resource, [properties, condition_reference, depends_on]
823
+ )
814
824
  node_resource = NodeResource(
815
825
  scope=scope,
816
826
  change_type=change_type,
@@ -827,7 +837,6 @@ class ChangeSetModel:
827
837
  self, scope: Scope, before_resources: Maybe[dict], after_resources: Maybe[dict]
828
838
  ) -> NodeResources:
829
839
  # TODO: investigate type changes behavior.
830
- change_type = ChangeType.UNCHANGED
831
840
  resources: list[NodeResource] = list()
832
841
  resource_names = self._safe_keys_of(before_resources, after_resources)
833
842
  for resource_name in resource_names:
@@ -841,8 +850,7 @@ class ChangeSetModel:
841
850
  after_resource=after_resource,
842
851
  )
843
852
  resources.append(resource)
844
- change_type = change_type.for_child(resource.change_type)
845
- return NodeResources(scope=scope, change_type=change_type, resources=resources)
853
+ return NodeResources(scope=scope, resources=resources)
846
854
 
847
855
  def _visit_mapping(
848
856
  self, scope: Scope, name: str, before_mapping: Maybe[dict], after_mapping: Maybe[dict]
@@ -850,14 +858,11 @@ class ChangeSetModel:
850
858
  bindings = self._visit_object(
851
859
  scope=scope, before_object=before_mapping, after_object=after_mapping
852
860
  )
853
- return NodeMapping(
854
- scope=scope, change_type=bindings.change_type, name=name, bindings=bindings
855
- )
861
+ return NodeMapping(scope=scope, name=name, bindings=bindings)
856
862
 
857
863
  def _visit_mappings(
858
864
  self, scope: Scope, before_mappings: Maybe[dict], after_mappings: Maybe[dict]
859
865
  ) -> NodeMappings:
860
- change_type = ChangeType.UNCHANGED
861
866
  mappings: list[NodeMapping] = list()
862
867
  mapping_names = self._safe_keys_of(before_mappings, after_mappings)
863
868
  for mapping_name in mapping_names:
@@ -871,8 +876,7 @@ class ChangeSetModel:
871
876
  after_mapping=after_mapping,
872
877
  )
873
878
  mappings.append(mapping)
874
- change_type = change_type.for_child(mapping.change_type)
875
- return NodeMappings(scope=scope, change_type=change_type, mappings=mappings)
879
+ return NodeMappings(scope=scope, mappings=mappings)
876
880
 
877
881
  def _visit_dynamic_parameter(self, parameter_name: str) -> ChangeSetEntity:
878
882
  scope = Scope("Dynamic").open_scope("Parameters")
@@ -907,13 +911,8 @@ class ChangeSetModel:
907
911
 
908
912
  dynamic_value = self._visit_dynamic_parameter(parameter_name=parameter_name)
909
913
 
910
- change_type = self._change_type_for_parent_of(
911
- change_types=[type_.change_type, default_value.change_type, dynamic_value.change_type]
912
- )
913
-
914
914
  node_parameter = NodeParameter(
915
915
  scope=scope,
916
- change_type=change_type,
917
916
  name=parameter_name,
918
917
  type_=type_,
919
918
  default_value=default_value,
@@ -930,7 +929,6 @@ class ChangeSetModel:
930
929
  return node_parameters
931
930
  parameter_names: list[str] = self._safe_keys_of(before_parameters, after_parameters)
932
931
  parameters: list[NodeParameter] = list()
933
- change_type = ChangeType.UNCHANGED
934
932
  for parameter_name in parameter_names:
935
933
  parameter_scope, (before_parameter, after_parameter) = self._safe_access_in(
936
934
  scope, parameter_name, before_parameters, after_parameters
@@ -942,10 +940,7 @@ class ChangeSetModel:
942
940
  after_parameter=after_parameter,
943
941
  )
944
942
  parameters.append(parameter)
945
- change_type = change_type.for_child(parameter.change_type)
946
- node_parameters = NodeParameters(
947
- scope=scope, change_type=change_type, parameters=parameters
948
- )
943
+ node_parameters = NodeParameters(scope=scope, parameters=parameters)
949
944
  self._visited_scopes[scope] = node_parameters
950
945
  return node_parameters
951
946
 
@@ -976,9 +971,7 @@ class ChangeSetModel:
976
971
  node_array = self._visit_array(
977
972
  scope=scope, before_array=before_depends_on, after_array=after_depends_on
978
973
  )
979
- node_depends_on = NodeDependsOn(
980
- scope=scope, change_type=node_array.change_type, depends_on=node_array
981
- )
974
+ node_depends_on = NodeDependsOn(scope=scope, depends_on=node_array)
982
975
  return node_depends_on
983
976
 
984
977
  def _visit_condition(
@@ -994,9 +987,7 @@ class ChangeSetModel:
994
987
  body = self._visit_value(
995
988
  scope=scope, before_value=before_condition, after_value=after_condition
996
989
  )
997
- node_condition = NodeCondition(
998
- scope=scope, change_type=body.change_type, name=condition_name, body=body
999
- )
990
+ node_condition = NodeCondition(scope=scope, name=condition_name, body=body)
1000
991
  self._visited_scopes[scope] = node_condition
1001
992
  return node_condition
1002
993
 
@@ -1008,7 +999,6 @@ class ChangeSetModel:
1008
999
  return node_conditions
1009
1000
  condition_names: list[str] = self._safe_keys_of(before_conditions, after_conditions)
1010
1001
  conditions: list[NodeCondition] = list()
1011
- change_type = ChangeType.UNCHANGED
1012
1002
  for condition_name in condition_names:
1013
1003
  condition_scope, (before_condition, after_condition) = self._safe_access_in(
1014
1004
  scope, condition_name, before_conditions, after_conditions
@@ -1020,33 +1010,27 @@ class ChangeSetModel:
1020
1010
  after_condition=after_condition,
1021
1011
  )
1022
1012
  conditions.append(condition)
1023
- change_type = change_type.for_child(child_change_type=condition.change_type)
1024
- node_conditions = NodeConditions(
1025
- scope=scope, change_type=change_type, conditions=conditions
1026
- )
1013
+ node_conditions = NodeConditions(scope=scope, conditions=conditions)
1027
1014
  self._visited_scopes[scope] = node_conditions
1028
1015
  return node_conditions
1029
1016
 
1030
1017
  def _visit_output(
1031
1018
  self, scope: Scope, name: str, before_output: Maybe[dict], after_output: Maybe[dict]
1032
1019
  ) -> NodeOutput:
1033
- change_type = ChangeType.UNCHANGED
1034
1020
  scope_value, (before_value, after_value) = self._safe_access_in(
1035
1021
  scope, ValueKey, before_output, after_output
1036
1022
  )
1037
1023
  value = self._visit_value(scope_value, before_value, after_value)
1038
- change_type = change_type.for_child(value.change_type)
1039
1024
 
1040
- export: Optional[ChangeSetEntity] = None
1025
+ export: Maybe[ChangeSetEntity] = Nothing
1041
1026
  scope_export, (before_export, after_export) = self._safe_access_in(
1042
1027
  scope, ExportKey, before_output, after_output
1043
1028
  )
1044
1029
  if before_export or after_export:
1045
1030
  export = self._visit_value(scope_export, before_export, after_export)
1046
- change_type = change_type.for_child(export.change_type)
1047
1031
 
1048
1032
  # TODO: condition references should be resolved for the condition's change_type?
1049
- condition_reference: Optional[TerminalValue] = None
1033
+ condition_reference: Maybe[TerminalValue] = Nothing
1050
1034
  scope_condition, (before_condition, after_condition) = self._safe_access_in(
1051
1035
  scope, ConditionKey, before_output, after_output
1052
1036
  )
@@ -1054,11 +1038,9 @@ class ChangeSetModel:
1054
1038
  condition_reference = self._visit_terminal_value(
1055
1039
  scope_condition, before_condition, after_condition
1056
1040
  )
1057
- change_type = change_type.for_child(condition_reference.change_type)
1058
1041
 
1059
1042
  return NodeOutput(
1060
1043
  scope=scope,
1061
- change_type=change_type,
1062
1044
  name=name,
1063
1045
  value=value,
1064
1046
  export=export,
@@ -1068,7 +1050,6 @@ class ChangeSetModel:
1068
1050
  def _visit_outputs(
1069
1051
  self, scope: Scope, before_outputs: Maybe[dict], after_outputs: Maybe[dict]
1070
1052
  ) -> NodeOutputs:
1071
- change_type = ChangeType.UNCHANGED
1072
1053
  outputs: list[NodeOutput] = list()
1073
1054
  output_names: list[str] = self._safe_keys_of(before_outputs, after_outputs)
1074
1055
  for output_name in output_names:
@@ -1082,8 +1063,7 @@ class ChangeSetModel:
1082
1063
  after_output=after_output,
1083
1064
  )
1084
1065
  outputs.append(output)
1085
- change_type = change_type.for_child(output.change_type)
1086
- return NodeOutputs(scope=scope, change_type=change_type, outputs=outputs)
1066
+ return NodeOutputs(scope=scope, outputs=outputs)
1087
1067
 
1088
1068
  def _model(self, before_template: Maybe[dict], after_template: Maybe[dict]) -> NodeTemplate:
1089
1069
  root_scope = Scope()
@@ -1133,7 +1113,6 @@ class ChangeSetModel:
1133
1113
  # TODO: compute the change_type of the template properly.
1134
1114
  return NodeTemplate(
1135
1115
  scope=root_scope,
1136
- change_type=resources.change_type,
1137
1116
  mappings=mappings,
1138
1117
  parameters=parameters,
1139
1118
  conditions=conditions,
@@ -1141,7 +1120,7 @@ class ChangeSetModel:
1141
1120
  outputs=outputs,
1142
1121
  )
1143
1122
 
1144
- def _retrieve_condition_if_exists(self, condition_name: str) -> Optional[NodeCondition]:
1123
+ def _retrieve_condition_if_exists(self, condition_name: str) -> Maybe[NodeCondition]:
1145
1124
  conditions_scope, (before_conditions, after_conditions) = self._safe_access_in(
1146
1125
  Scope(), ConditionsKey, self._before_template, self._after_template
1147
1126
  )
@@ -1158,14 +1137,12 @@ class ChangeSetModel:
1158
1137
  after_condition=after_condition,
1159
1138
  )
1160
1139
  return node_condition
1161
- return None
1140
+ return Nothing
1162
1141
 
1163
- def _retrieve_parameter_if_exists(self, parameter_name: str) -> Optional[NodeParameter]:
1142
+ def _retrieve_parameter_if_exists(self, parameter_name: str) -> Maybe[NodeParameter]:
1164
1143
  parameters_scope, (before_parameters, after_parameters) = self._safe_access_in(
1165
1144
  Scope(), ParametersKey, self._before_template, self._after_template
1166
1145
  )
1167
- before_parameters = before_parameters or dict()
1168
- after_parameters = after_parameters or dict()
1169
1146
  if parameter_name in before_parameters or parameter_name in after_parameters:
1170
1147
  parameter_scope, (before_parameter, after_parameter) = self._safe_access_in(
1171
1148
  parameters_scope, parameter_name, before_parameters, after_parameters
@@ -1177,15 +1154,13 @@ class ChangeSetModel:
1177
1154
  after_parameter=after_parameter,
1178
1155
  )
1179
1156
  return node_parameter
1180
- return None
1157
+ return Nothing
1181
1158
 
1182
1159
  def _retrieve_mapping(self, mapping_name) -> NodeMapping:
1183
1160
  # TODO: add caching mechanism, and raise appropriate error if missing.
1184
1161
  scope_mappings, (before_mappings, after_mappings) = self._safe_access_in(
1185
1162
  Scope(), MappingsKey, self._before_template, self._after_template
1186
1163
  )
1187
- before_mappings = before_mappings or dict()
1188
- after_mappings = after_mappings or dict()
1189
1164
  if mapping_name in before_mappings or mapping_name in after_mappings:
1190
1165
  scope_mapping, (before_mapping, after_mapping) = self._safe_access_in(
1191
1166
  scope_mappings, mapping_name, before_mappings, after_mappings
@@ -1242,15 +1217,6 @@ class ChangeSetModel:
1242
1217
  keys = sorted(key_set)
1243
1218
  return keys
1244
1219
 
1245
- @staticmethod
1246
- def _change_type_for_parent_of(change_types: list[ChangeType]) -> ChangeType:
1247
- parent_change_type = ChangeType.UNCHANGED
1248
- for child_change_type in change_types:
1249
- parent_change_type = parent_change_type.for_child(child_change_type)
1250
- if parent_change_type == ChangeType.MODIFIED:
1251
- break
1252
- return parent_change_type
1253
-
1254
1220
  @staticmethod
1255
1221
  def _name_if_intrinsic_function(value: Maybe[Any]) -> Optional[str]:
1256
1222
  if isinstance(value, dict):
@@ -1279,11 +1245,3 @@ class ChangeSetModel:
1279
1245
  @staticmethod
1280
1246
  def _is_array(value: Any) -> bool:
1281
1247
  return isinstance(value, list)
1282
-
1283
- @staticmethod
1284
- def _is_created(before: Maybe[Any], after: Maybe[Any]) -> bool:
1285
- return isinstance(before, NothingType) and not isinstance(after, NothingType)
1286
-
1287
- @staticmethod
1288
- def _is_removed(before: Maybe[Any], after: Maybe[Any]) -> bool:
1289
- return not isinstance(before, NothingType) and isinstance(after, NothingType)