Skip to content

Commit 0e9b64e

Browse files
committed
throw for invalid argument format-verison, fallback to latest for invalid discovered format-versions
1 parent a680b53 commit 0e9b64e

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

src/bioimageio/spec/_description.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,10 @@ def dump_description(
145145
for a given **type** and **format_version**."""
146146

147147

148-
def _get_rd_class(typ: Any, format_version: Any):
149-
return get_rd_class_impl(typ, format_version, DESCRIPTIONS_MAP)
148+
def _get_rd_class(typ: Any, format_version: Any, fallback_to_latest: bool):
149+
return get_rd_class_impl(
150+
typ, format_version, DESCRIPTIONS_MAP, fallback_to_latest=fallback_to_latest
151+
)
150152

151153

152154
@overload

src/bioimageio/spec/_description_impl.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import Any, Callable, List, Literal, Mapping, Optional, Type, TypeVar, Union
55

66
from ._internal.common_nodes import InvalidDescr, ResourceDescrBase
7+
from ._internal.field_validation import issue_warning
78
from ._internal.io import BioimageioYamlContentView
89
from ._internal.types import FormatVersionPlaceholder
910
from ._internal.validation_context import ValidationContext, get_validation_context
@@ -23,6 +24,7 @@ def get_rd_class_impl(
2324
typ: Any,
2425
format_version: Any,
2526
descriptions_map: Mapping[Optional[str], Mapping[str, Type[ResourceDescrT]]],
27+
fallback_to_latest: bool,
2628
) -> Type[ResourceDescrT]:
2729
"""get the resource description class for the given type and format version"""
2830
assert None in descriptions_map
@@ -46,10 +48,20 @@ def get_rd_class_impl(
4648

4749
descr_versions = descriptions_map[typ]
4850
if use_format_version not in descr_versions:
49-
raise ValueError(
50-
f"Unsupported format version '{format_version}' for type '{typ}'. "
51-
+ f"Supported format versions are: {', '.join(sorted(fv for fv in descr_versions))}"
52-
)
51+
if fallback_to_latest:
52+
issue_warning(
53+
"Unsupported format version '{value}' for type '{typ}'.",
54+
value=format_version,
55+
field="format_version",
56+
log_depth=3,
57+
msg_context={"typ": typ},
58+
)
59+
use_format_version = "latest"
60+
else:
61+
raise ValueError(
62+
f"Unsupported format version '{format_version}' for type '{typ}'."
63+
+ " Supported format versions are: {', '.join(sorted(fv for fv in descr_versions))}"
64+
)
5365

5466
return descr_versions[use_format_version]
5567

@@ -60,7 +72,7 @@ def build_description_impl(
6072
*,
6173
context: Optional[ValidationContext] = None,
6274
format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
63-
get_rd_class: Callable[[Any, Any], Type[ResourceDescrT]],
75+
get_rd_class: Callable[[Any, Any, bool], Type[ResourceDescrT]],
6476
) -> Union[ResourceDescrT, InvalidDescr]:
6577
context = context or get_validation_context()
6678
errors: List[ErrorEntry] = []
@@ -101,17 +113,19 @@ def build_description_impl(
101113
return ret
102114

103115
typ = content["type"]
104-
rd_class = get_rd_class(typ, content["format_version"])
116+
# check format_version argument before loading as 'discover'
117+
# to throw an exception for an invalid format_version early
118+
if str(format_version).lower() != DISCOVER:
119+
as_rd_class = get_rd_class(typ, format_version, False)
120+
else:
121+
as_rd_class = None
122+
# always load with discovered format_version first
123+
rd_class = get_rd_class(typ, content["format_version"], True)
105124
rd = rd_class.load(content, context=context)
106125

107-
if str(format_version).lower() not in (
108-
DISCOVER,
109-
rd_class.implemented_format_version,
110-
".".join(map(str, rd_class.implemented_format_version_tuple[:2])),
111-
):
126+
if as_rd_class is not None and as_rd_class is not rd_class:
112127
# load with requested format_version
113128
discover_details = rd.validation_summary.details
114-
as_rd_class = get_rd_class(typ, format_version)
115129
rd = as_rd_class.load(content, context=context)
116130
assert rd.validation_summary is not None
117131
rd.validation_summary.details[:0] = discover_details

0 commit comments

Comments
 (0)