def return_optional_value(self, builder, retty, valty, value): if valty == types.none: # Value is none self.return_native_none(builder) elif retty == valty: # Value is an optional, need a runtime switch optval = self.context.make_helper(builder, retty, value=value) validbit = cgutils.as_bool_bit(builder, optval.valid) with builder.if_then(validbit): retval = self.context.get_return_value(builder, retty.type, optval.data) self.return_value(builder, retval) self.return_native_none(builder) elif not isinstance(valty, types.Optional): # Value is not an optional, need a cast if valty != retty.type: value = self.context.cast(builder, value, fromty=valty, toty=retty.type) retval = self.context.get_return_value(builder, retty.type, value) self.return_value(builder, retval) else: raise NotImplementedError("returning {0} for {1}".format(valty, retty))
def optional_to_optional(context, builder, fromty, toty, val): """ The handling of optional->optional cast must be special cased for correct propagation of None value. Given type T and U. casting of T? to U? (? denotes optional) should always succeed. If the from-value is None, the None value the casted value (U?) should be None; otherwise, the from-value is casted to U. This is different from casting T? to U, which requires the from-value must not be None. """ optval = context.make_helper(builder, fromty, value=val) validbit = cgutils.as_bool_bit(builder, optval.valid) # Create uninitialized optional value outoptval = context.make_helper(builder, toty) with builder.if_else(validbit) as (is_valid, is_not_valid): with is_valid: # Cast internal value outoptval.valid = cgutils.true_bit outoptval.data = context.cast(builder, optval.data, fromty.type, toty.type) with is_not_valid: # Store None to result outoptval.valid = cgutils.false_bit outoptval.data = cgutils.get_null_value(outoptval.data.type) return outoptval._getvalue()
def optional_to_any(context, builder, fromty, toty, val): optval = context.make_helper(builder, fromty, value=val) validbit = cgutils.as_bool_bit(builder, optval.valid) with builder.if_then(builder.not_(validbit), likely=False): msg = "expected %s, got None" % (fromty.type, ) context.call_conv.return_user_exc(builder, TypeError, (msg, )) return context.cast(builder, optval.data, fromty.type, toty)
def optional_is_none(context, builder, sig, args): """ Check if an Optional value is invalid """ [lty, rty] = sig.args [lval, rval] = args # Make sure None is on the right if lty == types.none: lty, rty = rty, lty lval, rval = rval, lval opt_type = lty opt_val = lval opt = context.make_helper(builder, opt_type, opt_val) res = builder.not_(cgutils.as_bool_bit(builder, opt.valid)) return impl_ret_untracked(context, builder, sig.return_type, res)