示例#1
0
def parse_unit(item, custom_units):
    if isinstance(item, vy_ast.Name):
        if (item.id not in VALID_UNITS) and (custom_units is not None) and (
                item.id not in custom_units):  # noqa: E501
            raise InvalidType("Invalid base unit", item)
        return {item.id: 1}
    elif isinstance(item, vy_ast.Int) and item.n == 1:
        return {}
    elif not isinstance(item, vy_ast.BinOp):
        raise InvalidType("Invalid unit expression", item)
    elif isinstance(item.op, vy_ast.Mult):
        left, right = parse_unit(item.left, custom_units), parse_unit(
            item.right, custom_units)
        return combine_units(left, right)
    elif isinstance(item.op, vy_ast.Div):
        left, right = parse_unit(item.left, custom_units), parse_unit(
            item.right, custom_units)
        return combine_units(left, right, div=True)
    elif isinstance(item.op, vy_ast.Pow):
        if not isinstance(item.left, vy_ast.Name):
            raise InvalidType("Can only raise a base type to an exponent",
                              item)
        if not isinstance(item.right, vy_ast.Int) or not isinstance(
                item.right.n, int) or item.right.n <= 0:  # noqa: E501
            raise InvalidType("Exponent must be positive integer", item)
        return {item.left.id: item.right.n}
    else:
        raise InvalidType("Invalid unit expression", item)
示例#2
0
def canonicalize_type(t, is_indexed=False):
    if isinstance(t, ByteArrayLike):
        # Check to see if maxlen is small enough for events
        byte_type = 'string' if isinstance(t, StringType) else 'bytes'
        if is_indexed:
            return f'{byte_type}{t.maxlen}'
        else:
            return f'{byte_type}'

    if isinstance(t, ListType):
        if not isinstance(t.subtype, (ListType, BaseType)):
            raise InvalidType(f"List of {t.subtype}s not allowed")
        return canonicalize_type(t.subtype) + f"[{t.count}]"

    if isinstance(t, TupleLike):
        return f"({','.join(canonicalize_type(x) for x in t.tuple_members())})"

    if not isinstance(t, BaseType):
        raise InvalidType(f"Cannot canonicalize non-base type: {t}")

    t = t.typ
    if t in ('int128', 'uint256', 'bool', 'address', 'bytes32'):
        return t
    elif t == 'decimal':
        return 'fixed168x10'

    raise InvalidType(f"Invalid or unsupported type: {repr(t)}")
示例#3
0
def get_static_size_of_type(typ):
    if isinstance(typ, BaseType):
        return 1
    elif isinstance(typ, ByteArrayLike):
        return 1
    elif isinstance(typ, ListType):
        return get_size_of_type(typ.subtype) * typ.count
    elif isinstance(typ, MappingType):
        raise InvalidType("Maps are not supported for function arguments or outputs.")
    elif isinstance(typ, TupleLike):
        return sum([get_size_of_type(v) for v in typ.tuple_members()])
    else:
        raise InvalidType(f"Can not get size of type, Unexpected type: {repr(typ)}")
示例#4
0
def get_size_of_type(typ):
    if isinstance(typ, BaseType):
        return 1
    elif isinstance(typ, ByteArrayLike):
        # 1 word for offset (in static section), 1 word for length,
        # up to maxlen words for actual data.
        return ceil32(typ.maxlen) // 32 + 2
    elif isinstance(typ, ListType):
        return get_size_of_type(typ.subtype) * typ.count
    elif isinstance(typ, MappingType):
        raise InvalidType("Maps are not supported for function arguments or outputs.")
    elif isinstance(typ, TupleLike):
        return sum([get_size_of_type(v) for v in typ.tuple_members()])
    else:
        raise InvalidType(f"Can not get size of type, Unexpected type: {repr(typ)}")
