Skip to content

Commit

Permalink
refactor: remove and rationalize each usage of model_dump() with mo…
Browse files Browse the repository at this point in the history
…de="json" (#2019)
  • Loading branch information
antazoey authored Apr 22, 2024
1 parent cc4de0b commit c2f1bc4
Show file tree
Hide file tree
Showing 20 changed files with 60 additions and 31 deletions.
6 changes: 5 additions & 1 deletion src/ape/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ def display_config(ctx, param, value):
return

click.echo("# Current configuration")
click.echo(yaml.dump(ManagerAccessMixin.project_manager.config_manager.model_dump(mode="json")))

# NOTE: Using json-mode as yaml.dump requires JSON-like structure.
model = ManagerAccessMixin.project_manager.config_manager.model_dump(mode="json")

click.echo(yaml.dump(model))

ctx.exit() # NOTE: Must exit to bypass running ApeCLI

Expand Down
2 changes: 1 addition & 1 deletion src/ape/api/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def settings(self) -> PluginConfig:
The combination of settings from ``ape-config.yaml`` and ``.compiler_settings``.
"""
CustomConfig = self.config.__class__
data = {**self.config.model_dump(mode="json", by_alias=True), **self.compiler_settings}
data = {**self.config.model_dump(by_alias=True), **self.compiler_settings}
return CustomConfig.model_validate(data)

@abstractmethod
Expand Down
4 changes: 1 addition & 3 deletions src/ape/api/networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,7 @@ def networks(self) -> Dict[str, "NetworkAPI"]:
f"More than one network named '{custom_net.name}' in ecosystem '{self.name}'."
)

network_data = custom_net.model_dump(
mode="json", by_alias=True, exclude=("default_provider",)
)
network_data = custom_net.model_dump(by_alias=True, exclude=("default_provider",))
network_data["data_folder"] = self.data_folder / custom_net.name
network_data["ecosystem"] = self
network_type = create_network_type(custom_net.chain_id, custom_net.chain_id)
Expand Down
2 changes: 2 additions & 0 deletions src/ape/api/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,14 @@ def serialize_transaction(self) -> bytes:

@log_instead_of_fail(default="<TransactionAPI>")
def __repr__(self) -> str:
# NOTE: Using JSON mode for style.
data = self.model_dump(mode="json")
params = ", ".join(f"{k}={v}" for k, v in data.items())
cls_name = getattr(type(self), "__name__", TransactionAPI.__name__)
return f"<{cls_name} {params}>"

def __str__(self) -> str:
# NOTE: Using JSON mode for style.
data = self.model_dump(mode="json")
if len(data["data"]) > 9:
# only want to specify encoding if data["data"] is a string
Expand Down
1 change: 1 addition & 0 deletions src/ape/managers/project/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ def _get_contract(self, name: str) -> Optional[ContractContainer]:
return None

# def publish_manifest(self):
# NOTE: Using JSON mode for maximum publishing compatibility.
# manifest = self.manifest.model_dump(mode="json")
# if not manifest["name"]:
# raise ProjectError("Need name to release manifest")
Expand Down
6 changes: 3 additions & 3 deletions src/ape/utils/abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def _encode(self, _type: ABIType, value: Any):
and isinstance(value, (list, tuple))
and len(_type.components or []) > 0
):
non_array_type_data = _type.model_dump(mode="json")
non_array_type_data = _type.model_dump()
non_array_type_data["type"] = "tuple"
non_array_type = ABIType(**non_array_type_data)
return [self._encode(non_array_type, v) for v in value]
Expand Down Expand Up @@ -159,7 +159,7 @@ def _decode(
elif has_array_of_tuples_return:
item_type_str = str(_types[0].type).split("[")[0]
data = {
**_types[0].model_dump(mode="json"),
**_types[0].model_dump(),
"type": item_type_str,
"internalType": item_type_str,
}
Expand All @@ -181,7 +181,7 @@ def _decode(
if item_type_str == "tuple":
# Either an array of structs or nested structs.
item_type_data = {
**output_type.model_dump(mode="json"),
**output_type.model_dump(),
"type": item_type_str,
"internalType": item_type_str,
}
Expand Down
4 changes: 4 additions & 0 deletions src/ape_cache/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@ def _get_cache_data(
def _get_block_cache_data(
self, query: BlockQuery, result: Iterator[BaseInterfaceModel]
) -> Optional[List[Dict[str, Any]]]:
# NOTE: Using JSON-mode for maximum DB compatibility.
return [m.model_dump(mode="json", by_alias=False) for m in result]

@_get_cache_data.register
Expand All @@ -416,6 +417,8 @@ def _get_block_txns_data(
new_result = []
table_columns = [c.key for c in Transactions.__table__.columns] # type: ignore
txns: List[TransactionAPI] = cast(List[TransactionAPI], result)

# NOTE: Using JSON mode for maximum DB compatibility.
for val in [m for m in txns]:
new_dict = {
k: v
Expand Down Expand Up @@ -444,6 +447,7 @@ def _get_block_txns_data(
def _get_cache_events_data(
self, query: ContractEventQuery, result: Iterator[BaseInterfaceModel]
) -> Optional[List[Dict[str, Any]]]:
# NOTE: Using JSON mode for maximum DB compatibility.
return [m.model_dump(mode="json", by_alias=False) for m in result]

def update_cache(self, query: QueryType, result: Iterator[BaseInterfaceModel]):
Expand Down
8 changes: 4 additions & 4 deletions src/ape_ethereum/ecosystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,15 @@ def load_network_configs(cls, values):
use_fork=True,
default_transaction_type=cls.DEFAULT_TRANSACTION_TYPE,
gas_limit=cls.DEFAULT_LOCAL_GAS_LIMIT,
).model_dump(mode="json", by_alias=True)
).model_dump(by_alias=True)
data = merge_configs(default_fork_model, obj)
cfg_forks[key] = ForkedNetworkConfig.model_validate(data)

elif key != LOCAL_NETWORK_NAME and key not in cls.NETWORKS and isinstance(obj, dict):
# Custom network.
default_network_model = create_network_config(
default_transaction_type=cls.DEFAULT_TRANSACTION_TYPE
).model_dump(mode="json", by_alias=True)
).model_dump(by_alias=True)
data = merge_configs(default_network_model, obj)
custom_networks[name] = NetworkConfig.model_validate(data)

Expand Down Expand Up @@ -607,7 +607,7 @@ def encode_calldata(self, abi: Union[ConstructorABI, MethodABI], *args) -> HexBy

def decode_calldata(self, abi: Union[ConstructorABI, MethodABI], calldata: bytes) -> Dict:
raw_input_types = [i.canonical_type for i in abi.inputs]
input_types = [parse_type(i.model_dump(mode="json")) for i in abi.inputs]
input_types = [parse_type(i.model_dump()) for i in abi.inputs]

try:
raw_input_values = decode(raw_input_types, calldata, strict=False)
Expand Down Expand Up @@ -644,7 +644,7 @@ def decode_returndata(self, abi: MethodABI, raw_data: bytes) -> Tuple[Any, ...]:
elif not isinstance(vm_return_values, (tuple, list)):
vm_return_values = (vm_return_values,)

output_types = [parse_type(o.model_dump(mode="json")) for o in abi.outputs]
output_types = [parse_type(o.model_dump()) for o in abi.outputs]
output_values = [
self.decode_primitive_value(v, t) for v, t in zip(vm_return_values, output_types)
]
Expand Down
17 changes: 13 additions & 4 deletions src/ape_ethereum/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ def update_settings(self, new_settings: dict):
self.connect()

def estimate_gas_cost(self, txn: TransactionAPI, block_id: Optional[BlockID] = None) -> int:
# NOTE: Using JSON mode since used as request data.
txn_dict = txn.model_dump(by_alias=True, mode="json")

# Force the use of hex values to support a wider range of nodes.
Expand Down Expand Up @@ -513,6 +514,7 @@ def _eth_call(self, arguments: List) -> HexBytes:
return HexBytes(result)

def _prepare_call(self, txn: TransactionAPI, **kwargs) -> List:
# NOTE: Using JSON mode since used as request data.
txn_dict = txn.model_dump(by_alias=True, mode="json")
fields_to_convert = ("data", "chainId", "value")
for field in fields_to_convert:
Expand Down Expand Up @@ -557,7 +559,7 @@ def get_receipt(
except TimeExhausted as err:
raise TransactionNotFoundError(txn_hash, error_messsage=str(err)) from err

ecosystem_config = self.network.config.model_dump(by_alias=True, mode="json")
ecosystem_config = self.network.config.model_dump(by_alias=True)
network_config: Dict = ecosystem_config.get(self.network.name, {})
max_retries = network_config.get("max_get_transaction_retries", DEFAULT_MAX_RETRIES_TX)
txn = {}
Expand Down Expand Up @@ -868,7 +870,10 @@ def fetch_log_page(block_range):
start, stop = block_range
update = {"start_block": start, "stop_block": stop}
page_filter = log_filter.model_copy(update=update)

# NOTE: Using JSON mode since used as request data.
filter_params = page_filter.model_dump(mode="json")

logs = self._make_request("eth_getLogs", [filter_params])
return self.network.ecosystem.decode_logs(logs, *log_filter.events)

Expand Down Expand Up @@ -941,6 +946,7 @@ def send_transaction(self, txn: TransactionAPI) -> ReceiptAPI:
if txn.sender not in self.web3.eth.accounts:
self.chain_manager.provider.unlock_account(txn.sender)

# NOTE: Using JSON mode since used as request data.
txn_data = cast(TxParams, txn.model_dump(by_alias=True, mode="json"))
txn_hash = self.web3.eth.send_transaction(txn_data)

Expand All @@ -962,7 +968,9 @@ def send_transaction(self, txn: TransactionAPI) -> ReceiptAPI:
self.chain_manager.history.append(receipt)

if receipt.failed:
# NOTE: Using JSON mode since used as request data.
txn_dict = receipt.transaction.model_dump(by_alias=True, mode="json")

txn_params = cast(TxParams, txn_dict)

# Replay txn to get revert reason
Expand Down Expand Up @@ -1012,7 +1020,7 @@ def _create_call_tree_node(
inputs=evm_call.calldata if "CREATE" in call_type else evm_call.calldata[4:].hex(),
method_id=evm_call.calldata[:4].hex(),
outputs=evm_call.returndata.hex(),
raw=evm_call.model_dump(by_alias=True, mode="json"),
raw=evm_call.model_dump(by_alias=True),
txn_hash=txn_hash,
)

Expand All @@ -1035,7 +1043,7 @@ def _create_trace_frame(self, evm_frame: EvmTraceFrame) -> TraceFrame:
gas_cost=evm_frame.gas_cost,
depth=evm_frame.depth,
contract_address=address,
raw=evm_frame.model_dump(by_alias=True, mode="json"),
raw=evm_frame.model_dump(by_alias=True),
)

def _make_request(self, endpoint: str, parameters: Optional[List] = None) -> Any:
Expand Down Expand Up @@ -1081,6 +1089,7 @@ def create_access_list(
Returns:
List[:class:`~ape_ethereum.transactions.AccessList`]
"""
# NOTE: Using JSON mode since used in request data.
tx_dict = transaction.model_dump(by_alias=True, mode="json", exclude=("chain_id",))
tx_dict_converted = {}
for key, val in tx_dict.items():
Expand Down Expand Up @@ -1230,7 +1239,7 @@ def uri(self) -> str:
# Use adhoc, scripted value
return self.provider_settings["uri"]

config = self.config.model_dump(mode="json").get(self.network.ecosystem.name, None)
config = self.config.model_dump().get(self.network.ecosystem.name, None)
if config is None:
return DEFAULT_SETTINGS["uri"]

Expand Down
2 changes: 1 addition & 1 deletion src/ape_geth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def config_class():

@plugins.register(plugins.ProviderPlugin)
def providers():
networks_dict = GethNetworkConfig().model_dump(mode="json")
networks_dict = GethNetworkConfig().model_dump()
networks_dict.pop(LOCAL_NETWORK_NAME)
for network_name in networks_dict:
yield "ethereum", network_name, GethProvider
Expand Down
1 change: 1 addition & 0 deletions src/ape_geth/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ def connect(self):
self.start()

def start(self, timeout: int = 20):
# NOTE: Using JSON mode to ensure types can be passed as CLI args.
test_config = self.config_manager.get_config("test").model_dump(mode="json")

# Allow configuring a custom executable besides your $PATH geth.
Expand Down
1 change: 1 addition & 0 deletions src/ape_test/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def sign_message(self, msg: Any, **signer_options) -> Optional[MessageSignature]

def sign_transaction(self, txn: TransactionAPI, **signer_options) -> Optional[TransactionAPI]:
# Signs anything that's given to it
# NOTE: Using JSON mode since used as request data.
tx_data = txn.model_dump(mode="json", by_alias=True)

try:
Expand Down
12 changes: 11 additions & 1 deletion src/ape_test/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ def estimate_gas_cost(
return self.network.gas_limit

estimate_gas = self.web3.eth.estimate_gas

# NOTE: Using JSON mode since used as request data.
txn_dict = txn.model_dump(mode="json")

txn_dict.pop("gas", None)
txn_data = cast(TxParams, txn_dict)

Expand All @@ -125,7 +128,10 @@ def estimate_gas_cost(
# and then set it back.
expected_nonce, actual_nonce = gas_match.groups()
txn.nonce = int(expected_nonce)

# NOTE: Using JSON mode since used as request data.
txn_params: TxParams = cast(TxParams, txn.model_dump(by_alias=True, mode="json"))

value = estimate_gas(txn_params, block_identifier=block_id)
txn.nonce = int(actual_nonce)
return value
Expand All @@ -141,7 +147,7 @@ def estimate_gas_cost(
@property
def settings(self) -> EthTesterProviderConfig:
return EthTesterProviderConfig.model_validate(
{**self.config.provider.model_dump(mode="json"), **self.provider_settings}
{**self.config.provider.model_dump(), **self.provider_settings}
)

@cached_property
Expand Down Expand Up @@ -177,7 +183,9 @@ def send_call(
state: Optional[Dict] = None,
**kwargs,
) -> HexBytes:
# NOTE: Using JSON mode since used as request data.
data = txn.model_dump(mode="json", exclude_none=True)

state = kwargs.pop("state_override", None)
call_kwargs: Dict = {"block_identifier": block_id, "state_override": state}

Expand Down Expand Up @@ -214,7 +222,9 @@ def send_transaction(self, txn: TransactionAPI) -> ReceiptAPI:
self.chain_manager.history.append(receipt)

if receipt.failed:
# NOTE: Using JSON mode since used as request data.
txn_dict = txn.model_dump(mode="json")

txn_dict["nonce"] += 1
txn_params = cast(TxParams, txn_dict)

Expand Down
1 change: 1 addition & 0 deletions tests/functional/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ def ds_note_test_contract(eth_tester_provider, vyper_contract_type, owner, get_c
def project_with_contract(temp_config):
with temp_config() as project:
copy_tree(str(APE_PROJECT_FOLDER), str(project.path))
project.local_project._cached_manifest = None # Clean manifest
yield project


Expand Down
2 changes: 1 addition & 1 deletion tests/functional/test_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def block(chain):


def test_block_dict(block):
actual = block.model_dump(mode="json")
actual = block.model_dump()
expected = {
"baseFeePerGas": 1000000000,
"difficulty": 0,
Expand Down
6 changes: 2 additions & 4 deletions tests/functional/test_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_Contract_from_abi(contract_instance):
def test_Contract_from_abi_list(contract_instance):
contract = Contract(
contract_instance.address,
abi=[abi.model_dump(mode="json") for abi in contract_instance.contract_type.abi],
abi=[abi.model_dump() for abi in contract_instance.contract_type.abi],
)

assert isinstance(contract, ContractInstance)
Expand All @@ -34,9 +34,7 @@ def test_Contract_from_abi_list(contract_instance):
def test_Contract_from_json_str(contract_instance):
contract = Contract(
contract_instance.address,
abi=json.dumps(
[abi.model_dump(mode="json") for abi in contract_instance.contract_type.abi]
),
abi=json.dumps([abi.model_dump() for abi in contract_instance.contract_type.abi]),
)

assert isinstance(contract, ContractInstance)
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/test_contract_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ def test_value_to_non_payable_fallback_and_no_receive(
and you try to send a value, it fails.
"""
# Hack to set fallback as non-payable.
contract_type_data = vyper_fallback_contract_type.model_dump(mode="json")
contract_type_data = vyper_fallback_contract_type.model_dump()
for abi in contract_type_data["abi"]:
if abi.get("type") == "fallback":
abi["stateMutability"] = "non-payable"
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/test_ecosystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def test_block_handles_snake_case_parent_hash(eth_tester_provider, sender, recei

# Replace 'parentHash' key with 'parent_hash'
latest_block = eth_tester_provider.get_block("latest")
latest_block_dict = eth_tester_provider.get_block("latest").model_dump(mode="json")
latest_block_dict = eth_tester_provider.get_block("latest").model_dump()
latest_block_dict["parent_hash"] = latest_block_dict.pop("parentHash")

redefined_block = Block.model_validate(latest_block_dict)
Expand Down
4 changes: 2 additions & 2 deletions tests/functional/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,10 +265,10 @@ def test_data_when_contains_whitespace():
def test_model_dump_excludes_none_values():
txn = StaticFeeTransaction()
txn.value = 1000000
actual = txn.model_dump(mode="json")
actual = txn.model_dump()
assert "value" in actual
txn.value = None # type: ignore
actual = txn.model_dump(mode="json")
actual = txn.model_dump()
assert "value" not in actual


Expand Down
Loading

0 comments on commit c2f1bc4

Please sign in to comment.