Skip to content

Commit

Permalink
feat: vyper 0.4 support (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
antazoey authored Jun 12, 2024
1 parent ee1e4d2 commit 7096c4e
Show file tree
Hide file tree
Showing 9 changed files with 374 additions and 129 deletions.
4 changes: 2 additions & 2 deletions ape_vyper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ape import plugins

from .compiler import VyperCompiler, VyperConfig
from .compiler import FileType, VyperCompiler, VyperConfig


@plugins.register(plugins.Config)
Expand All @@ -10,4 +10,4 @@ def config_class():

@plugins.register(plugins.CompilerPlugin)
def register_compiler():
return (".vy",), VyperCompiler
return tuple(e.value for e in FileType), VyperCompiler
406 changes: 295 additions & 111 deletions ape_vyper/compiler.py

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion ape_vyper/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@ def __init__(self, err: Union[VyperError, str]):
message = "\n\n".join(
f"{e['sourceLocation']['file']}\n{e['type']}:"
f"{e.get('formattedMessage', e['message'])}"
for e in err.error_dict
for e in (err.error_dict or {})
)
# Try to find any indication of error.
message = message or getattr(err, "message", "")

# If is only the default, check stderr.
if message == "An error occurred during execution" and getattr(err, "stderr_data", ""):
message = err.stderr_data

else:
self.base_err = None
message = str(err)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
url="https://github.com/ApeWorX/ape-vyper",
include_package_data=True,
install_requires=[
"eth-ape>=0.8.2,<0.9",
"eth-ape>=0.8.3,<0.9",
"ethpm-types", # Use same version as eth-ape
"tqdm", # Use same version as eth-ape
"vvm>=0.2.0,<0.3",
Expand Down
8 changes: 7 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import ape
import pytest
import vvm # type: ignore
from ape.contracts import ContractContainer
from click.testing import CliRunner

BASE_CONTRACTS_PATH = Path(__file__).parent / "contracts"
Expand All @@ -28,6 +29,7 @@
"0.3.7",
"0.3.9",
"0.3.10",
"0.4.0rc6",
)

CONTRACT_VERSION_GEN_MAP = {
Expand All @@ -36,7 +38,7 @@
"0.3.9",
"0.3.10",
),
"sub_reverts": ALL_VERSIONS,
"sub_reverts": [v for v in ALL_VERSIONS if "0.4.0" not in v],
}


Expand Down Expand Up @@ -215,7 +217,11 @@ def cli_runner():


def _get_tb_contract(version: str, project, account):
project.load_contracts()

registry_type = project.get_contract(f"registry_{version}")
assert isinstance(registry_type, ContractContainer), "Setup failed - couldn't get container"
registry = account.deploy(registry_type)
contract = project.get_contract(f"traceback_contract_{version}")
assert isinstance(contract, ContractContainer), "Setup failed - couldn't get container"
return account.deploy(contract, registry)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# pragma version ~=0.4.0rc6

@external
@view
def implementThisPlease(role: bytes32) -> bool:
...
16 changes: 16 additions & 0 deletions tests/contracts/passing_contracts/zero_four.vy
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# pragma version ~=0.4.0rc6

import interfaces.IFaceZeroFour as IFaceZeroFour
implements: IFaceZeroFour

from . import zero_four_module as zero_four_module

@external
@view
def implementThisPlease(role: bytes32) -> bool:
return True


@external
def callModuleFunction(role: bytes32) -> bool:
return zero_four_module.moduleMethod()
5 changes: 5 additions & 0 deletions tests/contracts/passing_contracts/zero_four_module.vy
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# pragma version ~=0.4.0rc6

@internal
def moduleMethod() -> bool:
return True
47 changes: 34 additions & 13 deletions tests/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pytest
import vvm # type: ignore
from ape.exceptions import CompilerError, ContractLogicError
from ape.utils import get_full_extension
from ethpm_types import ContractType
from packaging.version import Version
from vvm.exceptions import VyperError # type: ignore
Expand All @@ -25,6 +26,7 @@
OLDER_VERSION_FROM_PRAGMA = Version("0.2.16")
VERSION_37 = Version("0.3.7")
VERSION_FROM_PRAGMA = Version("0.3.10")
VERSION_04 = Version("0.4.0rc6")


