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

Code before:
        """
        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
            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)
        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.

        Args:
            name: the name of target property.
            property: other information for the target property, defined in `TrainProperties` or `InferProperties`.

        """
        if not self._is_initialized:
            raise RuntimeError("Please execute 'initialize' before getting any parsed content.")
        prop_id = self._get_prop_id(name, property)
        return self.parser.get_parsed_content(id=prop_id) if prop_id is not None else None


Review comment (bug):
Based on error here: https://github.com/Project-MONAI/MONAI/actions/runs/11946274965/job/33300343831?pr=8146#step:12:23028
If `self.parser[id]` is not a list, it will throw error when remove_resolved_content.
```suggestion
            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(sub_id)
```

Code after:
        """
        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

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

        Args:
            name: the name of target property.