Repository: Avaiga/taipy
File: taipy/core/scenario/scenario.py (Python)

Code before:
        from ... import core as tp

        sc = tp.get(id)
        self.__dict__ = sc.__dict__

    def __hash__(self):
        return hash(self.id)

    def __eq__(self, other):
        return isinstance(other, Scenario) and self.id == other.id

    def __setattr__(self, name: str, value: Any) -> None:
        if self.__CHECK_INIT_DONE_ATTR_NAME not in dir(self) or name in dir(self):
            return super().__setattr__(name, value)
        else:
            protected_attribute_name = _validate_id(name)
            try:
                if protected_attribute_name not in self._properties and not self._get_attributes(
                    protected_attribute_name, name
                ):
                    raise AttributeError
                raise AttributeKeyAlreadyExisted(name)
            except AttributeError:
                return super().__setattr__(name, value)

    def _get_attributes(self, protected_attribute_name, attribute_name) -> Union[Sequence, Task, DataNode]:
        sequences = self._get_sequences()
        if protected_attribute_name in sequences:
            return sequences[protected_attribute_name]
        tasks = self.__get_tasks()
        if protected_attribute_name in tasks:
            return tasks[protected_attribute_name]
        data_nodes = self.__get_data_nodes()
        if protected_attribute_name in data_nodes:
            return data_nodes[protected_attribute_name]

        raise AttributeError(f"{attribute_name} is not an attribute of scenario {self.id}")

    def __getattr__(self, attribute_name):
        protected_attribute_name = _validate_id(attribute_name)
        if protected_attribute_name in self._properties:
            return _tpl._replace_templates(self._properties[protected_attribute_name])

        return self._get_attributes(protected_attribute_name, attribute_name)

    @property
    def config_id(self):
        return self._config_id

    @property  # type: ignore
    @_self_reload(_MANAGER_NAME)

Review comment (suggestion):
The `protected_attribute_name` is not used outside of the `_get_attributes()` right?

We probably can move the `_validate_id()` inside the `_get_attributes()` to make it cleaner.
```suggestion
    def _get_attributes(self, attribute_name) -> Union[Sequence, Task, DataNode]:
        protected_attribute_name = _validate_id(name)
```

Code after:
        from ... import core as tp

        sc = tp.get(id)
        self.__dict__ = sc.__dict__

    def __hash__(self):
        return hash(self.id)

    def __eq__(self, other):
        return isinstance(other, Scenario) and self.id == other.id

    def __setattr__(self, name: str, value: Any) -> None:
        if self.__CHECK_INIT_DONE_ATTR_NAME not in dir(self) or name in dir(self):
            return super().__setattr__(name, value)
        else:
            try:
                self.__getattr__(name)
                raise AttributeKeyAlreadyExisted(name)
            except AttributeError:
                return super().__setattr__(name, value)

    def __getattr__(self, attribute_name) -> Union[Sequence, Task, DataNode]:
        protected_attribute_name = _validate_id(attribute_name)
        sequences = self._get_sequences()
        if protected_attribute_name in sequences:
            return sequences[protected_attribute_name]
        tasks = self.__get_tasks()
        if protected_attribute_name in tasks:
            return tasks[protected_attribute_name]
        data_nodes = self.__get_data_nodes()
        if protected_attribute_name in data_nodes:
            return data_nodes[protected_attribute_name]

        raise AttributeError(f"{attribute_name} is not an attribute of scenario {self.id}")

    @property
    def config_id(self):
        return self._config_id

    @property  # type: ignore
    @_self_reload(_MANAGER_NAME)
    def sequences(self) -> Dict[str, Sequence]:
        return self._get_sequences()

    @sequences.setter  # type: ignore
    @_self_setter(_MANAGER_NAME)
    def sequences(
        self, sequences: Dict[str, Dict[str, Union[List[Task], List[TaskId], _ListAttributes, List[_Subscriber], Dict]]]
    ):
        self._sequences = sequences
        actual_sequences = self._get_sequences()