def test_subscript_negative(build_node, namespace): node = build_node("foo[-1]") type_def = Int128Definition() namespace["foo"] = ArrayDefinition(type_def, 3) with pytest.raises(ArrayIndexException): get_possible_types_from_node(node)
def get_type_from_abi( abi_type: Dict, location: DataLocation = DataLocation.UNSET, is_immutable: bool = False, is_public: bool = False, ) -> BaseTypeDefinition: """ Return a type object from an ABI type definition. Arguments --------- abi_type : Dict A type definition taken from the `input` or `output` field of an ABI. Returns ------- BaseTypeDefinition Type definition object. """ type_string = abi_type["type"] if type_string == "fixed168x10": type_string = "decimal" if type_string in ("string", "bytes"): type_string = type_string.capitalize() namespace = get_namespace() if "[" in type_string: value_type_string, length_str = type_string.rsplit("[", maxsplit=1) try: length = int(length_str.rstrip("]")) except ValueError: raise UnknownType(f"ABI type has an invalid length: {type_string}") from None try: value_type = get_type_from_abi( {"type": value_type_string}, location=location, is_immutable=is_immutable ) except UnknownType: raise UnknownType(f"ABI contains unknown type: {type_string}") from None try: return ArrayDefinition( value_type, length, location=location, is_immutable=is_immutable, is_public=is_public, ) except InvalidType: raise UnknownType(f"ABI contains unknown type: {type_string}") from None else: try: return namespace[type_string]._type( location=location, is_immutable=is_immutable, is_public=is_public ) except KeyError: raise UnknownType(f"ABI contains unknown type: {type_string}") from None
def types_from_List(self, node): # literal array if not node.elements: raise InvalidLiteral("Cannot have an empty array", node) types_list = get_common_types(*node.elements) if types_list: return [ArrayDefinition(i, len(node.elements)) for i in types_list] raise InvalidLiteral("Array contains multiple, incompatible types", node)
def get_type_from_annotation( node: vy_ast.VyperNode, location: DataLocation, is_immutable: bool = False, is_public: bool = False, ) -> BaseTypeDefinition: """ Return a type object for the given AST node. Arguments --------- node : VyperNode Vyper ast node from the `annotation` member of an `AnnAssign` node. Returns ------- BaseTypeDefinition Type definition object. """ namespace = get_namespace() try: # get id of leftmost `Name` node from the annotation type_name = next( i.id for i in node.get_descendants(vy_ast.Name, include_self=True)) type_obj = namespace[type_name] except StopIteration: raise StructureException("Invalid syntax for type declaration", node) except UndeclaredDefinition: raise UnknownType("Not a valid type - value is undeclared", node) from None if getattr(type_obj, "_as_array", False) and isinstance( node, vy_ast.Subscript): # if type can be an array and node is a subscript, create an `ArrayDefinition` length = get_index_value(node.slice) value_type = get_type_from_annotation(node.value, location, is_immutable, False) return ArrayDefinition(value_type, length, location, is_immutable, is_public) try: return type_obj.from_annotation(node, location, is_immutable, is_public) except AttributeError: raise UnknownType(f"'{type_name}' is not a valid type", node) from None
def test_subscript(build_node, namespace): node = build_node("foo[1]") type_def = Int128Definition() namespace["foo"] = ArrayDefinition(type_def, 3) assert get_possible_types_from_node(node) == [type_def]