Repository: Project-MONAI/MONAI
File: monai/bundle/workflows.py (Python)

Code before:
    def check_properties(self) -> list[str] | None:
        """
        Check whether the required properties are existing in the bundle workflow.
        If the optional properties have reference in the config, will also check whether the properties are existing.
        If no workflow type specified, return None, otherwise, return a list of required but missing properties.

        """
        ret = super().check_properties()
        if self.properties is None:
            logger.warn("No available properties had been set, skipping check.")
            return None
        if ret:
            logger.warn(f"Loaded bundle does not contain the following required properties: {ret}")
        # also check whether the optional properties use correct ID name if existing
        wrong_props = []
        for n, p in self.properties.items():
            if not p.get(BundleProperty.REQUIRED, False) and not self._check_optional_id(name=n, property=p):
                wrong_props.append(n)
        if wrong_props:
            logger.warn(f"Loaded bundle defines the following optional properties with wrong ID: {wrong_props}")
        if ret is not None:
            ret.extend(wrong_props)
        return ret

    def _run_expr(self, id: str, **kwargs: dict) -> list[Any]:
        ret = []
        if id in self.parser:
            # suppose all the expressions are in a list, run and reset the expressions
            if isinstance(self.parser[id], list):
                for i in range(len(self.parser[id])):
                    sub_id = f"{id}{ID_SEP_KEY}{i}"
                    ret.append(self.parser.get_parsed_content(sub_id, **kwargs))
                    self.parser.ref_resolver.remove_resolved_content(sub_id)
            else:
                ret.append(self.parser.get_parsed_content(id, **kwargs))
                self.parser.ref_resolver.remove_resolved_content(id)
        return ret

    def _get_prop_id(self, name: str, property: dict) -> Any:
        prop_id = property[BundlePropertyConfig.ID]
        if prop_id not in self.parser:
            if not property.get(BundleProperty.REQUIRED, False):
                return None
            else:
                raise KeyError(f"Property '{name}' with config ID '{prop_id}' not in the config.")
        return prop_id

    def _get_property(self, name: str, property: dict) -> Any:
        """
        With specified property name and information, get the parsed property value from config.


Review comment (suggestion):
```suggestion
    def _run_expr(self, id: str, **kwargs: dict) -> list[Any]:
        """
        Evaluate the expression or expression list given by `id`. The resolved values from the evaluations are not stored, allowing this to be evaluated repeatedly (eg. in streaming applications) without restarting the hosting process.
        """
        ret = []
```

Code after:
    def check_properties(self) -> list[str] | None:
        """
        Check whether the required properties are existing in the bundle workflow.
        If the optional properties have reference in the config, will also check whether the properties are existing.
        If no workflow type specified, return None, otherwise, return a list of required but missing properties.

        """
        ret = super().check_properties()
        if self.properties is None:
            logger.warn("No available properties had been set, skipping check.")
            return None
        if ret:
            logger.warn(f"Loaded bundle does not contain the following required properties: {ret}")
        # also check whether the optional properties use correct ID name if existing
        wrong_props = []
        for n, p in self.properties.items():
            if not p.get(BundleProperty.REQUIRED, False) and not self._check_optional_id(name=n, property=p):
                wrong_props.append(n)
        if wrong_props:
            logger.warn(f"Loaded bundle defines the following optional properties with wrong ID: {wrong_props}")
        if ret is not None:
            ret.extend(wrong_props)
        return ret

    def _run_expr(self, id: str, **kwargs: dict) -> list[Any]:
        """
        Evaluate the expression or expression list given by `id`. The resolved values from the evaluations are not stored,
        allowing this to be evaluated repeatedly (eg. in streaming applications) without restarting the hosting process.
        """
        ret = []
        if id in self.parser:
            # suppose all the expressions are in a list, run and reset the expressions
            if isinstance(self.parser[id], list):
                for i in range(len(self.parser[id])):
                    sub_id = f"{id}{ID_SEP_KEY}{i}"
                    ret.append(self.parser.get_parsed_content(sub_id, **kwargs))
                    self.parser.ref_resolver.remove_resolved_content(sub_id)
            else:
                ret.append(self.parser.get_parsed_content(id, **kwargs))
                self.parser.ref_resolver.remove_resolved_content(id)
        return ret

    def _get_prop_id(self, name: str, property: dict) -> Any:
        prop_id = property[BundlePropertyConfig.ID]
        if prop_id not in self.parser:
            if not property.get(BundleProperty.REQUIRED, False):
                return None
            else:
                raise KeyError(f"Property '{name}' with config ID '{prop_id}' not in the config.")
        return prop_id