Skip to content

Commit

Permalink
update snapshots
Browse files Browse the repository at this point in the history
  • Loading branch information
sentilesdal committed Nov 16, 2023
1 parent 6699f07 commit 8f1b613
Show file tree
Hide file tree
Showing 20 changed files with 333 additions and 186 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:
run: |
python -m pip install --upgrade .[all]
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: run pytest with coverage
run: |
IN_CI=true coverage run -m pytest
Expand Down
5 changes: 5 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,11 @@ good-names=i,
k,
ex,
Run,
s,
x,
y,
z,
w3, # web3
_

# Good variable names regexes, separated by a comma. If names match any regex,
Expand Down
46 changes: 46 additions & 0 deletions pypechain/foundry/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Types for foundry-rs."""
from typing import Any, Literal, TypedDict

from web3.types import ABI


class FoundryByteCode(TypedDict):
"""Foundry"""

object: str
sourceMap: str
linkReference: Any


class FoundryDeployedByteCode(TypedDict):
"""Foundry"""

object: str
sourceMap: str
linkReference: Any


class FoundryCompiler(TypedDict):
"""Foundry"""

version: str


class FoundryMetadata(TypedDict, total=False):
"""Foundry"""

compiler: FoundryCompiler
language: Literal["Solidity", "Vyper"]


class FoundryJson(TypedDict):
"""Foundry"""

abi: ABI
bytecode: FoundryByteCode
deployedBytecode: FoundryDeployedByteCode
methodIdentifiers: dict[str, str]
rawMetadata: str
metadata: FoundryMetadata
ast: Any
id: int
15 changes: 15 additions & 0 deletions pypechain/foundry/utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""Utilities for working with foundry-rs."""
from typing import TypeGuard

from pypechain.foundry.types import FoundryJson


def is_foundry_json(val: object) -> TypeGuard[FoundryJson]:
"""Determines whether a json object is a FoundryJson."""
required_keys = {"abi", "bytecode", "deployedBytecode", "methodIdentifiers", "rawMetadata", "metadata", "ast", "id"}
return isinstance(val, dict) and required_keys.issubset(val.keys())


def get_bytecode_from_foundry_json(json_abi: FoundryJson) -> str:
"""Gets the bytecode from a foundry json file."""
return json_abi.get("bytecode").get("object")
37 changes: 27 additions & 10 deletions pypechain/render/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

from pathlib import Path
from typing import TypedDict
from typing import Any, NamedTuple, TypedDict

from web3.types import ABI

Expand Down Expand Up @@ -51,40 +51,38 @@ def render_contract_file(contract_name: str, abi_file_path: Path) -> str:
A serialized python file.
"""
env = get_jinja_env()
base_template = env.get_template("contract.py/base.py.jinja2")
functions_template = env.get_template("contract.py/functions.py.jinja2")
abi_template = env.get_template("contract.py/abi.py.jinja2")
contract_template = env.get_template("contract.py/contract.py.jinja2")
templates = get_templates_for_contract_file(env)

# TODO: add return types to function calls

abi, bytecode = load_abi_from_file(abi_file_path)
function_datas, constructor_data = get_function_datas(abi)
has_overloading = any(len(function_data["signature_datas"]) > 1 for function_data in function_datas.values())
has_bytecode = (True if bytecode else False,)
has_bytecode = bool(bytecode)

functions_block = functions_template.render(
functions_block = templates.functions_template.render(
abi=abi,
has_overloading=has_overloading,
contract_name=contract_name,
functions=function_datas,
# TODO: use this data to add a typed constructor
constructor=constructor_data,
)

abi_block = abi_template.render(
abi_block = templates.abi_template.render(
abi=abi,
bytecode=bytecode,
contract_name=contract_name,
)

contract_block = contract_template.render(
contract_block = templates.contract_template.render(
has_bytecode=has_bytecode,
contract_name=contract_name,
functions=function_datas,
)

# Render the template
return base_template.render(
return templates.base_template.render(
contract_name=contract_name,
has_overloading=has_overloading,
has_bytecode=has_bytecode,
Expand All @@ -96,6 +94,25 @@ def render_contract_file(contract_name: str, abi_file_path: Path) -> str:
)


class ContractTemplates(NamedTuple):
"""Templates for the generated contract file."""

base_template: Any
functions_template: Any
abi_template: Any
contract_template: Any


def get_templates_for_contract_file(env):
"""Templates for the generated contract file."""
return ContractTemplates(
base_template=env.get_template("contract.py/base.py.jinja2"),
functions_template=env.get_template("contract.py/functions.py.jinja2"),
abi_template=env.get_template("contract.py/abi.py.jinja2"),
contract_template=env.get_template("contract.py/contract.py.jinja2"),
)


def get_function_datas(abi: ABI) -> tuple[dict[str, FunctionData], SignatureData | None]:
"""_summary_
Expand Down
2 changes: 1 addition & 1 deletion pypechain/render/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def render_types_file(contract_name: str, abi_file_path: Path) -> str:
env = get_jinja_env()
types_template = env.get_template("types.py.jinja2")

