Skip to content

Commit 93146f9

Browse files
authored
Merge pull request #690 from bioimage-io/dev
fix default validation context
2 parents e976979 + 7c78ed5 commit 93146f9

17 files changed

+85
-64
lines changed

bioimageio/spec/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "0.5.4.0"
2+
"version": "0.5.4.1"
33
}

bioimageio/spec/_description.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from ._internal.common_nodes import InvalidDescr
1111
from ._internal.io import BioimageioYamlContent
1212
from ._internal.types import FormatVersionPlaceholder
13-
from ._internal.validation_context import validation_context_var
13+
from ._internal.validation_context import get_validation_context
1414
from .application import (
1515
AnyApplicationDescr,
1616
ApplicationDescr,
@@ -224,7 +224,7 @@ def validate_format(
224224
Alternatively you can use `bioimagieo.spec.load_description` and access the
225225
`validation_summary` attribute of the returned object.
226226
"""
227-
with context or validation_context_var.get():
227+
with context or get_validation_context():
228228
rd = build_description(data, format_version=format_version)
229229

230230
assert rd.validation_summary is not None

bioimageio/spec/_description_impl.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from ._internal.common_nodes import InvalidDescr, ResourceDescrBase
66
from ._internal.io import BioimageioYamlContent
77
from ._internal.types import FormatVersionPlaceholder
8-
from ._internal.validation_context import ValidationContext, validation_context_var
8+
from ._internal.validation_context import ValidationContext, get_validation_context
99
from .summary import (
1010
ErrorEntry,
1111
ValidationDetail,
@@ -55,7 +55,7 @@ def build_description_impl(
5555
format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
5656
get_rd_class: Callable[[Any, Any], Type[ResourceDescrT]],
5757
) -> Union[ResourceDescrT, InvalidDescr]:
58-
context = context or validation_context_var.get()
58+
context = context or get_validation_context()
5959
errors: List[ErrorEntry] = []
6060
if isinstance(content, dict):
6161
for minimum in ("type", "format_version"):

bioimageio/spec/_internal/common_nodes.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,8 @@
4141
from .packaging_context import PackagingContext
4242
from .root_url import RootHttpUrl
4343
from .url import HttpUrl
44-
from .utils import (
45-
get_format_version_tuple,
46-
)
47-
from .validation_context import (
48-
ValidationContext,
49-
validation_context_var,
50-
)
44+
from .utils import get_format_version_tuple
45+
from .validation_context import ValidationContext, get_validation_context
5146
from .warning_levels import ALERT, ERROR, INFO
5247

5348

@@ -148,7 +143,10 @@ def _ignore_future_patch(cls, data: Union[Dict[Any, Any], Any], /) -> Any:
148143

149144
@model_validator(mode="after")
150145
def _set_init_validation_summary(self) -> Self:
151-
context = validation_context_var.get()
146+
context = get_validation_context()
147+
detail_name = (
148+
"Created" if isinstance(self, InvalidDescr) else "Successfully created"
149+
) + f" `{self.__class__.__name__}` object."
152150
self._validation_summary = ValidationSummary(
153151
name="bioimageio format validation",
154152
source_name=context.source_name,
@@ -158,11 +156,8 @@ def _set_init_validation_summary(self) -> Self:
158156
status="failed" if isinstance(self, InvalidDescr) else "valid-format",
159157
details=[
160158
ValidationDetail(
161-
name=(
162-
f"Sucessfully created `{self.__class__.__name__}` object."
163-
+ " Further validation is pending."
164-
),
165-
status="passed",
159+
name=detail_name,
160+
status="failed" if isinstance(self, InvalidDescr) else "passed",
166161
context=context.summary,
167162
)
168163
],
@@ -175,11 +170,11 @@ def validation_summary(self) -> ValidationSummary:
175170
return self._validation_summary
176171

177172
_root: Union[RootHttpUrl, DirectoryPath, ZipFile] = PrivateAttr(
178-
default_factory=lambda: validation_context_var.get().root
173+
default_factory=lambda: get_validation_context().root
179174
)
180175

181176
_file_name: Optional[FileName] = PrivateAttr(
182-
default_factory=lambda: validation_context_var.get().file_name
177+
default_factory=lambda: get_validation_context().file_name
183178
)
184179

185180
@property
@@ -211,7 +206,7 @@ def load(
211206
cls, data: BioimageioYamlContent, context: Optional[ValidationContext] = None
212207
) -> Union[Self, InvalidDescr]:
213208
"""factory method to create a resource description object"""
214-
context = context or validation_context_var.get()
209+
context = context or get_validation_context()
215210
assert isinstance(data, dict)
216211
with context:
217212
rd, errors, val_warnings = cls._load_impl(deepcopy(data))
@@ -247,7 +242,7 @@ def _load_impl(
247242
val_errors: List[ErrorEntry] = []
248243
val_warnings: List[WarningEntry] = []
249244

250-
context = validation_context_var.get()
245+
context = get_validation_context()
251246
try:
252247
rd = cls.model_validate(data)
253248
except pydantic.ValidationError as e:
@@ -275,7 +270,7 @@ def _load_impl(
275270
msg=(
276271
f"Encountered {len(val_warnings)} more severe than warning"
277272
" level "
278-
f"'{WARNING_LEVEL_TO_NAME[validation_context_var.get().warning_level]}'"
273+
f"'{WARNING_LEVEL_TO_NAME[context.warning_level]}'"
279274
),
280275
type="severe_warnings",
281276
)

bioimageio/spec/_internal/field_validation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .constants import KNOWN_GH_USERS, KNOWN_INVALID_GH_USERS
1616
from .field_warning import issue_warning
1717
from .type_guards import is_mapping, is_sequence, is_tuple
18-
from .validation_context import validation_context_var
18+
from .validation_context import get_validation_context
1919

2020

2121
def is_valid_yaml_leaf_value(value: Any) -> bool:
@@ -64,7 +64,7 @@ def validate_gh_user(username: str, hotfix_known_errorenous_names: bool = True)
6464

6565
if (
6666
username.lower() in KNOWN_GH_USERS
67-
or not validation_context_var.get().perform_io_checks
67+
or not get_validation_context().perform_io_checks
6868
):
6969
return username
7070

bioimageio/spec/_internal/field_warning.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
)
1616
from typing_extensions import Annotated, LiteralString
1717

18-
from .validation_context import validation_context_var
18+
from .validation_context import get_validation_context
1919
from .warning_levels import WARNING, WarningSeverity
2020

2121
if TYPE_CHECKING:
@@ -142,8 +142,8 @@ def issue_warning(
142142
field: Optional[str] = None,
143143
):
144144
msg_context = {"value": value, "severity": severity, **(msg_context or {})}
145-
if severity >= validation_context_var.get().warning_level:
145+
if severity >= (ctxt := get_validation_context()).warning_level:
146146
raise PydanticCustomError("warning", msg, msg_context)
147-
elif validation_context_var.get().log_warnings:
147+
elif ctxt.log_warnings:
148148
log_msg = (field + ": " if field else "") + (msg.format(**msg_context))
149149
logger.opt(depth=1).log(severity, log_msg)

bioimageio/spec/_internal/node.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from typing_extensions import Self
1313

1414
from .type_guards import is_kwargs
15-
from .validation_context import ValidationContext, validation_context_var
15+
from .validation_context import ValidationContext, get_validation_context
1616

1717

1818
def _node_title_generator(node: Type[Node]) -> str:
@@ -64,7 +64,7 @@ def model_validate(
6464
__tracebackhide__ = True
6565

6666
if context is None:
67-
context = validation_context_var.get()
67+
context = get_validation_context()
6868
elif isinstance(context, dict):
6969
context = ValidationContext(**context)
7070

bioimageio/spec/_internal/url.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from .field_warning import issue_warning
1111
from .root_url import RootHttpUrl
12-
from .validation_context import validation_context_var
12+
from .validation_context import get_validation_context
1313

1414

1515
def _validate_url(url: Union[str, pydantic.HttpUrl]) -> pydantic.HttpUrl:
@@ -127,7 +127,7 @@ class HttpUrl(RootHttpUrl):
127127

128128
def _after_validator(self):
129129
self = super()._after_validator()
130-
context = validation_context_var.get()
130+
context = get_validation_context()
131131
if (
132132
context.perform_io_checks
133133
and str(self._validated) not in context.known_files

bioimageio/spec/_internal/validation_context.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class ValidationContext(ValidationContextBase):
5454
if it matches its expected SHA256 hash value.
5555
"""
5656

57-
_context_tokens: "List[Token[ValidationContext]]" = field(
57+
_context_tokens: "List[Token[Optional[ValidationContext]]]" = field(
5858
init=False, default_factory=list
5959
)
6060

@@ -94,11 +94,11 @@ def summary(self):
9494
)
9595

9696
def __enter__(self):
97-
self._context_tokens.append(validation_context_var.set(self))
97+
self._context_tokens.append(_validation_context_var.set(self))
9898
return self
9999

100100
def __exit__(self, type, value, traceback): # type: ignore
101-
validation_context_var.reset(self._context_tokens.pop(-1))
101+
_validation_context_var.reset(self._context_tokens.pop(-1))
102102

103103
def replace( # TODO: probably use __replace__ when py>=3.13
104104
self,
@@ -160,11 +160,13 @@ def source_name(self) -> str:
160160
return str(source)
161161

162162

163-
validation_context_var: ContextVar[ValidationContext] = ContextVar(
164-
"validation_context_var", default=ValidationContext()
163+
_validation_context_var: ContextVar[Optional[ValidationContext]] = ContextVar(
164+
"validation_context_var", default=None
165165
)
166166

167167

168-
def get_validation_context():
169-
"""Get the currently active validation context"""
170-
return validation_context_var.get()
168+
def get_validation_context(
169+
default: Optional[ValidationContext] = None,
170+
) -> ValidationContext:
171+
"""Get the currently active validation context (or a default)"""
172+
return _validation_context_var.get() or default or ValidationContext()

bioimageio/spec/_io.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from ._internal.io_basics import Sha256
2222
from ._internal.io_utils import open_bioimageio_yaml, write_yaml
2323
from ._internal.types import FormatVersionPlaceholder
24-
from ._internal.validation_context import validation_context_var
24+
from ._internal.validation_context import get_validation_context
2525
from .common import PermissiveFileSource
2626
from .dataset import AnyDatasetDescr, DatasetDescr
2727
from .model import AnyModelDescr, ModelDescr
@@ -86,7 +86,7 @@ def load_description(
8686

8787
opened = open_bioimageio_yaml(source, sha256=sha256)
8888

89-
context = validation_context_var.get().replace(
89+
context = get_validation_context().replace(
9090
root=opened.original_root,
9191
file_name=opened.original_file_name,
9292
perform_io_checks=perform_io_checks,
@@ -281,7 +281,7 @@ def update_format(
281281
if isinstance(source, dict):
282282
descr = build_description(
283283
source,
284-
context=validation_context_var.get().replace(
284+
context=get_validation_context().replace(
285285
root=root, perform_io_checks=perform_io_checks
286286
),
287287
format_version=LATEST,
@@ -311,7 +311,7 @@ def update_hashes(
311311
else:
312312
root = None
313313

314-
context = validation_context_var.get().replace(
314+
context = get_validation_context().replace(
315315
update_hashes=True, root=root, perform_io_checks=True
316316
)
317317
with context:

0 commit comments

Comments
 (0)