示例#5
0
def validate_expected_type(node, expected_type):
    """
    Validate that the given node matches the expected type(s)

    Raises if the node does not match one of the expected types.

    Arguments
    ---------
    node : VyperNode
        Vyper ast node.
    expected_type : Tuple | BaseType
        A type object, or tuple of type objects

    Returns
    -------
    None
    """
    given_types = _ExprTypeChecker().get_possible_types_from_node(node)
    if not isinstance(expected_type, tuple):
        expected_type = (expected_type, )

    if isinstance(node, (vy_ast.List, vy_ast.Tuple)):
        # special case - for literal arrays or tuples we individually validate each item
        for expected in (i for i in expected_type
                         if isinstance(i, ArrayDefinition)):
            if _validate_literal_array(node, expected):
                return
    else:
        for given, expected in itertools.product(given_types, expected_type):
            if expected.compare_type(given):
                return

    # validation failed, prepare a meaningful error message
    if len(expected_type) > 1:
        expected_str = f"one of {', '.join(str(i) for i in expected_type)}"
    else:
        expected_str = expected_type[0]

    if len(given_types) == 1 and getattr(given_types[0], "_is_callable",
                                         False):
        raise StructureException(
            f"{given_types[0]} cannot be referenced directly, it must be called",
            node)

    if not isinstance(node,
                      (vy_ast.List, vy_ast.Tuple)) and node.get_descendants(
                          vy_ast.Name, include_self=True):
        given = given_types[0]
        raise TypeMismatch(
            f"Given reference has type {given}, expected {expected_str}", node)
    else:
        if len(given_types) == 1:
            given_str = str(given_types[0])
        else:
            types_str = sorted(str(i) for i in given_types)
            given_str = f"{', '.join(types_str[:1])} or {types_str[-1]}"

        raise InvalidType(
            f"Expected {expected_str} but literal can only be cast as {given_str}",
            node)
示例#6
0
 def types_from_Call(self, node):
     # function calls, e.g. `foo()`
     var = self.get_exact_type_from_node(node.func, False)
     return_value = var.fetch_call_return(node)
     if return_value:
         return [return_value]
     raise InvalidType(f"{var} did not return a value", node)
示例#7
0
    def make_struct(self, node: "vy_ast.StructDef") -> list:
        members = []

        for item in node.body:
            if isinstance(item, vy_ast.AnnAssign):
                member_name = item.target
                member_type = item.annotation
                # Check well-formedness of member names
                if not isinstance(member_name, vy_ast.Name):
                    raise InvalidType(
                        f"Invalid member name for struct {node.name}, needs to be a valid name. ",
                        item,
                    )
                # Check well-formedness of member types
                # Note this kicks out mutually recursive structs,
                # raising an exception instead of stackoverflow.
                # A struct must be defined before it is referenced.
                # This feels like a semantic step and maybe should be pushed
                # to a later compilation stage.
                parse_type(
                    member_type,
                    "storage",
                    custom_structs=self._structs,
                )
                members.append((member_name, member_type))
            else:
                raise StructureException("Structs can only contain variables",
                                         item)
        return members
示例#8
0
def make_struct_type(name, location, members, custom_units, custom_structs,
                     constants):
    o = OrderedDict()

    for key, value in members:
        if not isinstance(key, vy_ast.Name):
            raise InvalidType(
                f"Invalid member variable for struct {key.id}, expected a name.",
                key,
            )
        check_valid_varname(
            key.id,
            custom_units,
            custom_structs,
            constants,
            "Invalid member variable for struct",
        )
        o[key.id] = parse_type(
            value,
            location,
            custom_units=custom_units,
            custom_structs=custom_structs,
            constants=constants,
        )

    return StructType(o, name)
