Skip to content

Commit 5a23813

Browse files
committed
feat: expand supported types
1 parent 2b4873b commit 5a23813

File tree

7 files changed

+61
-48
lines changed

7 files changed

+61
-48
lines changed

examples/helloworld/client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# DO NOT MODIFY IT BY HAND.
66
import base64
77
import dataclasses
8+
import decimal
89
import typing
910
from abc import ABC, abstractmethod
1011

examples/lifecycle/client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# DO NOT MODIFY IT BY HAND.
66
import base64
77
import dataclasses
8+
import decimal
89
import typing
910
from abc import ABC, abstractmethod
1011

examples/state/client.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# DO NOT MODIFY IT BY HAND.
66
import base64
77
import dataclasses
8+
import decimal
89
import typing
910
from abc import ABC, abstractmethod
1011

@@ -505,7 +506,7 @@ class SetGlobalArgs(_ArgsBase[None]):
505506
int1: int
506507
int2: int
507508
bytes1: str
508-
bytes2: bytes | tuple[int, int, int, int]
509+
bytes2: bytes | bytearray | tuple[int, int, int, int]
509510

510511
@staticmethod
511512
def method() -> str:
@@ -517,7 +518,7 @@ class SetLocalArgs(_ArgsBase[None]):
517518
int1: int
518519
int2: int
519520
bytes1: str
520-
bytes2: bytes | tuple[int, int, int, int]
521+
bytes2: bytes | bytearray | tuple[int, int, int, int]
521522

522523
@staticmethod
523524
def method() -> str:
@@ -526,7 +527,7 @@ def method() -> str:
526527

527528
@dataclasses.dataclass(kw_only=True)
528529
class SetBoxArgs(_ArgsBase[None]):
529-
name: bytes | tuple[int, int, int, int]
530+
name: bytes | bytearray | tuple[int, int, int, int]
530531
value: str
531532

