Skip to content

Commit

Permalink
Merge branch 'master' into immutables_layout
Browse files Browse the repository at this point in the history
  • Loading branch information
charles-cooper committed Apr 30, 2022
2 parents 613fe67 + df29609 commit 33074bc
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 18 deletions.
1 change: 0 additions & 1 deletion docs/control-structures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ Internal functions (marked with the ``@internal`` decorator) are only accessible
def calculate(amount: uint256) -> uint256:
return self._times_two(amount)
Internal functions do not have access to ``msg.sender`` or ``msg.value``. If you require these values within an internal function you must pass them as parameters.
Mutability
----------
Expand Down
13 changes: 13 additions & 0 deletions docs/release-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@
Release Notes
#############

v0.3.3
******

Date released: 2022-04-22

This is a bugfix release. It patches an off-by-one error in the storage allocation mechanism for dynamic arrays reported by @haltman-at in `#2820 <https://github.com/vyperlang/vyper/issues/2820>`_

Other fixes and improvements:

* Add a ``print`` built-in which allows printing debugging messages in hardhat. (`#2818 <https://github.com/vyperlang/vyper/pull/2818>`_)
* Fix various error messages (`#2798 <https://github.com/vyperlang/vyper/pull/2798>`_, `#2805 <https://github.com/vyperlang/vyper/pull/2805>`_)


v0.3.2
******

Expand Down
5 changes: 3 additions & 2 deletions tests/cli/vyper_json/test_get_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ def test_contracts_bad_path():


def test_contract_collision():
input_json = {"sources": {"foo.vy": {"content": FOO_CODE}, "/foo.vy": {"content": FOO_CODE}}}
# ./foo.vy and foo.vy will resolve to the same path
input_json = {"sources": {"./foo.vy": {"content": FOO_CODE}, "foo.vy": {"content": FOO_CODE}}}
with pytest.raises(JSONError):
get_input_dict_contracts(input_json)


def test_contracts_return_value():
input_json = {
"sources": {"/foo.vy": {"content": FOO_CODE}, "contracts/bar.vy": {"content": BAR_CODE}}
"sources": {"foo.vy": {"content": FOO_CODE}, "contracts/bar.vy": {"content": BAR_CODE}}
}
result = get_input_dict_contracts(input_json)
assert result == {"foo.vy": FOO_CODE, "contracts/bar.vy": BAR_CODE}
8 changes: 4 additions & 4 deletions tests/cli/vyper_json/test_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_no_interfaces():


def test_interface_collision():
input_json = {"interfaces": {"/bar.json": {"abi": BAR_ABI}, "bar.vy": {"content": BAR_CODE}}}
input_json = {"interfaces": {"bar.json": {"abi": BAR_ABI}, "bar.vy": {"content": BAR_CODE}}}
with pytest.raises(JSONError):
get_input_dict_interfaces(input_json)

Expand Down Expand Up @@ -71,8 +71,8 @@ def test_vy_no_content():
def test_interfaces_output():
input_json = {
"interfaces": {
"/bar.json": {"abi": BAR_ABI},
"/interface.folder/bar2.vy": {"content": BAR_CODE},
"bar.json": {"abi": BAR_ABI},
"interface.folder/bar2.vy": {"content": BAR_CODE},
}
}
result = get_input_dict_interfaces(input_json)
Expand All @@ -86,7 +86,7 @@ def test_interfaces_output():
def test_manifest_output():
input_json = {
"interfaces": {
"/bar.json": {"contractTypes": {"Bar": {"abi": BAR_ABI}}},
"bar.json": {"contractTypes": {"Bar": {"abi": BAR_ABI}}},
}
}
result = get_input_dict_interfaces(input_json)
Expand Down
2 changes: 1 addition & 1 deletion vyper/builtin_functions/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def check_input_type(expr, arg, out_typ):
# 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("value and target are both {out_typ}", expr)
raise InvalidType(f"value and target are both {out_typ}", expr)

return f(expr, arg, out_typ)

Expand Down
4 changes: 2 additions & 2 deletions vyper/builtin_functions/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,9 @@ def fetch_call_return(self, node):

