|
9 | 9 | # See the License for the specific language governing permissions and |
10 | 10 | # limitations under the License. |
11 | 11 |
|
| 12 | +import os |
12 | 13 | import re |
| 14 | +import warnings |
13 | 15 | from typing import Any, Dict, Optional, Sequence, Set |
14 | 16 |
|
15 | 17 | from monai.bundle.config_item import ConfigComponent, ConfigExpression, ConfigItem |
@@ -50,6 +52,8 @@ class ReferenceResolver: |
50 | 52 | ref = ID_REF_KEY # reference prefix |
51 | 53 | # match a reference string, e.g. "@id#key", "@id#key#0", "@_target_#key" |
52 | 54 | id_matcher = re.compile(rf"{ref}(?:\w*)(?:{sep}\w*)*") |
| 55 | + # if `allow_missing_reference` and can't find a reference ID, will just raise a warning and don't update the config |
| 56 | + allow_missing_reference = False if os.environ.get("MONAI_ALLOW_MISSING_REFERENCE", "0") == "0" else True |
53 | 57 |
|
54 | 58 | def __init__(self, items: Optional[Sequence[ConfigItem]] = None): |
55 | 59 | # save the items in a dictionary with the `ConfigItem.id` as key |
@@ -140,7 +144,12 @@ def _resolve_one_item(self, id: str, waiting_list: Optional[Set[str]] = None, ** |
140 | 144 | try: |
141 | 145 | look_up_option(d, self.items, print_all_options=False) |
142 | 146 | except ValueError as err: |
143 | | - raise ValueError(f"the referring item `@{d}` is not defined in the config content.") from err |
| 147 | + msg = f"the referring item `@{d}` is not defined in the config content." |
| 148 | + if self.allow_missing_reference: |
| 149 | + warnings.warn(msg) |
| 150 | + continue |
| 151 | + else: |
| 152 | + raise ValueError(msg) from err |
144 | 153 | # recursively resolve the reference first |
145 | 154 | self._resolve_one_item(id=d, waiting_list=waiting_list, **kwargs) |
146 | 155 | waiting_list.discard(d) |
@@ -210,7 +219,12 @@ def update_refs_pattern(cls, value: str, refs: Dict) -> str: |
210 | 219 | for item in result: |
211 | 220 | ref_id = item[len(cls.ref) :] # remove the ref prefix "@" |
212 | 221 | if ref_id not in refs: |
213 | | - raise KeyError(f"can not find expected ID '{ref_id}' in the references.") |
| 222 | + msg = f"can not find expected ID '{ref_id}' in the references." |
| 223 | + if cls.allow_missing_reference: |
| 224 | + warnings.warn(msg) |
| 225 | + continue |
| 226 | + else: |
| 227 | + raise KeyError(msg) |
214 | 228 | if value_is_expr: |
215 | 229 | # replace with local code, will be used in the `evaluate` logic with `locals={"refs": ...}` |
216 | 230 | value = value.replace(item, f"{cls._vars}['{ref_id}']") |
|
0 commit comments