Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile time failure for chained comparison expressions #587

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pyteal/ast/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Tuple, List, TYPE_CHECKING

from pyteal.types import TealType
from pyteal.errors import TealInternalError
from pyteal.ir import TealBlock, TealSimpleBlock

if TYPE_CHECKING:
Expand Down Expand Up @@ -129,6 +130,9 @@ def __rshift__(self, other):

return ShiftRight(self, other)

def __bool__(self):
raise TealInternalError("Cannot coerce Expr to bool")

def And(self, other: "Expr") -> "Expr":
"""Take the logical And of this expression and another one.

Expand Down
12 changes: 6 additions & 6 deletions pyteal/ast/if_.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def __init__(
# Flag to denote and check whether the new If().Then() syntax is being used
self.alternateSyntaxFlag = False

if thenBranch:
if elseBranch:
if thenBranch is not None:
if elseBranch is not None:
require_type(thenBranch, elseBranch.type_of())
else:
# If there is only a thenBranch, then it should evaluate to none type
Expand Down Expand Up @@ -106,7 +106,7 @@ def Then(self, thenBranch: Expr, *then_branch_multi: Expr):

thenBranch = _use_seq_if_multiple(thenBranch, *then_branch_multi)

if not self.elseBranch:
if self.elseBranch is None:
self.thenBranch = thenBranch
else:
if not isinstance(self.elseBranch, If):
Expand All @@ -118,7 +118,7 @@ def ElseIf(self, cond):
if not self.alternateSyntaxFlag:
raise TealInputError("Cannot mix two different If syntax styles")

if not self.elseBranch:
if self.elseBranch is None:
self.elseBranch = If(cond)
else:
if not isinstance(self.elseBranch, If):
Expand All @@ -130,12 +130,12 @@ def Else(self, elseBranch: Expr, *else_branch_multi: Expr):
if not self.alternateSyntaxFlag:
raise TealInputError("Cannot mix two different If syntax styles")

if not self.thenBranch:
if self.thenBranch is None:
raise TealInputError("Must set Then branch before Else branch")

elseBranch = _use_seq_if_multiple(elseBranch, *else_branch_multi)

if not self.elseBranch:
if self.elseBranch is None:
require_type(elseBranch, self.thenBranch.type_of())
self.elseBranch = elseBranch
else:
Expand Down
8 changes: 4 additions & 4 deletions pyteal/ast/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class OnCompleteAction:
call_config: CallConfig = field(kw_only=True, default=CallConfig.NEVER)

def __post_init__(self):
if bool(self.call_config) ^ bool(self.action):
if (self.call_config == CallConfig.NEVER) ^ (self.action is None):
raise TealInputError(
f"action {self.action} and call_config {self.call_config!r} contradicts"
)
Expand Down Expand Up @@ -172,7 +172,7 @@ def always(
return OnCompleteAction(action=f, call_config=CallConfig.ALL)

def is_empty(self) -> bool:
return not self.action and self.call_config == CallConfig.NEVER
return self.action is None and self.call_config == CallConfig.NEVER


OnCompleteAction.__module__ = "pyteal"
Expand Down Expand Up @@ -528,15 +528,15 @@ def __init__(

if bare_calls and not bare_calls.is_empty():
bare_call_approval = bare_calls.approval_construction()
if bare_call_approval:
if bare_call_approval is not None:
self.approval_ast.conditions_n_branches.append(
CondNode(
Txn.application_args.length() == Int(0),
cast(Expr, bare_call_approval),
)
)
bare_call_clear = bare_calls.clear_state_construction()
if bare_call_clear:
if bare_call_clear is not None:
self.clear_state_ast.conditions_n_branches.append(
CondNode(
Txn.application_args.length() == Int(0),
Expand Down
4 changes: 2 additions & 2 deletions pyteal/ast/scratch.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def __init__(
"Exactly one of slot or index_expressions must be provided"
)

if index_expression:
if index_expression is not None:
if not isinstance(index_expression, Expr):
raise TealInputError(
"index_expression must be an Expr but was of type {}".format(
Expand Down Expand Up @@ -185,7 +185,7 @@ def __init__(
"Exactly one of slot or index_expressions must be provided"
)

if index_expression:
if index_expression is not None:
if not isinstance(index_expression, Expr):
raise TealInputError(
"index_expression must be an Expr but was of type {}".format(
Expand Down
2 changes: 1 addition & 1 deletion tests/blackbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def _prepare_n_calls(self):
*(self._arg_prep_n_call(i, p) for i, p in enumerate(self.input_types))
]
preps, calls = zip(*preps_n_calls) if preps_n_calls else ([], [])
preps = [p for p in preps if p]
preps = [p for p in preps if p is not None]
return preps, calls

def _handle_SubroutineFnWrapper(self):
Expand Down