def container_of(inner, arg, *, type, min_length=0, flatten=False, **kwargs): if not is_iterable(arg): raise IbisTypeError('Argument must be a sequence') if len(arg) < min_length: raise IbisTypeError( f'Arg must have at least {min_length} number of elements') if flatten: arg = flatten_iterable(arg) return type(inner(item, **kwargs) for item in arg)
def one_of(inners, arg, **kwargs): """At least one of the inner validators must pass""" for inner in inners: with suppress(IbisTypeError, ValueError): return inner(arg, **kwargs) raise IbisTypeError("argument passes none of the following rules: " f"{', '.join(map(repr, inners))}")
def cast(source: str | DataType, target: str | DataType, **kwargs) -> DataType: """Attempts to implicitly cast from source dtype to target dtype""" source, target = dtype(source), dtype(target) if not castable(source, target, **kwargs): raise IbisTypeError( f'Datatype {source} cannot be implicitly casted to {target}' ) return target
def higher_precedence(left: DataType, right: DataType) -> DataType: if castable(left, right, upcast=True): return right elif castable(right, left, upcast=True): return left raise IbisTypeError( f'Cannot compute precedence for {left} and {right} types' )
def from_string(value: str) -> DataType: try: return parse(value) except SyntaxError: raise IbisTypeError(f'{value!r} cannot be parsed as a datatype')
def default(value, **kwargs) -> DataType: raise IbisTypeError(f'Value {value!r} is not a valid datatype')
def instance_of(klasses, arg, **kwargs): """Require that a value has a particular Python type.""" if not isinstance(arg, klasses): raise IbisTypeError(f'Given argument with type {type(arg)} ' f'is not an instance of {klasses}') return arg