def gather_errors(func: Callable[..., ValidatorResult[T]]) -> Callable[..., T]: if not isgeneratorfunction(func): raise TypeError("func must be a generator returning a ValidatorResult") @wraps(func) def wrapper(*args, **kwargs): result, errors = func(*args, **kwargs), [] while True: try: errors.append(next(result)) except StopIteration as stop: if errors: raise build_validation_error(errors) return stop.value if "return" in func.__annotations__: ret = func.__annotations__["return"] if isinstance(ret, str): match = re.match(r"ValidatorResult\[(?P<ret>.*)\]", ret) if match is not None: ret = match.groupdict("ret") else: annotations = get_args(ret)[1:] if is_annotated(ret) else () if get_origin2(ret) == GeneratorOrigin: ret = get_args2(ret)[2] if annotations: ret = Annotated[(ret, *annotations)] wrapper.__annotations__["return"] = ret return wrapper
def full_metadata(self) -> Mapping[str, Any]: if not is_annotated(self.type): return self.metadata return ChainMap( self.metadata, *(arg for arg in reversed(get_args(self.type)[1:]) if isinstance(arg, Mapping)), )
def merged_schema( schema: Optional[Schema], tp: Optional[AnyType]) -> Tuple[Optional[Schema], Mapping[str, Any]]: if is_annotated(tp): for annotation in reversed(get_args(tp)[1:]): if isinstance(annotation, TypeNameFactory): break elif isinstance(annotation, Mapping) and SCHEMA_METADATA in annotation: schema = merge_schema(annotation[SCHEMA_METADATA], schema) schema_dict: Dict[str, Any] = {} if schema is not None: schema.merge_into(schema_dict) return schema, schema_dict
def keep_annotations(tp: AnyType, annotated: AnyType) -> AnyType: return Annotated[( tp, *get_args(annotated)[1:])] if is_annotated(annotated) else tp
def _annotated(tp: AnyType) -> AnyType: return get_args(tp)[0] if is_annotated(tp) else tp
def __call__(self, tp: T) -> T: if is_annotated(tp): raise TypeError("Cannot register schema on Annotated type") _schemas[replace_builtins(tp)] = self return tp