From 0e3dddf2fdac8366d71d3e40737ae75114ff60a9 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:42:36 +0000 Subject: [PATCH 01/14] fix: compatability issue with vvm 0.2.0 --- brownie/project/compiler/utils.py | 4 ++++ brownie/project/compiler/vyper.py | 20 +++++++++++++++++--- requirements.in | 4 ++-- requirements.txt | 13 +++++++++---- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 7c0627094..70e89f5c3 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,6 +8,10 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists + + if not isinstance(source_map_str, str): + raise TypeError(source_map_str) from None + source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): if value is None: diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 1dafedfe2..9e2f3b59c 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -7,6 +7,7 @@ import vvm import vyper +from packaging.version import Version as PVersion from requests.exceptions import ConnectionError from semantic_version import Version from vyper.cli import vyper_json @@ -46,6 +47,8 @@ def set_vyper_version(version: Union[str, Version]) -> str: if isinstance(version, str): version = Version(version) if version != Version(vyper.__version__): + # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + version = str(version) try: vvm.set_vyper_version(version, silent=True) except vvm.exceptions.VyperNotInstalled: @@ -82,13 +85,13 @@ def get_abi(contract_source: str, name: str) -> Dict: def _get_vyper_version_list() -> Tuple[List, List]: global AVAILABLE_VYPER_VERSIONS - installed_versions = vvm.get_installed_vyper_versions() + installed_versions = _convert_to_semver(vvm.get_installed_vyper_versions()) lib_version = Version(vyper.__version__) if lib_version not in installed_versions: installed_versions.append(lib_version) if AVAILABLE_VYPER_VERSIONS is None: try: - AVAILABLE_VYPER_VERSIONS = vvm.get_installable_vyper_versions() + AVAILABLE_VYPER_VERSIONS = _convert_to_semver(vvm.get_installable_vyper_versions()) except ConnectionError: if not installed_versions: raise ConnectionError("Vyper not installed and cannot connect to GitHub") @@ -237,11 +240,13 @@ def compile_from_input_json( outputs.remove("devdoc") if version == Version(vyper.__version__): try: - return vyper_json.compile_json(input_json, root_path=allow_paths) + return vyper_json.compile_json(input_json) except VyperException as exc: raise exc.with_traceback(None) else: try: + # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + version = str(version) return vvm.compile_standard(input_json, base_path=allow_paths, vyper_version=version) except vvm.exceptions.VyperError as exc: raise CompilerError(exc, "vyper") @@ -449,3 +454,12 @@ def _get_statement_nodes(ast_json: List) -> List: else: stmt_nodes.append(node) return stmt_nodes + + +def _convert_to_semver(versions: List[PVersion]) -> List[Version]: + """ + Converts a list of packaging.version.Version objects to a list of semantic_version.Version objects. + vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. + This function serves as a stopgap. + """ + return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre)) for version in versions] \ No newline at end of file diff --git a/requirements.in b/requirements.in index 56d07b964..405ae2cd6 100644 --- a/requirements.in +++ b/requirements.in @@ -23,7 +23,7 @@ requests>=2.25.0,<3 rlp semantic-version<3 tqdm<5 -vvm==0.1.0 # 0.2.0 switches from semantic-version to packaging.version and things break -vyper>=0.3.8,<0.4 +vvm==0.2.1 +vyper>=0.4.0,<0.5 web3>=6,<7 wrapt>=1.12.1,<2 diff --git a/requirements.txt b/requirements.txt index 9758d4e63..410e36a15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.11 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements.in @@ -10,6 +10,8 @@ aiosignal==1.3.1 # via aiohttp asttokens==2.4.1 # via vyper +async-timeout==4.0.3 + # via aiohttp attrs==23.2.0 # via # aiohttp @@ -125,6 +127,7 @@ packaging==23.2 # via # black # pytest + # vvm # vyper parsimonious==0.9.0 # via eth-abi @@ -200,7 +203,6 @@ semantic-version==2.10.0 # via # -r requirements.in # py-solc-x - # vvm six==1.16.0 # via # asttokens @@ -209,20 +211,23 @@ sortedcontainers==2.4.0 # via hypothesis toml==0.10.2 # via pytest +tomli==2.0.1 + # via black toolz==0.12.1 # via cytoolz tqdm==4.66.2 # via -r requirements.in typing-extensions==4.9.0 # via + # black # eth-rlp # eth-typing # web3 urllib3==2.2.1 # via requests -vvm==0.1.0 +vvm==0.2.1 # via -r requirements.in -vyper==0.3.10 +vyper==0.4.0 # via -r requirements.in wcwidth==0.2.13 # via prompt-toolkit From 9e2d8b48d6b5792618f5e8074300687f6372b79d Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:46:46 +0000 Subject: [PATCH 02/14] fix: None not iterable --- brownie/project/compiler/vyper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 9e2f3b59c..3163290b4 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -462,4 +462,4 @@ def _convert_to_semver(versions: List[PVersion]) -> List[Version]: vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. This function serves as a stopgap. """ - return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre)) for version in versions] \ No newline at end of file + return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre) if version.pre else None) for version in versions] \ No newline at end of file From c6eed94ebb3c8acfadda0902a6d74da55c90d35c Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:50:16 +0000 Subject: [PATCH 03/14] fix: TypeError --- brownie/project/compiler/vyper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 3163290b4..a30f89b5e 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -48,12 +48,12 @@ def set_vyper_version(version: Union[str, Version]) -> str: version = Version(version) if version != Version(vyper.__version__): # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string - version = str(version) + version_str = str(version) try: - vvm.set_vyper_version(version, silent=True) + vvm.set_vyper_version(version_str, silent=True) except vvm.exceptions.VyperNotInstalled: install_vyper(version) - vvm.set_vyper_version(version, silent=True) + vvm.set_vyper_version(version_str, silent=True) _active_version = version return str(_active_version) From 7f58e2fcd754a65e89a003e04cad9a0558bddef0 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 00:55:51 +0000 Subject: [PATCH 04/14] fix: debug source_map_str not being string --- brownie/project/compiler/vyper.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index a30f89b5e..af6f6a681 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -262,8 +262,12 @@ def _get_unique_build_json( else: ast = ast_json + source_map = output_evm["deployedBytecode"]["sourceMap"] + if not isinstance(source_map, str): + raise TypeError(source_map) + pc_map, statement_map, branch_map = _generate_coverage_data( - output_evm["deployedBytecode"]["sourceMap"], + source_map, output_evm["deployedBytecode"]["opcodes"], contract_name, ast, From d28b3b09d30c6a86e9d3688365f9ceebbbfc9e01 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:03:56 +0000 Subject: [PATCH 05/14] chore: add exc detail --- brownie/project/compiler/vyper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index af6f6a681..6179e8ecc 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -264,7 +264,7 @@ def _get_unique_build_json( source_map = output_evm["deployedBytecode"]["sourceMap"] if not isinstance(source_map, str): - raise TypeError(source_map) + raise TypeError(source_map.keys(), source_map) pc_map, statement_map, branch_map = _generate_coverage_data( source_map, From 3ad567b2aa91bb5571d6971465b54cef5815b7c8 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:09:41 +0000 Subject: [PATCH 06/14] chore: add exc detail --- brownie/project/compiler/utils.py | 2 ++ brownie/project/compiler/vyper.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 70e89f5c3..21be6ecba 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -10,6 +10,8 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists if not isinstance(source_map_str, str): + # NOTE: why do we need this? + source_map_str = source_map_str["ps_pos_map_compressed"] raise TypeError(source_map_str) from None source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 6179e8ecc..3a94012cb 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -263,8 +263,8 @@ def _get_unique_build_json( ast = ast_json source_map = output_evm["deployedBytecode"]["sourceMap"] - if not isinstance(source_map, str): - raise TypeError(source_map.keys(), source_map) + #if not isinstance(source_map, str): + # raise TypeError(source_map.keys(), source_map) pc_map, statement_map, branch_map = _generate_coverage_data( source_map, From 70423777121004c6894f13ca9133c384f24e40d5 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:10:54 +0000 Subject: [PATCH 07/14] fix: typo --- brownie/project/compiler/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 21be6ecba..82b2ee44e 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -11,7 +11,7 @@ def expand_source_map(source_map_str: str) -> List: if not isinstance(source_map_str, str): # NOTE: why do we need this? - source_map_str = source_map_str["ps_pos_map_compressed"] + source_map_str = source_map_str["pc_pos_map_compressed"] raise TypeError(source_map_str) from None source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] From 804a2f383b1b40277e99f53252daaf715b46d7de Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:12:02 +0000 Subject: [PATCH 08/14] fix: typo --- brownie/project/compiler/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 82b2ee44e..5673f2bb8 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -12,7 +12,7 @@ def expand_source_map(source_map_str: str) -> List: if not isinstance(source_map_str, str): # NOTE: why do we need this? source_map_str = source_map_str["pc_pos_map_compressed"] - raise TypeError(source_map_str) from None + #raise TypeError(source_map_str) from None source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): From 8b09824df47c6b03c46d0d59e503c8e6d8934980 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 01:14:33 +0000 Subject: [PATCH 09/14] fix: KeyError --- brownie/project/compiler/vyper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 3a94012cb..794b1afc0 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -406,7 +406,7 @@ def _generate_coverage_data( if node["ast_type"] in ("Assert", "If") or ( node["ast_type"] == "Expr" - and node["value"]["func"].get("id", None) == "assert_modifiable" + and node["value"].get("func", {}).get("id", None) == "assert_modifiable" ): # branch coverage pc_list[-1]["branch"] = count From 35c2741e63dbab6e66d2e5c60906598088b8544d Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 16:29:12 +0000 Subject: [PATCH 10/14] chore: black --- brownie/project/compiler/utils.py | 5 ++--- brownie/project/compiler/vyper.py | 16 ++++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 5673f2bb8..784071239 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,12 +8,11 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists - + if not isinstance(source_map_str, str): # NOTE: why do we need this? source_map_str = source_map_str["pc_pos_map_compressed"] - #raise TypeError(source_map_str) from None - + source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): if value is None: diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 794b1afc0..4d0cccd9a 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -262,12 +262,8 @@ def _get_unique_build_json( else: ast = ast_json - source_map = output_evm["deployedBytecode"]["sourceMap"] - #if not isinstance(source_map, str): - # raise TypeError(source_map.keys(), source_map) - pc_map, statement_map, branch_map = _generate_coverage_data( - source_map, + output_evm["deployedBytecode"]["sourceMap"], output_evm["deployedBytecode"]["opcodes"], contract_name, ast, @@ -466,4 +462,12 @@ def _convert_to_semver(versions: List[PVersion]) -> List[Version]: vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. This function serves as a stopgap. """ - return [Version(major=version.major, minor=version.minor, patch=version.micro, prerelease=''.join(str(x) for x in version.pre) if version.pre else None) for version in versions] \ No newline at end of file + return [ + Version( + major=version.major, + minor=version.minor, + patch=version.micro, + prerelease="".join(str(x) for x in version.pre) if version.pre else None, + ) + for version in versions + ] From 674dc8f7cdb746bba627466d6ff4f286b493db8e Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 16:33:37 +0000 Subject: [PATCH 11/14] chore: flake8 --- brownie/project/compiler/vyper.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 4d0cccd9a..61af3eaa6 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -47,7 +47,8 @@ def set_vyper_version(version: Union[str, Version]) -> str: if isinstance(version, str): version = Version(version) if version != Version(vyper.__version__): - # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # `semantic_version.Version` so we first must cast it as a string version_str = str(version) try: vvm.set_vyper_version(version_str, silent=True) @@ -245,7 +246,8 @@ def compile_from_input_json( raise exc.with_traceback(None) else: try: - # NOTE: vvm uses packaging.version.Version which is not compatible with semantic_version.Version so we first must cast it as a string + # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # `semantic_version.Version` so we first must cast it as a string version = str(version) return vvm.compile_standard(input_json, base_path=allow_paths, vyper_version=version) except vvm.exceptions.VyperError as exc: @@ -458,8 +460,12 @@ def _get_statement_nodes(ast_json: List) -> List: def _convert_to_semver(versions: List[PVersion]) -> List[Version]: """ - Converts a list of packaging.version.Version objects to a list of semantic_version.Version objects. - vvm 0.2.0 switched to packaging.version but we are not ready to migrate brownie off of semantic-version. + Converts a list of `packaging.version.Version` objects to a list of + `semantic_version.Version` objects. + + vvm 0.2.0 switched to packaging.version but we are not ready to + migrate brownie off of semantic-version. + This function serves as a stopgap. """ return [ From e05e53fada8e5cb9a209478eda23ab632b7f6562 Mon Sep 17 00:00:00 2001 From: BobTheBuidler Date: Sat, 17 Aug 2024 16:35:42 +0000 Subject: [PATCH 12/14] chore: black --- brownie/project/compiler/vyper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/brownie/project/compiler/vyper.py b/brownie/project/compiler/vyper.py index 61af3eaa6..acd754904 100644 --- a/brownie/project/compiler/vyper.py +++ b/brownie/project/compiler/vyper.py @@ -47,7 +47,7 @@ def set_vyper_version(version: Union[str, Version]) -> str: if isinstance(version, str): version = Version(version) if version != Version(vyper.__version__): - # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # NOTE: vvm uses `packaging.version.Version` which is not compatible with # `semantic_version.Version` so we first must cast it as a string version_str = str(version) try: @@ -246,7 +246,7 @@ def compile_from_input_json( raise exc.with_traceback(None) else: try: - # NOTE: vvm uses `packaging.version.Version` which is not compatible with + # NOTE: vvm uses `packaging.version.Version` which is not compatible with # `semantic_version.Version` so we first must cast it as a string version = str(version) return vvm.compile_standard(input_json, base_path=allow_paths, vyper_version=version) From dc665d1b23eb352578858401f01b6f5cfea7de8c Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sat, 17 Aug 2024 21:53:43 -0400 Subject: [PATCH 13/14] chore: better comment --- brownie/project/compiler/utils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 784071239..8694d9cd7 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,10 +8,12 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists - - if not isinstance(source_map_str, str): - # NOTE: why do we need this? +' + if isinstance(source_map_str, dict): + # NOTE: vyper >= 0.4 gives us a dict that contains the source map source_map_str = source_map_str["pc_pos_map_compressed"] + if not isinstance(source_map_str, str): + raise TypeError(source_map_str) source_map: List = [_expand_row(i) if i else None for i in source_map_str.split(";")] for i, value in enumerate(source_map[1:], 1): From 326cce6b0fbd8d20cffd2d03e082e855aa923a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stas=20SU=C8=98COV?= Date: Wed, 23 Oct 2024 18:47:25 +0100 Subject: [PATCH 14/14] typo --- brownie/project/compiler/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownie/project/compiler/utils.py b/brownie/project/compiler/utils.py index 8694d9cd7..98c947252 100644 --- a/brownie/project/compiler/utils.py +++ b/brownie/project/compiler/utils.py @@ -8,7 +8,7 @@ def expand_source_map(source_map_str: str) -> List: # Expands the compressed sourceMap supplied by solc into a list of lists -' + if isinstance(source_map_str, dict): # NOTE: vyper >= 0.4 gives us a dict that contains the source map source_map_str = source_map_str["pc_pos_map_compressed"]