Coverage for src / bioimageio / spec / _internal / node.py: 90%

29 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-27 14:45 +0000

1from __future__ import annotations 

2 

3import collections.abc 

4import warnings 

5from typing import ( 

6 Any, 

7 Dict, 

8 Literal, 

9 Mapping, 

10 Optional, 

11 Type, 

12 Union, 

13) 

14 

15import pydantic 

16from typing_extensions import Callable, ParamSpec, Self, TypeVar 

17 

18from .type_guards import is_kwargs 

19from .validation_context import ValidationContext, get_validation_context 

20 

21 

22def _node_title_generator(node: Type[Node]) -> str: 

23 return ( 

24 f"{node.implemented_type} {node.implemented_format_version}" # pyright: ignore[reportAttributeAccessIssue] 

25 if hasattr(node, "implemented_type") 

26 and hasattr(node, "implemented_format_version") 

27 else f"{node.__module__.replace('bioimageio.spec.', '')}.{node.__name__}" 

28 ) 

29 

30 

31P = ParamSpec("P") 

32T = TypeVar("T") 

33 

34 

35class Node( 

36 pydantic.BaseModel, 

37 allow_inf_nan=False, 

38 extra="forbid", 

39 frozen=False, 

40 model_title_generator=_node_title_generator, 

41 populate_by_name=True, 

42 revalidate_instances="always", 

43 use_attribute_docstrings=True, 

44 validate_assignment=True, 

45 validate_default=True, 

46 validate_return=True, 

47): 

48 """""" # empty docstring to remove all pydantic docstrings from the pdoc spec docs 

49 

50 @classmethod 

51 def model_validate( 

52 cls, 

53 obj: Union[Any, Mapping[str, Any]], 

54 *, 

55 strict: Optional[bool] = None, 

56 extra: Optional[Literal["allow", "ignore", "forbid"]] = None, 

57 from_attributes: Optional[bool] = None, 

58 context: Union[ValidationContext, Mapping[str, Any], None] = None, 

59 by_alias: Optional[bool] = None, 

60 by_name: Optional[bool] = None, 

61 ) -> Self: 

62 """Validate a pydantic model instance. 

63 

64 Args: 

65 obj: The object to validate. 

66 strict: Whether to raise an exception on invalid fields. 

67 from_attributes: Whether to extract data from object attributes. 

68 context: Additional context to pass to the validator. 

69 

70 Raises: 

71 ValidationError: If the object failed validation. 

72 

73 Returns: 

74 The validated description instance. 

75 """ 

76 __tracebackhide__ = True 

77 

78 if context is None: 

79 context = get_validation_context() 

80 elif isinstance(context, collections.abc.Mapping): 

81 context = ValidationContext(**context) 

82 

83 assert not isinstance(obj, collections.abc.Mapping) or is_kwargs(obj), obj 

84 

85 # TODO: pass on extra with pydantic >=2.12 

86 if extra is not None: 

87 warnings.warn("`extra` argument is currently ignored") 

88 

89 with context: 

90 # use validation context as context manager for equal behavior of __init__ and model_validate 

91 return super().model_validate( 

92 obj, strict=strict, from_attributes=from_attributes 

93 ) 

94 

95 @classmethod 

96 def dict_from_kwargs( 

97 cls: Callable[P, T], *args: P.args, **kwargs: P.kwargs 

98 ) -> Dict[str, Any]: 

99 assert not args, "Did not expected any args" 

100 return dict(kwargs)