@pytest.fixture
Expand All @@ -46,14 +48,26 @@ def dev_revert_source(project):


def test_compile_project(project):
contracts = project.load_contracts()
assert len(contracts) == len(
[p.name for p in project.contracts_folder.glob("*.vy") if p.is_file()]
actual = sorted(list(project.load_contracts().keys()))

# NOTE: Ignore interfaces for this test.
expected = sorted(
[
p.stem
for p in project.contracts_folder.rglob("*.vy")
if p.is_file() and not p.name.startswith("I")
]
)
prefix = "contracts/passing_contracts"
assert contracts["contract_039"].source_id == f"{prefix}/contract_039.vy"
assert contracts["contract_no_pragma"].source_id == f"{prefix}/contract_no_pragma.vy"
assert contracts["older_version"].source_id == f"{prefix}/older_version.vy"
if missing := [e for e in expected if e not in actual]:
missing_str = ", ".join(missing)
pytest.xfail(f"Missing the following expected sources: {missing_str}")
if extra := [a for a in actual if a not in expected]:
extra_str = ", ".join(extra)
pytest.xfail(f"Received the following extra sources: {extra_str}")

assert "contract_039" in actual
assert "contract_no_pragma" in actual
assert "older_version" in actual


@pytest.mark.parametrize("contract_name", PASSING_CONTRACT_NAMES)
Expand Down Expand Up @@ -83,7 +97,9 @@ def test_install_failure(compiler):

def test_get_version_map(project, compiler, all_versions):
vyper_files = [
x for x in project.contracts_folder.iterdir() if x.is_file() and x.suffix == ".vy"
x
for x in project.contracts_folder.iterdir()
if x.is_file() and get_full_extension(x) == ".vy"
]
actual = compiler.get_version_map(vyper_files, project=project)
expected_versions = [Version(v) for v in all_versions]
Expand Down Expand Up @@ -137,18 +153,23 @@ def test_get_version_map(project, compiler, all_versions):

assert not failures, "\n".join(failures)

# Vyper 0.4.0 assertions.
actual4 = {x.name for x in actual[VERSION_04]}
expected4 = {"zero_four_module.vy", "zero_four.vy"}
assert actual4 == expected4


def test_compiler_data_in_manifest(project):
def run_test(manifest):
assert len(manifest.compilers) >= 3, manifest.compilers

all_latest = [c for c in manifest.compilers if str(c.version) == str(VERSION_FROM_PRAGMA)]
codesize_latest = [c for c in all_latest if c.settings["optimize"] == "codesize"][0]
evm_latest = [c for c in all_latest if c.settings["evmVersion"] == "paris"][0]
evm_latest = [c for c in all_latest if c.settings.get("evmVersion") == "paris"][0]
true_latest = [
c
for c in all_latest
if c.settings["optimize"] is True and c.settings["evmVersion"] != "paris"
if c.settings["optimize"] is True and c.settings.get("evmVersion") != "paris"
][0]
vyper_028 = [
c for c in manifest.compilers if str(c.version) == str(OLDER_VERSION_FROM_PRAGMA)
Expand All @@ -167,7 +188,7 @@ def run_test(manifest):

# There is only one contract with evm-version pragma.
assert evm_latest.contractTypes == ["evm_pragma"]
assert evm_latest.settings["evmVersion"] == "paris"
assert evm_latest.settings.get("evmVersion") == "paris"

assert len(true_latest.contractTypes) >= 9
assert len(vyper_028.contractTypes) >= 1
Expand Down Expand Up @@ -212,8 +233,8 @@ def test_get_imports(compiler, project):
actual = compiler.get_imports(vyper_files, project=project)
prefix = "contracts/passing_contracts"
builtin_import = "vyper/interfaces/ERC20.json"
local_import = "interfaces/IFace.vy"
local_from_import = "interfaces/IFace2.vy"
local_import = f"{prefix}/interfaces/IFace.vy"
local_from_import = f"{prefix}/interfaces/IFace2.vy"
dep_key = project.dependencies.get_dependency("exampledependency", "local").package_id.replace(
"/", "_"
)
Expand Down

0 comments on commit 7096c4e

Please sign in to comment.