Skip to content

Commit

Permalink
Add method to get Method by name (#345)
Browse files Browse the repository at this point in the history
* adding util method to get a Method from an interface or contract by name string
  • Loading branch information
barnjamin committed Jun 15, 2022
1 parent d64385b commit 13196fa
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
UNITS = "@unit.abijson or @unit.algod or @unit.algod.ledger_refactoring or @unit.applications or @unit.atomic_transaction_composer or @unit.dryrun or @unit.dryrun.trace.application or @unit.feetest or @unit.indexer or @unit.indexer.ledger_refactoring or @unit.indexer.logs or @unit.offline or @unit.rekey or @unit.transactions.keyreg or @unit.responses or @unit.responses.231 or @unit.tealsign or @unit.transactions or @unit.transactions.payment or @unit.responses.unlimited_assets"
UNITS = "@unit.abijson or @unit.abijson.byname or @unit.algod or @unit.algod.ledger_refactoring or @unit.applications or @unit.atomic_transaction_composer or @unit.dryrun or @unit.dryrun.trace.application or @unit.feetest or @unit.indexer or @unit.indexer.ledger_refactoring or @unit.indexer.logs or @unit.offline or @unit.rekey or @unit.transactions.keyreg or @unit.responses or @unit.responses.231 or @unit.tealsign or @unit.transactions or @unit.transactions.payment or @unit.responses.unlimited_assets"
unit:
behave --tags=$(UNITS) test -f progress2

Expand Down
5 changes: 4 additions & 1 deletion algosdk/abi/contract.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
from typing import Dict, List, Union

from algosdk.abi.method import Method
from algosdk.abi.method import Method, get_method_by_name


class Contract:
Expand Down Expand Up @@ -63,6 +63,9 @@ def undictify(d: dict) -> "Contract":
name=name, desc=desc, networks=networks, methods=method_list
)

def get_method_by_name(self, name: str) -> Method:
return get_method_by_name(self.methods, name)


class NetworkInfo:
"""
Expand Down
5 changes: 4 additions & 1 deletion algosdk/abi/interface.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
from typing import List, Union

from algosdk.abi.method import Method
from algosdk.abi.method import Method, get_method_by_name


class Interface:
Expand Down Expand Up @@ -49,3 +49,6 @@ def undictify(d: dict) -> "Interface":
method_list = [Method.undictify(method) for method in d["methods"]]
desc = d["desc"] if "desc" in d else None
return Interface(name=name, desc=desc, methods=method_list)

def get_method_by_name(self, name: str) -> Method:
return get_method_by_name(self.methods, name)
19 changes: 19 additions & 0 deletions algosdk/abi/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,25 @@ def undictify(d: dict) -> "Method":
return Method(name=name, args=arg_list, returns=return_obj, desc=desc)


def get_method_by_name(methods: List[Method], name: str) -> Method:
methods_filtered = [method for method in methods if method.name == name]

if len(methods_filtered) > 1:
raise KeyError(
"found {} methods with the same name {}".format(
len(methods_filtered),
",".join(
[method.get_signature() for method in methods_filtered]
),
)
)

if len(methods_filtered) == 0:
raise KeyError("found 0 methods for {}".format(name))

return methods_filtered[0]


class Argument:
"""
Represents an argument for a ABI method
Expand Down
51 changes: 51 additions & 0 deletions test/steps/application_v2_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -992,3 +992,54 @@ def spin_results_satisfy(context, result_index, regex):
spin = bytes(spin).decode()

assert re.search(regex, spin), f"{spin} did not match the regex {regex}"


@when(
'I append to my Method objects list in the case of a non-empty signature "{method:MaybeString}"'
)
def make_extra_method(context, method):
if not hasattr(context, "methods"):
context.methods = []

if method != "":
context.methods.append(abi.Method.from_signature(method))


@when("I create an Interface object from my Method objects list")
def create_interface_from_method(context):
context.iface = abi.Interface("", context.methods)


@when("I create a Contract object from my Method objects list")
def create_contract_from_method(context):
context.contract = abi.Contract("", context.methods)


@when('I get the method from the Interface by name "{name}"')
def get_interface_method_by_name(context, name):
try:
context.retrieved_method = context.iface.get_method_by_name(name)
except KeyError as ke:
context.error = str(ke)


@when('I get the method from the Contract by name "{name}"')
def get_contract_method_by_name(context, name):
try:
context.retrieved_method = context.contract.get_method_by_name(name)
except KeyError as ke:
context.error = str(ke)


@then(
'the produced method signature should equal "{methodsig}". If there is an error it begins with "{error:MaybeString}"'
)
def check_found_method_or_error(context, methodsig, error: str = None):
if hasattr(context, "retrieved_method"):
assert error == ""
assert methodsig == context.retrieved_method.get_signature()
elif hasattr(context, "error"):
assert error != ""
assert error in context.error
else:
assert False, "Both retrieved method and error string are None"

0 comments on commit 13196fa

Please sign in to comment.