Skip to content

Commit

Permalink
update type spec assignable check scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
ahangsu committed Oct 3, 2022
1 parent 116a88f commit a535375
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 27 deletions.
4 changes: 2 additions & 2 deletions pyteal/ast/abi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
type_spec_from_annotation,
type_specs_from_signature,
contains_type_spec,
type_spec_is_assignable,
type_spec_is_assignable_to,
)

__all__ = [
Expand Down Expand Up @@ -168,5 +168,5 @@
"algosdk_from_annotation",
"algosdk_from_type_spec",
"contains_type_spec",
"type_spec_is_assignable",
"type_spec_is_assignable_to",
]
31 changes: 12 additions & 19 deletions pyteal/ast/abi/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ def type_specs_from_signature(sig: str) -> tuple[list[TypeSpec], Optional[TypeSp
return [type_spec_from_algosdk(arg.type) for arg in sdk_method.args], return_type


def type_spec_is_assignable(a: TypeSpec, b: TypeSpec) -> bool:
def type_spec_is_assignable_to(a: TypeSpec, b: TypeSpec) -> bool:
from pyteal.ast.abi import (
TupleTypeSpec,
ArrayTypeSpec,
Expand All @@ -518,36 +518,29 @@ def type_spec_is_assignable(a: TypeSpec, b: TypeSpec) -> bool:
return False
return all(
map(
lambda ab: type_spec_is_assignable(ab[0], ab[1]),
lambda ab: type_spec_is_assignable_to(ab[0], ab[1]),
zip(a.value_type_specs(), b.value_type_specs()),
)
)
case TupleTypeSpec(), _:
return False
case ArrayTypeSpec(), ArrayTypeSpec():
a, b = cast(ArrayTypeSpec, a), cast(ArrayTypeSpec, b)
if not type_spec_is_assignable(a.value_type_spec(), b.value_type_spec()):
if not type_spec_is_assignable_to(a.value_type_spec(), b.value_type_spec()):
return False
match a, b:
case AddressTypeSpec(), StaticArrayTypeSpec():
a, b = cast(AddressTypeSpec, a), cast(StaticArrayTypeSpec, b)
return a.length_static() == b.length_static()
case StaticArrayTypeSpec(), AddressTypeSpec():
return False
case StaticArrayTypeSpec(), StaticArrayTypeSpec():
a, b = cast(StaticArrayTypeSpec, a), cast(StaticArrayTypeSpec, b)
return a.length_static() == b.length_static()
case DynamicArrayTypeSpec(), DynamicArrayTypeSpec():
case StringTypeSpec(), DynamicArrayTypeSpec():
return True
return False
case (ArrayTypeSpec(), _) | (_, ArrayTypeSpec()):
if isinstance(b, ArrayTypeSpec):
a, b = b, a
match a, b:
case DynamicArrayTypeSpec(), StringTypeSpec():
a, b = cast(DynamicArrayTypeSpec, a), cast(StringTypeSpec, b)
return a.value_type_spec() == b.value_type_spec()
case StaticArrayTypeSpec(), AddressTypeSpec():
a, b = cast(StaticArrayTypeSpec, a), cast(AddressTypeSpec, b)
return (
a.value_type_spec() == b.value_type_spec()
and a.length_static() == b.length_static()
)
return False
case DynamicArrayTypeSpec(), DynamicArrayTypeSpec():
return True
return False

if isinstance(a, type(b)):
Expand Down
12 changes: 6 additions & 6 deletions pyteal/ast/abi/util_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -783,12 +783,12 @@ class NamedTDecl(abi.NamedTuple):

class NamedTComp0(abi.NamedTuple):
a0: abi.Field[abi.String]
a1: abi.Field[abi.StaticArray[abi.Byte, Literal[32]]]
a1: abi.Field[abi.Address]


class NamedTComp1(abi.NamedTuple):
b0: abi.Field[abi.DynamicBytes]
b1: abi.Field[abi.Address]
b1: abi.Field[abi.StaticBytes[Literal[32]]]


class NamedTComp2(abi.NamedTuple):
Expand Down Expand Up @@ -874,7 +874,7 @@ class NamedTComp2(abi.NamedTuple):
(
abi.type_spec_from_annotation(abi.DynamicArray[abi.Byte]),
abi.type_spec_from_annotation(abi.String),
True,
False,
),
(
abi.type_spec_from_annotation(abi.DynamicArray[abi.Uint32]),
Expand All @@ -889,7 +889,7 @@ class NamedTComp2(abi.NamedTuple):
(
abi.type_spec_from_annotation(abi.StaticBytes[Literal[32]]),
abi.type_spec_from_annotation(abi.Address),
True,
False,
),
(
abi.type_spec_from_annotation(abi.StaticBytes[Literal[33]]),
Expand All @@ -904,7 +904,7 @@ class NamedTComp2(abi.NamedTuple):
(
abi.type_spec_from_annotation(NamedTComp1),
abi.type_spec_from_annotation(NamedTComp0),
True,
False,
),
(
abi.type_spec_from_annotation(NamedTDecl),
Expand All @@ -931,4 +931,4 @@ class NamedTComp2(abi.NamedTuple):

@pytest.mark.parametrize("a, b, expected", TYPE_SPEC_ASSIGNABLE_CASES)
def test_type_spec_assignable(a, b, expected):
assert abi.type_spec_is_assignable(a, b) == expected
assert abi.type_spec_is_assignable_to(a, b) == expected

0 comments on commit a535375

Please sign in to comment.