diff --git a/murano/dsl/murano_object.py b/murano/dsl/murano_object.py index 8ce7f56c..7cc11a09 100644 --- a/murano/dsl/murano_object.py +++ b/murano/dsl/murano_object.py @@ -52,7 +52,6 @@ class MuranoObject(dsl_types.MuranoObject): self.__parents[name] = known_classes[name] = obj else: self.__parents[name] = known_classes[name] - self.__initialized = False @property def extension(self): @@ -67,8 +66,6 @@ class MuranoObject(dsl_types.MuranoObject): self.__extension = value def initialize(self, context, params, used_names=None): - if self.__initialized: - return context = context.create_child_context() context[constants.CTX_ALLOW_PROPERTY_WRITES] = True object_store = helpers.get_object_store() @@ -134,19 +131,20 @@ class MuranoObject(dsl_types.MuranoObject): if method: filtered_params = yaql_integration.filter_parameters( method.body, **params) - with helpers.with_object_store(object_store.parent_store): - self.__extension = method.invoke( - self, filtered_params[0], filtered_params[1], context) + yield lambda: method.invoke( + self, filtered_params[0], filtered_params[1], context) for parent in self.__parents.values(): - parent.initialize(context, params, used_names) + for t in parent.initialize(context, params, used_names): + yield t + + def run_init(): + context[constants.CTX_ARGUMENT_OWNER] = self.real_this + init.invoke(self.real_this, (), init_args, + context.create_child_context()) if not object_store.initializing and init: - context[constants.CTX_ARGUMENT_OWNER] = self.real_this - with helpers.with_object_store(object_store.parent_store): - init.invoke(self.real_this, (), init_args, - context.create_child_context()) - self.__initialized = True + yield run_init @property def object_id(self): diff --git a/murano/dsl/object_store.py b/murano/dsl/object_store.py index 01ccbcde..1c1f517f 100644 --- a/murano/dsl/object_store.py +++ b/murano/dsl/object_store.py @@ -99,6 +99,7 @@ class InitializationObjectStore(ObjectStore): self._initializing = False self._root_owner = root_owner self._keep_ids = keep_ids + self._initializers = [] @property def initializing(self): @@ -136,11 +137,19 @@ class InitializationObjectStore(ObjectStore): if context is None: context = self.executor.create_object_context(obj) - obj.initialize(context, parsed['properties']) + + def run_initialize(): + self._initializers.extend( + obj.initialize(context, parsed['properties'])) + + run_initialize() if owner is self._root_owner: self._initializing = False - obj.initialize(context, parsed['properties']) + run_initialize() finally: if owner is self._root_owner: - self._initializing = False + with helpers.with_object_store(self.parent_store): + for fn in self._initializers: + fn() + return obj diff --git a/murano/dsl/yaql_integration.py b/murano/dsl/yaql_integration.py index 0382fbd5..e75502ac 100644 --- a/murano/dsl/yaql_integration.py +++ b/murano/dsl/yaql_integration.py @@ -370,9 +370,9 @@ def get_class_factory_definition(cls, murano_class): args = tuple(dsl.to_mutable(arg, engine) for arg in args) kwargs = dsl.to_mutable(kwargs, engine) with helpers.contextual(__context): - __context[constants.CTX_NAMES_SCOPE] = \ - murano_class - return helpers.evaluate(cls(*args, **kwargs), __context) + __context[constants.CTX_NAMES_SCOPE] = murano_class + result = helpers.evaluate(cls(*args, **kwargs), __context) + __receiver.object.extension = result try: fd = specs.get_function_definition( diff --git a/murano/tests/unit/dsl/meta/CreatingClass.yaml b/murano/tests/unit/dsl/meta/CreatingClass.yaml index d1928e43..4df7019d 100644 --- a/murano/tests/unit/dsl/meta/CreatingClass.yaml +++ b/murano/tests/unit/dsl/meta/CreatingClass.yaml @@ -74,6 +74,19 @@ Methods: Body: Return: new(:ConstructionFromInit).out.nodes[1] + testReferenceAccessFromInit: + Body: + - $model: + :Node: + value: rootNode + nodes: + - childNode + - :NodeWithReferenceAccess: + value: childNode + id: childNode + - $.out: new($model, $this) + + --- Name: Node @@ -130,3 +143,12 @@ Methods: nodes: [childNode1] id: childNode2 - $.out: new($model, $this) + +--- + +Name: NodeWithReferenceAccess +Extends: Node + +Methods: + .init: + Body: $.find(Node).nodes.select(trace($.value)) \ No newline at end of file diff --git a/murano/tests/unit/dsl/test_construction.py b/murano/tests/unit/dsl/test_construction.py index c4b813aa..16b5f7b4 100644 --- a/murano/tests/unit/dsl/test_construction.py +++ b/murano/tests/unit/dsl/test_construction.py @@ -67,3 +67,7 @@ class TestConstruction(test_case.DslTestCase): def test_nested_new_loads_in_separate_store(self): res = self._runner.testNestedNewLoadsInSeparateStore() self.assertIsInstance(res, dsl.MuranoObjectInterface) + + def test_reference_access_from_init(self): + self._runner.testReferenceAccessFromInit() + self.assertEqual(2, self.traces.count('childNode'))