示例#9
0
def new_type_to_old_type(typ: new.BasePrimitive) -> old.NodeType:
    if isinstance(typ, new.BoolDefinition):
        return old.BaseType("bool")
    if isinstance(typ, new.AddressDefinition):
        return old.BaseType("address")
    if isinstance(typ, new.Bytes32Definition):
        return old.BaseType("bytes32")
    if isinstance(typ, new.BytesArrayDefinition):
        return old.ByteArrayType(typ.length)
    if isinstance(typ, new.StringDefinition):
        return old.StringType(typ.length)
    if isinstance(typ, new.DecimalDefinition):
        return old.BaseType("decimal")
    if isinstance(typ, new.SignedIntegerAbstractType):
        bits = typ._bits  # type: ignore
        return old.BaseType("int" + str(bits))
    if isinstance(typ, new.UnsignedIntegerAbstractType):
        bits = typ._bits  # type: ignore
        return old.BaseType("uint" + str(bits))
    if isinstance(typ, new.ArrayDefinition):
        return old.SArrayType(new_type_to_old_type(typ.value_type), typ.length)
    if isinstance(typ, new.DynamicArrayDefinition):
        return old.DArrayType(new_type_to_old_type(typ.value_type), typ.length)
    if isinstance(typ, new.TupleDefinition):
        return old.TupleType(typ.value_type)
    if isinstance(typ, new.StructDefinition):
        return old.StructType(
            {n: new_type_to_old_type(t)
             for (n, t) in typ.members.items()}, typ._id)
    raise InvalidType(f"unknown type {typ}")
示例#10
0
def _validate_revert_reason(msg_node: vy_ast.VyperNode) -> None:
    if msg_node:
        if isinstance(msg_node, vy_ast.Str):
            if not msg_node.value.strip():
                raise StructureException("Reason string cannot be empty", msg_node)
        elif not (isinstance(msg_node, vy_ast.Name) and msg_node.id == "UNREACHABLE"):
            raise InvalidType("Reason must UNREACHABLE or a string literal", msg_node)
示例#11
0
 def validate_index_type(self, node):
     if not isinstance(node, vy_ast.Int):
         raise InvalidType("Tuple indexes must be literals", node)
     if node.value < 0:
         raise ArrayIndexException("Vyper does not support negative indexing", node)
     if node.value >= self.length:
         raise ArrayIndexException("Index out of range", node)
示例#12
0
def get_index_value(node: vy_ast.Index) -> int:
    """
    Return the literal value for a `Subscript` index.

    Arguments
    ---------
    node : vy_ast.Index
        Vyper ast node from the `slice` member of a Subscript node. Must be an
        `Index` object (Vyper does not support `Slice` or `ExtSlice`).

    Returns
    -------
    int
        Literal integer value.
    """

    if not isinstance(node.get("value"), vy_ast.Int):
        if hasattr(node, "value"):
            # even though the subscript is an invalid type, first check if it's a valid _something_
            # this gives a more accurate error in case of e.g. a typo in a constant variable name
            try:
                get_possible_types_from_node(node.value)
            except StructureException:
                # StructureException is a very broad error, better to raise InvalidType in this case
                pass

        raise InvalidType("Subscript must be a literal integer", node)

    if node.value.value <= 0:
        raise ArrayIndexException("Subscript must be greater than 0", node)

    return node.value.value
示例#13
0
文件: utils.py 项目: vyperlang/vyper
def get_type_from_annotation(
    node: vy_ast.VyperNode,
    location: DataLocation,
    is_constant: bool = False,
    is_public: bool = False,
    is_immutable: bool = False,
) -> BaseTypeDefinition:
    """
    Return a type object for the given AST node.

    Arguments
    ---------
    node : VyperNode
        Vyper ast node from the `annotation` member of a `VariableDef` or `AnnAssign` node.

    Returns
    -------
    BaseTypeDefinition
        Type definition object.
    """
    namespace = get_namespace()

    if isinstance(node, vy_ast.Tuple):
        values = node.elements
        types = tuple(
            get_type_from_annotation(v, DataLocation.UNSET) for v in values)
        return TupleDefinition(types)

    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))
    except StopIteration:
        raise StructureException("Invalid syntax for type declaration", node)
    try:
        type_obj = namespace[type_name]
    except UndeclaredDefinition:
        suggestions_str = get_levenshtein_error_suggestions(
            type_name, namespace, 0.3)
        raise UnknownType(
            f"No builtin or user-defined type named '{type_name}'. {suggestions_str}",
            node) from None

    if (getattr(type_obj, "_as_array", False)
            and isinstance(node, vy_ast.Subscript)
            and node.value.get("id") != "DynArray"):
        # TODO: handle `is_immutable` for arrays
        # 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_constant, False, is_immutable)
        return ArrayDefinition(value_type, length, location, is_constant,
                               is_public, is_immutable)

    try:
        return type_obj.from_annotation(node, location, is_constant, is_public,
                                        is_immutable)
    except AttributeError:
        raise InvalidType(f"'{type_name}' is not a valid type", node) from None