abi = load_abi_from_file(abi_file_path)
abi, _ = load_abi_from_file(abi_file_path)

structs_by_name = get_structs_for_abi(abi)
structs_list = list(structs_by_name.values())
Expand Down
20 changes: 20 additions & 0 deletions pypechain/solc/types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Types for solc."""

from typing import TypedDict

from web3.types import ABI


class SolcContract(TypedDict):
"""Foundry"""

abi: ABI
bin: str
metadata: str


class SolcJson(TypedDict):
"""Foundry"""

contracts: dict[str, SolcContract]
version: str
26 changes: 26 additions & 0 deletions pypechain/solc/utilities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Utilities for working with solc."""
from typing import TypeGuard

from pypechain.solc.types import SolcJson


def is_solc_json(val: object) -> TypeGuard[SolcJson]:
"""Determines whether a json object is a SolcJson."""
return (
isinstance(val, dict)
and "contracts" in val
and isinstance(val["contracts"], dict)
and all(
isinstance(contract, dict) and "abi" in contract and "bin" in contract and "metadata" in contract
for contract in val["contracts"].values()
)
and "version" in val
)


def get_bytecode_from_solc_json(json_abi: SolcJson) -> str:
"""Gets the bytecode from a foundry json file."""
# assume one contract right now
contract = list(json_abi.get("contracts").values())[0]
binary = contract.get("bin")
return f"0x{binary}"
2 changes: 1 addition & 1 deletion pypechain/templates/contract.py/abi.py.jinja2
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{contract_name | lower}}_abi: ABI = cast(ABI, {{abi}})
{% if bytecode %}
{% if bytecode %}# pylint: disable=line-too-long
{{contract_name | lower}}_bytecode = HexStr("{{bytecode}}")
{%- endif -%}
4 changes: 2 additions & 2 deletions pypechain/templates/contract.py/functions.py.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ class {{contract_name}}{{function_data.capitalized_name}}ContractFunction(Contra
# pylint: disable=function-redefined
{%- endif -%}
{% for signature_data in function_data.signature_datas %}
{% if function_data.signature_datas|length > 1%} @multimethod{% endif %}
def __call__(self{% if signature_data.input_names_and_types %}, {{signature_data.input_names_and_types|join(', ')}}{% endif %}) -> "{{contract_name}}{{function_data.capitalized_name}}ContractFunction":
{% if has_overloading %} @multimethod{% endif %}
def __call__(self{% if signature_data.input_names_and_types %}, {{signature_data.input_names_and_types|join(', ')}}{% endif %}) -> "{{contract_name}}{{function_data.capitalized_name}}ContractFunction":{%- if has_overloading %} #type: ignore{% endif %}
super().__call__({{signature_data.input_names|join(', ')}})
return self
{% endfor %}
Expand Down
47 changes: 2 additions & 45 deletions pypechain/test/overloading/abis/OverloadedMethods.json
Original file line number Diff line number Diff line change
@@ -1,45 +1,2 @@
{
"contracts": {
"pypechain/test/overloading/contracts/OverloadedMethods.sol:OverloadedMethods": {
"abi": [
{
"inputs": [
{ "internalType": "string", "name": "s", "type": "string" }
],
"name": "doSomething",
"outputs": [
{ "internalType": "string", "name": "", "type": "string" }
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "x", "type": "uint256" }
],
"name": "doSomething",
"outputs": [
{ "internalType": "uint256", "name": "", "type": "uint256" }
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "x", "type": "uint256" },
{ "internalType": "uint256", "name": "y", "type": "uint256" }
],
"name": "doSomething",
"outputs": [
{ "internalType": "uint256", "name": "added", "type": "uint256" }
],
"stateMutability": "pure",
"type": "function"
}
],
"bin": "608060405234801561000f575f80fd5b506104d08061001d5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c80638ae3048e14610043578063a6b206bf14610073578063b2dd1d79146100a3575b5f80fd5b61005d60048036038101906100589190610254565b6100d3565b60405161006a9190610315565b60405180910390f35b61008d60048036038101906100889190610368565b6100dd565b60405161009a91906103a2565b60405180910390f35b6100bd60048036038101906100b891906103bb565b6100f2565b6040516100ca91906103a2565b60405180910390f35b6060819050919050565b5f6002826100eb9190610426565b9050919050565b5f81836100ff9190610467565b905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61016682610120565b810181811067ffffffffffffffff8211171561018557610184610130565b5b80604052505050565b5f610197610107565b90506101a3828261015d565b919050565b5f67ffffffffffffffff8211156101c2576101c1610130565b5b6101cb82610120565b9050602081019050919050565b828183375f83830152505050565b5f6101f86101f3846101a8565b61018e565b9050828152602081018484840111156102145761021361011c565b5b61021f8482856101d8565b509392505050565b5f82601f83011261023b5761023a610118565b5b813561024b8482602086016101e6565b91505092915050565b5f6020828403121561026957610268610110565b5b5f82013567ffffffffffffffff81111561028657610285610114565b5b61029284828501610227565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156102d25780820151818401526020810190506102b7565b5f8484015250505050565b5f6102e78261029b565b6102f181856102a5565b93506103018185602086016102b5565b61030a81610120565b840191505092915050565b5f6020820190508181035f83015261032d81846102dd565b905092915050565b5f819050919050565b61034781610335565b8114610351575f80fd5b50565b5f813590506103628161033e565b92915050565b5f6020828403121561037d5761037c610110565b5b5f61038a84828501610354565b91505092915050565b61039c81610335565b82525050565b5f6020820190506103b55f830184610393565b92915050565b5f80604083850312156103d1576103d0610110565b5b5f6103de85828601610354565b92505060206103ef85828601610354565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61043082610335565b915061043b83610335565b925082820261044981610335565b915082820484148315176104605761045f6103f9565b5b5092915050565b5f61047182610335565b915061047c83610335565b9250828201905080821115610494576104936103f9565b5b9291505056fea264697066735822122030deddf27c7d4db295788e5d996b4428f4e2eb5cf7d4e84a067e6776ac7b8ee464736f6c63430008170033",
"metadata": "{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"name\":\"doSomething\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"doSomething\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"name\":\"doSomething\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"added\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"pypechain/test/overloading/contracts/OverloadedMethods.sol\":\"OverloadedMethods\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"pypechain/test/overloading/contracts/OverloadedMethods.sol\":{\"keccak256\":\"0x189b9cc9e57b72a172e36cf533ece6b6fdd88f8c7f329c5690ee45fe381bec6c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fb8762ce2440e288fd86e0d8037909b4fe979f30a88f50194f7f193b3a4bb2e\",\"dweb:/ipfs/QmZCayU5PBxvKE9oF7XDQKxUaPK784RougENHkfxeTHjh9\"]}},\"version\":1}"
}
},
"version": "0.8.23+commit.f704f362.Darwin.appleclang"
}
{"contracts":{"contracts/OverloadedMethods.sol:OverloadedMethods":{"abi":[{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"doSomething","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"doSomething","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"},{"internalType":"uint256","name":"y","type":"uint256"}],"name":"doSomething","outputs":[{"internalType":"uint256","name":"added","type":"uint256"}],"stateMutability":"pure","type":"function"}],"bin":"608060405234801561000f575f80fd5b506104d08061001d5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c80638ae3048e14610043578063a6b206bf14610073578063b2dd1d79146100a3575b5f80fd5b61005d60048036038101906100589190610254565b6100d3565b60405161006a9190610315565b60405180910390f35b61008d60048036038101906100889190610368565b6100dd565b60405161009a91906103a2565b60405180910390f35b6100bd60048036038101906100b891906103bb565b6100f2565b6040516100ca91906103a2565b60405180910390f35b6060819050919050565b5f6002826100eb9190610426565b9050919050565b5f81836100ff9190610467565b905092915050565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b61016682610120565b810181811067ffffffffffffffff8211171561018557610184610130565b5b80604052505050565b5f610197610107565b90506101a3828261015d565b919050565b5f67ffffffffffffffff8211156101c2576101c1610130565b5b6101cb82610120565b9050602081019050919050565b828183375f83830152505050565b5f6101f86101f3846101a8565b61018e565b9050828152602081018484840111156102145761021361011c565b5b61021f8482856101d8565b509392505050565b5f82601f83011261023b5761023a610118565b5b813561024b8482602086016101e6565b91505092915050565b5f6020828403121561026957610268610110565b5b5f82013567ffffffffffffffff81111561028657610285610114565b5b61029284828501610227565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156102d25780820151818401526020810190506102b7565b5f8484015250505050565b5f6102e78261029b565b6102f181856102a5565b93506103018185602086016102b5565b61030a81610120565b840191505092915050565b5f6020820190508181035f83015261032d81846102dd565b905092915050565b5f819050919050565b61034781610335565b8114610351575f80fd5b50565b5f813590506103628161033e565b92915050565b5f6020828403121561037d5761037c610110565b5b5f61038a84828501610354565b91505092915050565b61039c81610335565b82525050565b5f6020820190506103b55f830184610393565b92915050565b5f80604083850312156103d1576103d0610110565b5b5f6103de85828601610354565b92505060206103ef85828601610354565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61043082610335565b915061043b83610335565b925082820261044981610335565b915082820484148315176104605761045f6103f9565b5b5092915050565b5f61047182610335565b915061047c83610335565b9250828201905080821115610494576104936103f9565b5b9291505056fea2646970667358221220302a4cdc1dfb754065d06f51532b94876e677fac92e5bc7cf8488748219e851564736f6c63430008170033","metadata":"{\"compiler\":{\"version\":\"0.8.23+commit.f704f362\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"name\":\"doSomething\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"}],\"name\":\"doSomething\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"name\":\"doSomething\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"added\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/OverloadedMethods.sol\":\"OverloadedMethods\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"contracts/OverloadedMethods.sol\":{\"keccak256\":\"0x189b9cc9e57b72a172e36cf533ece6b6fdd88f8c7f329c5690ee45fe381bec6c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://1fb8762ce2440e288fd86e0d8037909b4fe979f30a88f50194f7f193b3a4bb2e\",\"dweb:/ipfs/QmZCayU5PBxvKE9oF7XDQKxUaPK784RougENHkfxeTHjh9\"]}},\"version\":1}"}},"version":"0.8.23+commit.f704f362.Darwin.appleclang"}

4 changes: 1 addition & 3 deletions pypechain/test/overloading/test_overloading.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
"""Tests for overloading methods."""
from __future__ import annotations

import errno
import os

import pytest
import web3
from web3.exceptions import Web3ValidationError

from pypechain.test.overloading.pypechain_types.OverloadedMethodsContract import OverloadedMethodsContract
from pypechain.test.overloading.types.OverloadedMethodsContract import OverloadedMethodsContract

# using pytest fixtures necessitates this.
# pylint: disable=redefined-outer-name
Expand Down
Loading

0 comments on commit 8f1b613

Please sign in to comment.