532533
@staticmethod
@@ -802,7 +803,7 @@ def set_global(
802803
int1: int,
803804
int2: int,
804805
bytes1: str,
805-
bytes2: bytes | tuple[int, int, int, int],
806+
bytes2: bytes | bytearray | tuple[int, int, int, int],
806807
transaction_parameters: algokit_utils.TransactionParameters | None = None,
807808
) -> algokit_utils.ABITransactionResponse[None]:
808809
args = SetGlobalArgs(
@@ -824,7 +825,7 @@ def set_local(
824825
int1: int,
825826
int2: int,
826827
bytes1: str,
827-
bytes2: bytes | tuple[int, int, int, int],
828+
bytes2: bytes | bytearray | tuple[int, int, int, int],
828829
transaction_parameters: algokit_utils.TransactionParameters | None = None,
829830
) -> algokit_utils.ABITransactionResponse[None]:
830831
args = SetLocalArgs(
@@ -843,7 +844,7 @@ def set_local(
843844
def set_box(
844845
self,
845846
*,
846-
name: bytes | tuple[int, int, int, int],
847+
name: bytes | bytearray | tuple[int, int, int, int],
847848
value: str,
848849
transaction_parameters: algokit_utils.TransactionParameters | None = None,
849850
) -> algokit_utils.ABITransactionResponse[None]:

examples/voting/client.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# DO NOT MODIFY IT BY HAND.
66
import base64
77
import dataclasses
8+
import decimal
89
import typing
910
from abc import ABC, abstractmethod
1011

@@ -359,7 +360,7 @@ class VotingPreconditions:
359360

360361
@dataclasses.dataclass(kw_only=True)
361362
class GetPreconditionsArgs(_ArgsBase[VotingPreconditions]):
362-
signature: bytes
363+
signature: bytes | bytearray
363364

364365
@staticmethod
365366
def method() -> str:
@@ -369,7 +370,7 @@ def method() -> str:
369370
@dataclasses.dataclass(kw_only=True)
370371
class VoteArgs(_ArgsBase[None]):
371372
fund_min_bal_req: TransactionWithSigner
372-
signature: bytes
373+
signature: bytes | bytearray
373374
answer_ids: list[int]
374375

375376
@staticmethod
@@ -380,7 +381,7 @@ def method() -> str:
380381
@dataclasses.dataclass(kw_only=True)
381382
class CreateArgs(_ArgsBase[None]):
382383
vote_id: str
383-
snapshot_public_key: bytes
384+
snapshot_public_key: bytes | bytearray
384385
metadata_ipfs_cid: str
385386
start_time: int
386387
end_time: int
@@ -582,7 +583,7 @@ def close(
582583
def get_preconditions(
583584
self,
584585
*,
585-
signature: bytes,
586+
signature: bytes | bytearray,
586587
transaction_parameters: algokit_utils.TransactionParameters | None = None,
587588
) -> algokit_utils.ABITransactionResponse[VotingPreconditions]:
588589
args = GetPreconditionsArgs(
@@ -602,7 +603,7 @@ def vote(
602603
self,
603604
*,
604605
fund_min_bal_req: TransactionWithSigner,
605-
signature: bytes,
606+
signature: bytes | bytearray,
606607
answer_ids: list[int],
607608
transaction_parameters: algokit_utils.TransactionParameters | None = None,
608609
) -> algokit_utils.ABITransactionResponse[None]:
@@ -622,7 +623,7 @@ def create_create(
622623
self,
623624
*,
624625
vote_id: str,
625-
snapshot_public_key: bytes,
626+
snapshot_public_key: bytes | bytearray,
626627
metadata_ipfs_cid: str,
627628
start_time: int,
628629
end_time: int,

src/algokit_client_generator/generator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ def imports(context: GenerateContext) -> DocumentParts:
8080
yield utils.lines(
8181
"""import base64
8282
import dataclasses
83+
import decimal
8384
import typing
8485
from abc import ABC, abstractmethod
8586

src/algokit_client_generator/spec.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@ def get_contract_methods(
156156
struct_class_name=struct_class_name,
157157
fields=[
158158
ABIStructField(
159-
name=name, abi_type=abi_type, python_type=utils.map_abi_type_to_python(abi_type)
159+
name=name,
160+
abi_type=abi_type,
161+
python_type=utils.map_abi_type_to_python(abi_type),
160162
)
161163
# TODO: nested structs?!
162164
for name, abi_type in struct["elements"]

src/algokit_client_generator/utils.py

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import re
22
from collections.abc import Iterable
33

4+
from algosdk import abi
5+
46
from algokit_client_generator.document import DocumentParts, Part
57

68

@@ -23,41 +25,45 @@ def get_method_name(name: str, string_suffix: str = "") -> str:
2325
return "_".join(p for p in parts)
2426

2527

26-
def map_abi_type_to_python(abi_type: str) -> str: # noqa: ignore[PLR0911]
27-
match = re.match(r".*\[([0-9]*)]$", abi_type)
28-
if match:
29-
array_size = match.group(1)
30-
if array_size:
31-
abi_type = abi_type[: -2 - len(array_size)]
32-
array_size = int(array_size)
33-
inner_type = ", ".join([map_abi_type_to_python(abi_type)] * array_size)
34-
tuple_type = f"tuple[{inner_type}]"
35-
if abi_type == "byte":
36-
return f"bytes | {tuple_type}"
37-
return tuple_type
38-
else:
39-
abi_type = abi_type[:-2]
40-
if abi_type == "byte":
41-
return "bytes"
42-
return f"list[{map_abi_type_to_python(abi_type)}]"
43-
if abi_type.startswith("(") and abi_type.endswith(")"):
44-
abi_type = abi_type[1:-1]
45-
inner_types = [map_abi_type_to_python(t) for t in abi_type.split(",")]
46-
return f"tuple[{', '.join(inner_types)}]"
47-
# TODO validate or annotate ints
48-
python_type = {
49-
"string": "str",
50-
"uint8": "int", # < 256
51-
"uint32": "int", # < 2^32
52-
"uint64": "int", # < 2^64
53-
"void": "None",
54-
"byte[]": "bytes",
55-
"byte": "int", # length 1
56-
"pay": "TransactionWithSigner",
57-
}.get(abi_type)
58-
if python_type:
59-
return python_type
60-
return abi_type
28+
def abi_type_to_python(abi_type: abi.ABIType) -> str: # noqa: ignore[PLR0911]
29+
match abi_type:
30+
case abi.UintType():
31+
return "int"
32+
case abi.ArrayDynamicType() as array:
33+
child = array.child_type
34+
if isinstance(child, abi.ByteType):
35+
return "bytes | bytearray"
36+
return f"list[{abi_type_to_python(child)}]"
37+
case abi.ArrayStaticType() as array:
38+
child = array.child_type
39+
if isinstance(child, abi.ByteType):
40+
return f"bytes | bytearray | tuple[{', '.join('int' for _ in range(array.static_length))}]"
41+
inner_type = abi_type_to_python(child)
42+
return f"list[{inner_type}] | tuple[{', '.join(inner_type for _ in range(array.static_length))}]"
43+
case abi.AddressType():
44+
return "str"
45+
case abi.BoolType():
46+
return "bool"
47+
case abi.UfixedType():
48+
return "decimal.Decimal"
49+
case abi.TupleType() as tuple_type:
50+
return f"tuple[{', '.join(abi_type_to_python(t) for t in tuple_type.child_types)}]"
51+
case abi.ByteType():
52+
return "int"
53+
case abi.StringType():
54+
return "str"
55+
case _:
56+
return "typing.Any"
57+
58+
59+
def map_abi_type_to_python(abi_type_str: str) -> str:
60+
if abi_type_str == "void":
61+
return "None"
62+
if abi.is_abi_transaction_type(abi_type_str):
63+
# TODO: generic TransactionWithSigner and/or allow unsigned types signed with signer used in transaction
64+
return "TransactionWithSigner"
65+
abi_type = abi.ABIType.from_string(abi_type_str)
66+
return abi_type_to_python(abi_type)
6167

6268

6369
def get_unique_symbol_by_incrementing(existing_symbols: set[str], base_name: str) -> str:

0 commit comments

Comments
 (0)