示例#14
0
    def visit_Assert(self, node):
        if node.msg:
            _validate_revert_reason(node.msg)

        try:
            validate_expected_type(node.test, BoolDefinition())
        except InvalidType:
            raise InvalidType("Assertion test value must be a boolean", node.test)
示例#15
0
    def add_globals_and_events(self, item):
        item_attributes = {"public": False}

        if self._nonrentrant_counter:
            raise CompilerPanic(
                "Re-entrancy lock was set before all storage slots were defined"
            )

        # Make sure we have a valid variable name.
        if not isinstance(item.target, vy_ast.Name):
            raise StructureException("Invalid global variable name",
                                     item.target)

        # Handle constants.
        if self.get_call_func_name(item) == "constant":
            return

        item_name, item_attributes = self.get_item_name_and_attributes(
            item, item_attributes)

        # references to `len(self._globals)` are remnants of deprecated code, retained
        # to preserve existing interfaces while we complete a larger refactor. location
        # and size of storage vars is handled in `vyper.context.validation.data_positions`
        if item_name in self._contracts or item_name in self._interfaces:
            if self.get_call_func_name(item) == "address":
                raise StructureException(
                    f"Persistent address({item_name}) style contract declarations "
                    "are not support anymore."
                    f" Use {item.target.id}: {item_name} instead")
            self._globals[item.target.id] = ContractRecord(
                item.target.id,
                len(self._globals),
                InterfaceType(item_name),
                True,
            )
        elif self.get_call_func_name(item) == "public":
            if isinstance(item.annotation.args[0],
                          vy_ast.Name) and item_name in self._contracts:
                typ = InterfaceType(item_name)
            else:
                typ = self.parse_type(item.annotation.args[0], "storage")
            self._globals[item.target.id] = VariableRecord(
                item.target.id,
                len(self._globals),
                typ,
                True,
            )

        elif isinstance(item.annotation,
                        (vy_ast.Name, vy_ast.Call, vy_ast.Subscript)):
            self._globals[item.target.id] = VariableRecord(
                item.target.id,
                len(self._globals),
                self.parse_type(item.annotation, "storage"),
                True,
            )
        else:
            raise InvalidType("Invalid global type specified", item)
示例#16
0
def make_struct_type(name, sigs, members, custom_structs, enums):
    o = OrderedDict()

    for key, value in members:
        if not isinstance(key, vy_ast.Name):
            raise InvalidType(f"Invalid member variable for struct {key.id}, expected a name.", key)
        o[key.id] = parse_type(value, sigs=sigs, custom_structs=custom_structs, enums=enums)

    return StructType(o, name)
示例#17
0
def parse_integer_typeinfo(typename: str) -> IntegerTypeInfo:
    t = _int_parser.fullmatch(typename)
    if not t:
        raise InvalidType(f"Invalid integer type {typename}")  # pragma: notest

    return IntegerTypeInfo(
        is_signed=t.group(1) != "u",
        bits=int(t.group(2)),
    )
