def evaluate(self) -> VyperNode: """ Attempt to evaluate the comparison. Returns ------- NameConstant Node representing the result of the evaluation. """ left, right = self.left, self.right if not isinstance(left, Constant): raise UnfoldableNode("Node contains invalid field(s) for evaluation") if isinstance(self.op, (In, NotIn)): if not isinstance(right, List): raise UnfoldableNode("Node contains invalid field(s) for evaluation") if next((i for i in right.elements if not isinstance(i, Constant)), None): raise UnfoldableNode("Node contains invalid field(s) for evaluation") if len(set([type(i) for i in right.elements])) > 1: raise UnfoldableNode("List contains multiple literal types") value = self.op._op(left.value, [i.value for i in right.elements]) return NameConstant.from_node(self, value=value) if not isinstance(left, type(right)): raise UnfoldableNode("Cannot compare different literal types") if not isinstance(self.op, (Eq, NotEq)) and not isinstance(left, (Int, Decimal)): raise TypeMismatch(f"Invalid literal types for {self.op.description} comparison", self) value = self.op._op(left.value, right.value) return NameConstant.from_node(self, value=value)
def evaluate(self) -> VyperNode: """ Attempt to evaluate the unary operation. Returns ------- Int | Decimal Node representing the result of the evaluation. """ if isinstance(self.op, Not) and not isinstance(self.operand, NameConstant): raise UnfoldableNode("Node contains invalid field(s) for evaluation") if isinstance(self.op, USub) and not isinstance(self.operand, (Int, Decimal)): raise UnfoldableNode("Node contains invalid field(s) for evaluation") value = self.op._op(self.operand.value) _validate_numeric_bounds(self, value) return type(self.operand).from_node(self, value=value)
def evaluate(self) -> "VyperNode": """ Attempt to evaluate the content of a node and generate a new node from it. If a node cannot be evaluated it should raise `UnfoldableNode`. This base method acts as a catch-all to raise on any inherited classes that do not implement the method. """ raise UnfoldableNode(f"{type(self)} cannot be evaluated")
def evaluate(self) -> VyperNode: """ Attempt to evaluate the boolean operation. Returns ------- NameConstant Node representing the result of the evaluation. """ if next((i for i in self.values if not isinstance(i, NameConstant)), None): raise UnfoldableNode("Node contains invalid field(s) for evaluation") values = [i.value for i in self.values] if None in values: raise UnfoldableNode("Node contains invalid field(s) for evaluation") value = self.op._op(values) return NameConstant.from_node(self, value=value)
def evaluate(self) -> VyperNode: """ Attempt to evaluate the arithmetic operation. Returns ------- Int | Decimal Node representing the result of the evaluation. """ left, right = self.left, self.right if type(left) is not type(right): raise UnfoldableNode("Node contains invalid field(s) for evaluation") if not isinstance(left, (Int, Decimal)): raise UnfoldableNode("Node contains invalid field(s) for evaluation") value = self.op._op(left.value, right.value) _validate_numeric_bounds(self, value) return type(left).from_node(self, value=value)
def evaluate(self) -> VyperNode: """ Attempt to evaluate the subscript. This method reduces an indexed reference to a literal array into the value within the array, e.g. `["foo", "bar"][1]` becomes `"bar"` Returns ------- VyperNode Node representing the result of the evaluation. """ if not isinstance(self.value, List): raise UnfoldableNode("Subscript object is not a literal list") elements = self.value.elements if len(set([type(i) for i in elements])) > 1: raise UnfoldableNode("List contains multiple node types") idx = self.slice.get("value.value") if not isinstance(idx, int) or idx < 0 or idx >= len(elements): raise UnfoldableNode("Invalid index value") return elements[idx]