def castable(source, target): """Return whether source ir type is implicitly castable to target Based on the underlying datatypes and the value in case of Literals """ op = source.op() value = getattr(op, 'value', None) return dt.castable(source.type(), target.type(), value=value)
def value(dtype, arg): """Validates that the given argument is a Value with a particular datatype Parameters ---------- dtype : DataType subclass or DataType instance arg : python literal or an ibis expression If a python literal is given the validator tries to coerce it to an ibis literal. Returns ------- arg : AnyValue An ibis value expression with the specified datatype """ if not isinstance(arg, ir.Expr): # coerce python literal to ibis literal arg = ir.literal(arg) if not isinstance(arg, ir.AnyValue): raise com.IbisTypeError( 'Given argument with type {} is not a value ' 'expression'.format(type(arg)) ) # retrieve literal values for implicit cast check value = getattr(arg.op(), 'value', None) if isinstance(dtype, type) and isinstance(arg.type(), dtype): # dtype class has been specified like dt.Interval or dt.Decimal return arg elif dt.castable(arg.type(), dt.dtype(dtype), value=value): # dtype instance or string has been specified and arg's dtype is # implicitly castable to it, like dt.int8 is castable to dt.int64 return arg else: raise com.IbisTypeError( 'Given argument with datatype {} is not ' 'subtype of {} nor implicitly castable to ' 'it'.format(arg.type(), dtype) )
def test_implicitly_uncastable_values(source, target, value): assert not dt.castable(source, target, value=value)
def test_implicitly_uncastable(source, target): assert not dt.castable(source, target)
def test_implicit_castable(source, target): assert dt.castable(source, target)