示例#18
0
    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 `InvalidType`. This base
        method acts as a catch-all to raise on any inherited classes that do not
        implement the method.
        """
        raise InvalidType(f"{type(self)} cannot be evaluated", self)
示例#19
0
    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 InvalidType("Node contains invalid field(s) for evaluation",
                              self)
        if not isinstance(left, (Int, Decimal)):
            raise InvalidType("Node contains invalid field(s) for evaluation",
                              self)

        value = self.op._op(left.value, right.value)
        return type(left).from_node(self, value=value)
示例#20
0
    def fetch_call_return(self,
                          node: vy_ast.Call) -> Optional[BaseTypeDefinition]:
        if node.get(
                "func.value.id"
        ) == "self" and self.visibility == FunctionVisibility.EXTERNAL:
            raise CallViolation("Cannot call external functions via 'self'",
                                node)

        # for external calls, include gas and value as optional kwargs
        kwarg_keys = self.kwarg_keys.copy()
        if node.get("func.value.id") != "self":
            kwarg_keys += list(self.call_site_kwargs.keys())
        validate_call_args(node, (self.min_arg_count, self.max_arg_count),
                           kwarg_keys)

        if self.mutability < StateMutability.PAYABLE:
            kwarg_node = next((k for k in node.keywords if k.arg == "value"),
                              None)
            if kwarg_node is not None:
                raise CallViolation("Cannot send ether to nonpayable function",
                                    kwarg_node)

        for arg, expected in zip(node.args, self.arguments.values()):
            validate_expected_type(arg, expected)

        # TODO this should be moved to validate_call_args
        for kwarg in node.keywords:
            if kwarg.arg in self.call_site_kwargs:
                kwarg_settings = self.call_site_kwargs[kwarg.arg]
                validate_expected_type(kwarg.value, kwarg_settings.typ)
                if kwarg_settings.require_literal:
                    if not isinstance(kwarg.value, vy_ast.Constant):
                        raise InvalidType(
                            f"{kwarg.arg} must be literal {kwarg_settings.typ}",
                            kwarg.value)
            else:
                # Generate the modified source code string with the kwarg removed
                # as a suggestion to the user.
                kwarg_pattern = rf"{kwarg.arg}\s*=\s*{re.escape(kwarg.value.node_source_code)}"
                modified_line = re.sub(kwarg_pattern,
                                       kwarg.value.node_source_code,
                                       node.node_source_code)
                error_suggestion = (
                    f"\n(hint: Try removing the kwarg: `{modified_line}`)"
                    if modified_line != node.node_source_code else "")

                raise ArgumentException(
                    ("Usage of kwarg in Vyper is restricted to " +
                     ", ".join([f"{k}="
                                for k in self.call_site_kwargs.keys()]) +
                     f". {error_suggestion}"),
                    kwarg,
                )

        return self.return_type
示例#21
0
    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 InvalidType("Node contains invalid field(s) for evaluation",
                              self)
        if isinstance(self.op,
                      USub) and not isinstance(self.operand, (Int, Decimal)):
            raise InvalidType("Node contains invalid field(s) for evaluation",
                              self)

        value = self.op._op(self.operand.value)
        return type(self.operand).from_node(self, value=value)
示例#22
0
def has_dynamic_data(typ):
    if isinstance(typ, BaseType):
        return False
    elif isinstance(typ, ByteArrayLike):
        return True
    elif isinstance(typ, ListType):
        return has_dynamic_data(typ.subtype)
    elif isinstance(typ, TupleLike):
        return any([has_dynamic_data(v) for v in typ.tuple_members()])
    else:
        raise InvalidType(f"Unexpected type: {repr(typ)}")
示例#23
0
    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 InvalidType("Node contains invalid field(s) for evaluation",
                              self)

        values = [i.value for i in self.values]
        if None in values:
            raise InvalidType("Node contains invalid field(s) for evaluation",
                              self)

        value = self.op._op(values)
        return NameConstant.from_node(self, value=value)
示例#24
0
    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 InvalidType("Node contains invalid field(s) for evaluation",
                              self)

        if isinstance(self.op, In):
            if not isinstance(right, List):
                raise InvalidType(
                    "Node contains invalid field(s) for evaluation", self)
            if next((i for i in right.elts if not isinstance(i, Constant)),
                    None):
                raise InvalidType(
                    "Node contains invalid field(s) for evaluation", self)
            if len(set([type(i) for i in right.elts])) > 1:
                raise InvalidType("List contains multiple literal types",
                                  self.right)
            value = self.op._op(left.value, [i.value for i in right.elts])
            return NameConstant.from_node(self, value=value)

        if not isinstance(left, type(right)):
            raise InvalidType("Cannot compare different literal types", self)

        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)
示例#25
0
文件: local.py 项目: vyperlang/vyper
def _validate_revert_reason(msg_node: vy_ast.VyperNode) -> None:
    if msg_node:
        if isinstance(msg_node, vy_ast.Str):
            if not msg_node.value.strip():
                raise StructureException("Reason string cannot be empty",
                                         msg_node)
        elif not (isinstance(msg_node, vy_ast.Name)
                  and msg_node.id == "UNREACHABLE"):
            try:
                validate_expected_type(msg_node, StringDefinition(1024))
            except TypeMismatch as e:
                raise InvalidType(
                    "revert reason must fit within String[1024]") from e
示例#26
0
    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 InvalidType("Subscript object is not a literal list",
                              self.value)
        elts = self.value.elts
        if len(set([type(i) for i in elts])) > 1:
            raise InvalidType("List contains multiple node types", self.value)
        idx = self.slice.get('value.value')
        if not isinstance(idx, int) or idx < 0 or idx >= len(elts):
            raise InvalidType("Invalid index value", self.slice)

        return elts[idx]
示例#27
0
def canonicalize_type(t, is_indexed=False):
    if isinstance(t, ByteArrayLike):
        # Check to see if maxlen is small enough for events
        byte_type = "string" if isinstance(t, StringType) else "bytes"
        return byte_type

    if isinstance(t, ListType):
        if not isinstance(t.subtype, (ListType, BaseType)):
            raise InvalidType(f"List of {t.subtype} not allowed")
        return canonicalize_type(t.subtype) + f"[{t.count}]"

    if isinstance(t, TupleLike):
        return f"({','.join(canonicalize_type(x) for x in t.tuple_members())})"

    if not isinstance(t, BaseType):
        raise InvalidType(f"Cannot canonicalize non-base type: {t}")

    t = t.typ
    if t in ("int128", "uint256", "bool", "address", "bytes32"):
        return t
    elif t == "decimal":
        return "fixed168x10"

    raise InvalidType(f"Invalid or unsupported type: {repr(t)}")
示例#28
0
        def check_input_type(expr, arg, out_typ):
            # convert arg to out_typ.
            # (expr is the AST corresponding to `arg`)
            ityp = _type_class_of(arg.typ)
            ok = ityp in allowed_types
            if not ok:
                _FAIL(arg.typ, out_typ, expr)

            # user safety: disallow convert from type to itself
            # note allowance of [u]int256; this is due to type inference
            # on literals not quite working yet.
            if arg.typ == out_typ and not is_base_type(arg.typ, ("uint256", "int256")):
                raise InvalidType(f"value and target are both {out_typ}", expr)

            return f(expr, arg, out_typ)
示例#29
0
文件: types.py 项目: skellet0r/vyper
def _basetype_to_abi_type(t: "BaseType") -> ABIType:
    if is_integer_type(t):
        typinfo = parse_integer_typeinfo(t.typ)
        return ABI_GIntM(typinfo.bits, typinfo.is_signed)
    if t.typ == "address":
        return ABI_Address()
    if t.typ == "bytes32":
        # TODO must generalize to more bytes types
        return ABI_BytesM(32)
    if t.typ == "bool":
        return ABI_Bool()
    if t.typ == "decimal":
        return ABI_FixedMxN(168, 10, True)

    raise InvalidType(f"Unrecognized type {t}")  # pragma: notest
示例#30
0
def _basetype_to_abi_type(t: "BaseType") -> ABIType:
    if is_integer_type(t):
        info = t._int_info
        return ABI_GIntM(info.bits, info.is_signed)
    if is_decimal_type(t):
        info = t._decimal_info
        return ABI_FixedMxN(info.bits, info.decimals, signed=True)
    if is_bytes_m_type(t):
        return ABI_BytesM(t._bytes_info.m)
    if t.typ == "address":
        return ABI_Address()
    if t.typ == "bool":
        return ABI_Bool()

    raise InvalidType(f"Unrecognized type {t}")  # pragma: notest