if start_literal is not None:
if start_literal > arg_type.length:
raise ArgumentException("slice out of bounds for {arg_type}", start_expr)
raise ArgumentException(f"slice out of bounds for {arg_type}", start_expr)
if length_literal is not None and start_literal + length_literal > arg_type.length:
raise ArgumentException("slice out of bounds for {arg_type}", node)
raise ArgumentException(f"slice out of bounds for {arg_type}", node)

# we know the length statically
if length_literal is not None:
Expand Down
33 changes: 28 additions & 5 deletions vyper/cli/vyper_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
import warnings
from pathlib import Path
from typing import Callable, Dict, Tuple, Union
from typing import Any, Callable, Dict, Hashable, List, Tuple, Union

import vyper
from vyper.cli.utils import extract_file_interface_imports, get_interface_file_path
Expand Down Expand Up @@ -136,12 +136,18 @@ def exc_handler_to_dict(file_path: Union[str, None], exception: Exception, compo


def _standardize_path(path_str: str) -> str:
root_path = Path("/__vyper").resolve()
path = root_path.joinpath(path_str.lstrip("/")).resolve()
try:
path = path.relative_to(root_path)
path = Path(path_str)

if path.is_absolute():
path = path.resolve()
else:
pwd = Path(".").resolve()
path = path.resolve().relative_to(pwd)

except ValueError:
raise JSONError(f"{path_str} - path exists outside base folder")

return path.as_posix()


Expand Down Expand Up @@ -435,6 +441,21 @@ def format_to_output_dict(compiler_data: Dict) -> Dict:
return output_dict


# https://stackoverflow.com/a/49518779
def _raise_on_duplicate_keys(ordered_pairs: List[Tuple[Hashable, Any]]) -> Dict:
"""
Raise JSONError if a duplicate key exists in provided ordered list
of pairs, otherwise return a dict.
"""
dict_out = {}
for key, val in ordered_pairs:
if key in dict_out:
raise JSONError(f"Duplicate key: {key}")
else:
dict_out[key] = val
return dict_out


def compile_json(
input_json: Union[Dict, str],
exc_handler: Callable = exc_handler_raises,
Expand All @@ -444,7 +465,9 @@ def compile_json(
try:
if isinstance(input_json, str):
try:
input_dict: Dict = json.loads(input_json)
input_dict: Dict = json.loads(
input_json, object_pairs_hook=_raise_on_duplicate_keys
)
except json.decoder.JSONDecodeError as exc:
new_exc = JSONError(str(exc), exc.lineno, exc.colno)
return exc_handler(json_path, new_exc, "json")
Expand Down
2 changes: 1 addition & 1 deletion vyper/codegen/abi_encoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def abi_encode(dst, ir_node, context, bufsz, returns_len=False):
elif abi_t.is_complex_type():
ir_ret.append("dyn_ofst")
else:
raise CompilerPanic("unknown type {ir_node.typ}")
raise CompilerPanic(f"unknown type {ir_node.typ}")

if abi_t.is_dynamic() and abi_t.is_complex_type():
dyn_section_start = abi_t.static_size()
Expand Down
2 changes: 1 addition & 1 deletion vyper/codegen/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ def _get_element_ptr_mapping(parent, key):

# TODO when is key None?
if key is None or parent.location != STORAGE:
raise TypeCheckFailure("bad dereference on mapping {parent}[{sub}]")
raise TypeCheckFailure(f"bad dereference on mapping {parent}[{key}]")

return IRnode.from_list(["sha3_64", parent, key], typ=subtype, location=STORAGE)

Expand Down
2 changes: 1 addition & 1 deletion vyper/semantics/types/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ def set_reentrancy_key_position(self, position: StorageSlot) -> None:
if hasattr(self, "reentrancy_key_position"):
raise CompilerPanic("Position was already assigned")
if self.nonreentrant is None:
raise CompilerPanic("No reentrant key {self}")
raise CompilerPanic(f"No reentrant key {self}")
# sanity check even though implied by the type
if position._location != DataLocation.STORAGE:
raise CompilerPanic("Non-storage reentrant key")
Expand Down

0 comments on commit 33074bc

Please sign in to comment.