Coverage for src/bioimageio/spec/_internal/validator_annotations.py: 85%
34 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-18 09:17 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-18 09:17 +0000
1from __future__ import annotations
3from dataclasses import dataclass
4from typing import Any
6import annotated_types
7from pydantic import GetCoreSchemaHandler, functional_validators
8from pydantic_core import CoreSchema
9from pydantic_core.core_schema import no_info_after_validator_function
11from .utils import SLOTS
14# TODO: make sure we use this one everywhere and not the vanilla pydantic one
15@dataclass(frozen=True, **SLOTS)
16class AfterValidator(functional_validators.AfterValidator):
17 def __str__(self):
18 return f"AfterValidator({self.func.__name__})"
21# TODO: make sure we use this one everywhere and not the vanilla pydantic one
22@dataclass(frozen=True, **SLOTS)
23class BeforeValidator(functional_validators.BeforeValidator):
24 def __str__(self):
25 return f"BeforeValidator({self.func.__name__})"
28# TODO: make sure we use this one everywhere and not the vanilla pydantic one
29@dataclass(frozen=True, **SLOTS)
30class Predicate(annotated_types.Predicate):
31 def __str__(self):
32 return f"Predicate({self.func.__name__})"
35@dataclass(frozen=True, **SLOTS)
36class RestrictCharacters:
37 alphabet: str
39 def __get_pydantic_core_schema__(
40 self, source: type[Any], handler: GetCoreSchemaHandler
41 ) -> CoreSchema:
42 if not self.alphabet:
43 raise ValueError("Alphabet may not be empty")
45 schema = handler(source) # get the CoreSchema from the type / inner constraints
46 if schema["type"] != "str" and not (
47 schema["type"] == "function-after" and schema["schema"]["type"] == "str"
48 ):
49 raise TypeError("RestrictCharacters can only be applied to strings")
51 return no_info_after_validator_function(
52 self.validate,
53 schema,
54 )
56 def validate(self, value: str) -> str:
57 if any(c not in self.alphabet for c in value):
58 raise ValueError(f"{value!r} is not restricted to {self.alphabet!r}")
59 return value