def validate(self): if self.value < SizeLimits.MIN_INT256: raise OverflowException( "Value is below lower bound for all numeric types", self) if self.value > SizeLimits.MAX_UINT256: raise OverflowException( "Value exceeds upper bound for all numeric types", self)
def validate(self): if self.value.as_tuple().exponent < -MAX_DECIMAL_PLACES: raise InvalidLiteral("Vyper supports a maximum of ten decimal points", self) if self.value < SizeLimits.MIN_INT128: raise OverflowException("Value is below lower bound for decimal types", self) if self.value > SizeLimits.MAX_INT128: raise OverflowException("Value exceeds upper bound for decimal types", self)
def from_literal(cls, node: vy_ast.Constant) -> BaseTypeDefinition: obj = super().from_literal(node) lower, upper = cls._bounds if node.value < lower: raise OverflowException(f"Value is below lower bound for given type ({lower})", node) if node.value > upper: raise OverflowException(f"Value exceeds upper bound for given type ({upper})", node) return obj
def validate_numeric_op( self, node: Union[vy_ast.UnaryOp, vy_ast.BinOp, vy_ast.AugAssign]) -> None: if self._invalid_op and isinstance(node.op, self._invalid_op): raise InvalidOperation( f"Cannot perform {node.op.description} on {self}", node) if isinstance(node.op, vy_ast.Pow): if isinstance(node, vy_ast.BinOp): left, right = node.left, node.right elif isinstance(node, vy_ast.AugAssign): left, right = node.target, node.value else: raise CompilerPanic( f"Unexpected node type for numeric op: {type(node).__name__}" ) value_bits = self._bits - (1 if self._is_signed else 0) # constant folding ensures one of `(left, right)` is never a literal if isinstance(left, vy_ast.Int): if left.value >= 2**value_bits: raise OverflowException( "Base is too large, calculation will always overflow", left) elif left.value < -(2**value_bits): raise OverflowException( "Base is too small, calculation will always underflow", left) elif isinstance(right, vy_ast.Int): if right.value < 0: raise InvalidOperation("Cannot calculate a negative power", right) if right.value > value_bits: raise OverflowException( "Power is too large, calculation will always overflow", right) else: msg = ( "Cannot apply an overflow check on exponentiation when both " "the base and power are unknown at compile-time.") if not self._is_signed: msg = ( f"{msg} To perform this operation without an overflow check, use " f"`pow_mod256({left.node_source_code}, {right.node_source_code})`" ) raise InvalidOperation(msg, node)
def _validate_numeric_bounds(node: Union["BinOp", "UnaryOp"], value: Union[decimal.Decimal, int]) -> None: if isinstance(value, decimal.Decimal): lower, upper = SizeLimits.MIN_INT128, SizeLimits.MAX_INT128 elif isinstance(value, int): lower, upper = SizeLimits.MIN_INT256, SizeLimits.MAX_UINT256 else: raise CompilerPanic( f"Unexpected return type from {node._op}: {type(value)}") if not lower <= value <= upper: raise OverflowException( f"Result of {node.op.description} ({value}) is outside bounds of all numeric types", node, )
def types_from_Constant(self, node): # literal value (integer, string, etc) types_list = [] for primitive in types.get_primitive_types().values(): try: obj = primitive.from_literal(node) types_list.append(obj) except VyperException: continue if types_list: return types_list if isinstance(node, vy_ast.Num): raise OverflowException( "Numeric literal is outside of allowable range for number types", node, ) raise InvalidLiteral(f"Could not determine type for literal value '{node.value}'", node)