diff --git a/CHANGELOG.md b/CHANGELOG.md index fe7bada73..be248fd9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ## Changed * Subroutines that take ABI type of Transaction now allow any Transaction type to be passed. ([#531](https://github.com/algorand/pyteal/pull/531)) +* Relaxing exact type check in `InnerTxnFieldExpr.MethodCall` by applying `abi.type_spec_is_assignable_to`. ([#561](https://github.com/algorand/pyteal/pull/561)) # 0.18.1 diff --git a/pyteal/ast/abi/__init__.py b/pyteal/ast/abi/__init__.py index c137110de..f13a59b60 100644 --- a/pyteal/ast/abi/__init__.py +++ b/pyteal/ast/abi/__init__.py @@ -82,6 +82,7 @@ make, size_of, type_spec_from_annotation, + type_spec_from_algosdk, type_specs_from_signature, contains_type_spec, type_spec_is_assignable_to, @@ -162,6 +163,7 @@ "KeyRegisterTransactionTypeSpec", "TransactionTypeSpecs", "type_spec_from_annotation", + "type_spec_from_algosdk", "type_specs_from_signature", "make", "size_of", diff --git a/pyteal/ast/itxn.py b/pyteal/ast/itxn.py index d38eb55d5..71b39445c 100644 --- a/pyteal/ast/itxn.py +++ b/pyteal/ast/itxn.py @@ -387,9 +387,10 @@ def MethodCall( txntype = cast(EnumInt, arg[TxnField.type_enum]).name # If the arg is an unspecified transaction, no need to check the type_enum - if not type( - method_arg_ts - ) is abi.TransactionTypeSpec and txntype != str(method_arg_ts): + + if not abi.type_spec_is_assignable_to( + abi.type_spec_from_algosdk(txntype), method_arg_ts + ): raise TealInputError( f"Expected Transaction at arg {idx} to be {method_arg_ts}, got {txntype}" ) @@ -459,7 +460,9 @@ def MethodCall( require_type(arg, TealType.bytes) app_args.append(arg) elif isinstance(arg, abi.BaseType): - if arg.type_spec() != method_arg_ts: + if not abi.type_spec_is_assignable_to( + arg.type_spec(), method_arg_ts + ): raise TealTypeError(arg.type_spec(), method_arg_ts) app_args.append(arg.encode()) else: diff --git a/pyteal/ast/itxn_test.py b/pyteal/ast/itxn_test.py index f6ee455ef..d4f111215 100644 --- a/pyteal/ast/itxn_test.py +++ b/pyteal/ast/itxn_test.py @@ -309,6 +309,27 @@ def test_InnerTxnBuilder_Execute(): ), None, ), + ( + pt.Int(1), + "query(byte[],uint64)void", + [t6_1 := pt.abi.DynamicBytes(), t6_2 := pt.abi.Uint64()], + {TxnField.fee: pt.Int(0)}, + pt.Seq( + pt.InnerTxnBuilder.SetFields( + { + pt.TxnField.type_enum: TxnType.ApplicationCall, + pt.TxnField.application_id: pt.Int(1), + pt.TxnField.application_args: [ + pt.MethodSignature("query(byte[],uint64)void"), + t6_1.encode(), + t6_2.encode(), + ], + pt.TxnField.fee: pt.Int(0), + } + ), + ), + None, + ), # Error cases ( pt.Int(1),