Skip to content

Commit

Permalink
Merge pull request #733 from eth-brownie/feat-solcx-v1
Browse files Browse the repository at this point in the history
Use solcx v1.0.0
  • Loading branch information
iamdefinitelyahuman authored Aug 27, 2020
2 parents 6deb2dc + 69c73fd commit 5edb85c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 94 deletions.
16 changes: 6 additions & 10 deletions brownie/network/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import json
import os
import re
import sys
import warnings
from pathlib import Path
from textwrap import TextWrapper
Expand Down Expand Up @@ -682,21 +681,18 @@ def from_explorer(
else:
try:
version = Version(compiler_str.lstrip("v")).truncate()
if sys.platform == "darwin":
is_compilable = (
version >= Version("0.5.0")
or f"v{version}" in solcx.get_installed_solc_versions()
)
else:
is_compilable = f"v{version}" in solcx.get_available_solc_versions()
is_compilable = (
version
in solcx.get_installable_solc_versions() + solcx.get_installed_solc_versions()
)
except Exception:
is_compilable = False

if not is_compilable:
if not silent:
warnings.warn(
f"{address}: target compiler '{compiler_str}' is "
"unsupported by Brownie. Some functionality will not be available.",
f"{address}: target compiler '{compiler_str}' cannot be installed or is not "
"supported by Brownie. Some debugging functionality will not be available.",
BrownieCompilerWarning,
)
return cls.from_abi(name, address, abi, owner)
Expand Down
31 changes: 16 additions & 15 deletions brownie/project/compiler/solidity.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
from collections import deque
from hashlib import sha1
from typing import Any, Dict, List, Optional, Set, Tuple
from typing import Any, Dict, List, Optional, Set, Tuple, Union

import solcast
import solcx
Expand Down Expand Up @@ -61,33 +61,34 @@ def compile_from_input_json(
print(f" EVM Version: {input_json['settings']['evmVersion'].capitalize()}")

try:
return solcx.compile_standard(
input_json,
optimize=optimizer["enabled"],
optimize_runs=optimizer["runs"],
evm_version=input_json["settings"]["evmVersion"],
allow_paths=allow_paths,
)
return solcx.compile_standard(input_json, allow_paths=allow_paths,)
except solcx.exceptions.SolcError as e:
raise CompilerError(e, "solc")


def set_solc_version(version: str) -> str:
def set_solc_version(version: Union[str, Version]) -> str:
"""Sets the solc version. If not available it will be installed."""
if Version(version.lstrip("v")) < Version("0.4.22"):
if not isinstance(version, Version):
version = Version(version.lstrip("v"))
if version < Version("0.4.22"):
raise IncompatibleSolcVersion("Brownie only supports Solidity versions >=0.4.22")
try:
solcx.set_solc_version(version, silent=True)
except solcx.exceptions.SolcNotInstalled:
if version not in _get_solc_version_list()[0]:
raise IncompatibleSolcVersion(
f"Cannot install Solidity v{version} on this OS. You may be able to "
f"manually compile from source with `solcx.compile_solc('{version}')`"
)
install_solc(version)
solcx.set_solc_version(version, silent=True)
return str(solcx.get_solc_version())


def install_solc(*versions: str) -> None:
def install_solc(*versions: Union[Version, str]) -> None:
"""Installs solc versions."""
for version in versions:
solcx.install_solc(str(version), show_progress=True)
solcx.install_solc(version, show_progress=True)


def get_abi(contract_source: str, allow_paths: Optional[str] = None) -> Dict:
Expand Down Expand Up @@ -156,7 +157,7 @@ def find_solc_versions(
# install new versions if needed
if to_install:
install_solc(*to_install)
installed_versions = [Version(i[1:]) for i in solcx.get_installed_solc_versions()]
installed_versions = solcx.get_installed_solc_versions()
elif new_versions and not silent:
print(
f"New compatible solc version{'s' if len(new_versions) > 1 else ''}"
Expand Down Expand Up @@ -219,10 +220,10 @@ def find_best_solc_version(

def _get_solc_version_list() -> Tuple[List, List]:
global AVAILABLE_SOLC_VERSIONS
installed_versions = [Version(i[1:]) for i in solcx.get_installed_solc_versions()]
installed_versions = solcx.get_installed_solc_versions()
if AVAILABLE_SOLC_VERSIONS is None:
try:
AVAILABLE_SOLC_VERSIONS = [Version(i[1:]) for i in solcx.get_available_solc_versions()]
AVAILABLE_SOLC_VERSIONS = solcx.get_installable_solc_versions()
except ConnectionError:
if not installed_versions:
raise ConnectionError("Solc not installed and cannot connect to GitHub")
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ prompt-toolkit==3.0.5
psutil>=5.7.0,<6.0.0
py>=1.5.0
py-solc-ast>=1.2.5,<2.0.0
py-solc-x>=0.10.1,<1.0.0
py-solc-x>=1.0.0,<2.0.0
pygments==2.6.1
pygments_lexer_solidity==0.5.1
pytest==5.4.3
Expand Down
39 changes: 21 additions & 18 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from ethpm._utils.ipfs import dummy_ipfs_pin
from ethpm.backends.ipfs import BaseIPFSBackend
from prompt_toolkit.input.defaults import create_pipe_input
from semantic_version import Version

import brownie
from brownie._cli.console import Console
Expand Down Expand Up @@ -71,7 +72,7 @@ def pytest_configure(config):
solc_versions, evm_verions, runs = [i.split(",") for i in config.option.evm]
runs = [int(i) for i in runs]
if "latest" in solc_versions:
latest_version = solcx.get_available_solc_versions()[0]
latest_version = solcx.get_installable_solc_versions()[0]
solc_versions.remove("latest")
solc_versions.append(latest_version)
config.option.evm = (evm_verions, runs, solc_versions)
Expand All @@ -86,22 +87,24 @@ def pytest_generate_tests(metafunc):


# travis cannot call github ethereum/solidity API, so this method is patched
def pytest_sessionstart():
monkeypatch_session = MonkeyPatch()
monkeypatch_session.setattr(
"solcx.get_available_solc_versions",
lambda: [
"v0.6.7",
"v0.6.2",
"v0.5.15",
"v0.5.8",
"v0.5.7",
"v0.5.0",
"v0.4.25",
"v0.4.24",
"v0.4.22",
],
)
def pytest_sessionstart(session):
if not session.config.getoption("--evm"):
monkeypatch_session = MonkeyPatch()
monkeypatch_session.setattr(
"solcx.get_installable_solc_versions",
lambda: [
Version("0.6.7"),
Version("0.6.2"),
Version("0.6.0"),
Version("0.5.15"),
Version("0.5.8"),
Version("0.5.7"),
Version("0.5.0"),
Version("0.4.25"),
Version("0.4.24"),
Version("0.4.22"),
],
)


# worker ID for xdist process, as an integer
Expand Down Expand Up @@ -208,7 +211,7 @@ def evmtester(_project_factory, project, tmp_path, accounts, request):
)
conf_json = {
"evm_version": evm_version,
"compiler": {"solc": {"version": solc_version, "optimize": runs > 0, "runs": runs}},
"compiler": {"solc": {"version": str(solc_version), "optimize": runs > 0, "runs": runs}},
}
with tmp_path.joinpath("brownie-config.yaml").open("w") as fp:
json.dump(conf_json, fp)
Expand Down
12 changes: 0 additions & 12 deletions tests/network/contract/test_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,18 +153,6 @@ def test_from_explorer_pre_422(network):
assert "pcMap" not in contract._build


def test_from_explorer_osx_pre_050(network, monkeypatch):
network.connect("mainnet")
monkeypatch.setattr("sys.platform", "darwin")
installed = ["v0.5.8", "v0.5.7"]
monkeypatch.setattr("solcx.get_installed_solc_versions", lambda: installed)

# chainlink, compiler version 0.4.24
with pytest.warns(BrownieCompilerWarning):
contract = Contract.from_explorer("0xf79d6afbb6da890132f9d7c355e3015f15f3406f")
assert "pcMap" not in contract._build


def test_from_explorer_vyper_supported_020(network):
network.connect("mainnet")

Expand Down
57 changes: 19 additions & 38 deletions tests/project/compiler/test_solidity.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,15 @@ def fn(version, **kwargs):

@pytest.fixture
def msolc(monkeypatch):
installed = ["v0.5.8", "v0.5.7", "v0.4.23", "v0.4.22", "v0.4.6"]
installed = [
Version("0.5.8"),
Version("0.5.7"),
Version("0.4.23"),
Version("0.4.22"),
Version("0.4.6"),
]
monkeypatch.setattr("solcx.get_installed_solc_versions", lambda: installed)
monkeypatch.setattr("solcx.install_solc", lambda k, **z: installed.append("v" + k))
monkeypatch.setattr("solcx.install_solc", lambda k, **z: installed.append(k))
yield installed


Expand Down Expand Up @@ -96,31 +102,6 @@ def test_compile_input_json_evm_translates(solc5source, original, translated):
compiler.compile_from_input_json(input_json)


def test_compile_optimizer(monkeypatch):
def _test_compiler(a, **kwargs):
assert kwargs["optimize"] is True
assert kwargs["optimize_runs"] == 666

monkeypatch.setattr("solcx.compile_standard", _test_compiler)
input_json = {
"language": "Solidity",
"settings": {"optimizer": {"enabled": True, "runs": 666}, "remappings": []},
}
compiler.compile_from_input_json(input_json)
input_json = {
"language": "Solidity",
"settings": {"optimizer": {"enabled": True, "runs": 31337}, "remappings": []},
}
with pytest.raises(AssertionError):
compiler.compile_from_input_json(input_json)
input_json = {
"language": "Solidity",
"settings": {"optimizer": {"enabled": False, "runs": 666}, "remappings": []},
}
with pytest.raises(AssertionError):
compiler.compile_from_input_json(input_json)


def test_build_json_keys(solc5source):
build_json = compiler.compile_and_format({"path.sol": solc5source})
assert set(build.BUILD_KEYS) == set(build_json["Foo"])
Expand Down Expand Up @@ -173,24 +154,24 @@ def test_find_solc_versions(find_version, msolc):


def test_find_solc_versions_install(find_version, msolc):
assert "v0.4.25" not in msolc
assert "v0.5.10" not in msolc
assert Version("0.4.25") not in msolc
assert Version("0.5.10") not in msolc
find_version("^0.4.24", install_needed=True)
assert msolc.pop() == "v0.4.25"
assert msolc.pop() == Version("0.4.25")
find_version("^0.4.22", install_latest=True)
assert msolc.pop() == "v0.4.25"
assert msolc.pop() == Version("0.4.25")
find_version("^0.4.24 || >=0.5.10", install_needed=True)
assert msolc.pop() == "v0.6.7"
assert msolc.pop() == Version("0.6.7")
find_version(">=0.4.24", install_latest=True)
assert msolc.pop() == "v0.6.7"
assert msolc.pop() == Version("0.6.7")


def test_install_solc(msolc):
assert "v0.5.10" not in msolc
assert "v0.6.0" not in msolc
compiler.install_solc("0.6.0", "0.5.10")
assert "v0.5.10" in msolc
assert "v0.6.0" in msolc
assert Version("0.5.10") not in msolc
assert Version("0.6.0") not in msolc
compiler.install_solc(Version("0.6.0"), Version("0.5.10"))
assert Version("0.5.10") in msolc
assert Version("0.6.0") in msolc


def test_first_revert(BrownieTester, ExternalCallTester):
Expand Down

0 comments on commit 5edb85c

Please sign in to comment.