Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_return_mismatch(bad_code):
with raises(StructureException):
compiler.compile_code(bad_code)
def pre_parser(code):
result = []
g = tokenize.tokenize(io.BytesIO(code.encode('utf-8')).readline)
for token in g:
# Alias contract definition to class definition.
if token.type == COMMENT and "@version" in token.string:
parse_version_pragma(token.string[1:])
if (token.type, token.string, token.start[1]) == (NAME, "contract", 0):
token = TokenInfo(token.type, "class", token.start, token.end, token.line)
# Prevent semi-colon line statements.
elif (token.type, token.string) == (OP, ";"):
raise StructureException("Semi-colon statements not allowed.", token.start)
result.append(token)
return tokenize.untokenize(result).decode('utf-8')
def add_globals_and_events(_custom_units, _contracts, _defs, _events, _getters, _globals, item):
item_attributes = {"public": False}
if not (isinstance(item.annotation, ast.Call) and item.annotation.func.id == "event"):
item_name, item_attributes = get_item_name_and_attributes(item, item_attributes)
if not all([attr in valid_global_keywords for attr in item_attributes.keys()]):
raise StructureException('Invalid global keyword used: %s' % item_attributes, item)
if item.value is not None:
raise StructureException('May not assign value whilst defining type', item)
if isinstance(item.annotation, ast.Call) and item.annotation.func.id == "event":
if _globals or len(_defs):
raise StructureException("Events must all come before global declarations and function definitions", item)
_events.append(item)
elif not isinstance(item.target, ast.Name):
raise StructureException("Can only assign type to variable in top-level statement", item)
# Is this a custom unit definition.
elif item.target.id == 'units':
if not _custom_units:
if not isinstance(item.annotation, ast.Dict):
raise VariableDeclarationException("Define custom units using units: { }.", item.target)
for key, value in zip(item.annotation.keys, item.annotation.values):
if not isinstance(value, ast.Str):
raise VariableDeclarationException("Custom unit description must be a valid string.", value)
if not isinstance(self.context.return_type, TupleType):
raise TypeMismatchException(
f"Trying to return tuple type {sub.typ}, output expecting "
f"{self.context.return_type}",
self.stmt.value,
)
if len(self.context.return_type.members) != len(sub.typ.members):
raise StructureException("Tuple lengths don't match!", self.stmt)
# check return type matches, sub type.
for i, ret_x in enumerate(self.context.return_type.members):
s_member = sub.typ.members[i]
sub_type = s_member if isinstance(s_member, NodeType) else s_member.typ
if type(sub_type) is not type(ret_x):
raise StructureException(
"Tuple return type does not match annotated return. "
f"{type(sub_type)} != {type(ret_x)}",
self.stmt
)
return gen_tuple_return(self.stmt, self.context, sub)
else:
raise TypeMismatchException(f"Can't return type {sub.typ}", self.stmt)
def add_contract(code):
_defs = []
for item in code:
# Function definitions
if isinstance(item, ast.FunctionDef):
_defs.append(item)
else:
raise StructureException("Invalid contract reference", item)
return _defs
def get_item_name_and_attributes(self, item, attributes):
is_map_invocation = (
(
isinstance(item, ast.Call) and isinstance(item.func, ast.Name)
) and item.func.id == 'map'
)
if isinstance(item, ast.Name):
return item.id, attributes
elif isinstance(item, ast.AnnAssign):
return self.get_item_name_and_attributes(item.annotation, attributes)
elif isinstance(item, ast.Subscript):
return self.get_item_name_and_attributes(item.value, attributes)
elif is_map_invocation:
if len(item.args) != 2:
raise StructureException(
"Map type expects two type arguments map(type1, type2)", item.func
)
return self.get_item_name_and_attributes(item.args, attributes)
# elif ist
elif isinstance(item, ast.Call) and isinstance(item.func, ast.Name):
attributes[item.func.id] = True
# Raise for multiple args
if len(item.args) != 1:
raise StructureException(f"{item.func.id} expects one arg (the type)")
return self.get_item_name_and_attributes(item.args[0], attributes)
return None, attributes
def _assert_reason(self, test_expr, msg):
if isinstance(msg, ast.Name) and msg.id == 'UNREACHABLE':
return self._assert_unreachable(test_expr, msg)
if not isinstance(msg, ast.Str):
raise StructureException(
'Reason parameter of assert needs to be a literal string '
'(or UNREACHABLE constant).',
msg
)
if len(msg.s.strip()) == 0:
raise StructureException(
'Empty reason string not allowed.', self.stmt
)
reason_str = msg.s.strip()
sig_placeholder = self.context.new_placeholder(BaseType(32))
arg_placeholder = self.context.new_placeholder(BaseType(32))
reason_str_type = ByteArrayType(len(reason_str))
placeholder_bytes = Expr(msg, self.context).lll_node
method_id = fourbytes_to_int(keccak256(b"Error(string)")[:4])
assert_reason = [
'seq',
# from .parser import (
# parse_body,
# )
# Type 0 for, e.g. for i in list(): ...
if self._is_list_iter():
return self.parse_for_list()
is_invalid_for_statement = any((
not isinstance(self.stmt.iter, ast.Call),
not isinstance(self.stmt.iter.func, ast.Name),
not isinstance(self.stmt.target, ast.Name),
self.stmt.iter.func.id != "range",
len(self.stmt.iter.args) not in {1, 2},
))
if is_invalid_for_statement:
raise StructureException((
"For statements must be of the form `for i in range(rounds): "
"..` or `for i in range(start, start + rounds): ..`"
), self.stmt.iter)
block_scope_id = id(self.stmt)
with self.context.make_blockscope(block_scope_id):
# Get arg0
arg0 = self.stmt.iter.args[0]
num_of_args = len(self.stmt.iter.args)
# Type 1 for, e.g. for i in range(10): ...
if num_of_args == 1:
arg0_val = self._get_range_const_value(arg0)
start = LLLnode.from_list(0, typ='int128', pos=getpos(self.stmt))
rounds = arg0_val
raise StructureException("Bad decorator", dec)
if public and private:
raise StructureException(
f"Cannot use public and private decorators on the same function: {name}"
)
if payable and const:
raise StructureException(
f"Function {name} cannot be both constant and payable."
)
if payable and private:
raise StructureException(
f"Function {name} cannot be both private and payable."
)
if (not public and not private) and not contract_def:
raise StructureException(
"Function visibility must be declared (@public or @private)",
code,
)
if const and nonreentrant_key:
raise StructureException("@nonreentrant makes no sense on a @constant function.", code)
# Determine the return type and whether or not it's constant. Expects something
# of the form:
# def foo(): ...
# def foo() -> int128: ...
# If there is no return type, ie. it's of the form def foo(): ...
# and NOT def foo() -> type: ..., then it's null
if not code.returns:
output_type = None
elif isinstance(code.returns, (ast.Name, ast.Compare, ast.Subscript, ast.Call, ast.Tuple)):
output_type = parse_type(