Skip to content

Commit

Permalink
fix: prevent usage of state proxies (GlobalState, LocalState) outside…
Browse files Browse the repository at this point in the history
… __init__ method

BREAKING CHANGE: Using state proxies (GlobalState, LocalState) outside of an __init__ method may not give the behaviour expected, so prevent their usage in those scenarios
  • Loading branch information
daniel-makerx authored and tristanmenzel committed Apr 8, 2024
1 parent c9a7224 commit d354d4e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/puya/awst_build/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
CLS_BIGUINT_ALIAS = f"{ALGOPY_PREFIX}BigUInt"
CLS_TRANSACTION_BASE = f"{ALGOPY_PREFIX}gtxn.TransactionBase"
CLS_LOCAL_STATE = f"{ALGOPY_PREFIX}_state.LocalState"
CLS_LOCAL_STATE_ALIAS = f"{ALGOPY_PREFIX}.LocalState"
CLS_LOCAL_STATE_ALIAS = f"{ALGOPY_PREFIX}LocalState"
CLS_GLOBAL_STATE = f"{ALGOPY_PREFIX}_state.GlobalState"
CLS_GLOBAL_STATE_ALIAS = f"{ALGOPY_PREFIX}.GlobalState"
CLS_GLOBAL_STATE_ALIAS = f"{ALGOPY_PREFIX}GlobalState"
SUBROUTINE_HINT = f"{ALGOPY_PREFIX}_hints.subroutine"
LOGICSIG_DECORATOR = f"{ALGOPY_PREFIX}_logic_sig.logicsig"
LOGICSIG_DECORATOR_ALIAS = f"{ALGOPY_PREFIX}.logicsig"
Expand Down
5 changes: 5 additions & 0 deletions src/puya/awst_build/subroutine.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,11 @@ def _handle_state_proxy_assignment(
raise CodeError(
f"{rvalue.python_name} should only be used inside a contract class", stmt_loc
)
if self.func_def.name != "__init__":
raise CodeError(
f"{rvalue.python_name} can only be used in the __init__ method",
stmt_loc,
)
if len(lvalues) != 1:
raise CodeError(
f"{rvalue.python_name} can only be assigned to a single member variable",
Expand Down
21 changes: 21 additions & 0 deletions tests/test_expected_output/expected_errors.test
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,24 @@ class Baddie(arc4.ARC4Contract):
arr2.append(arc4.Byte(1))
assert foo


## case: test_state_proxies_outside_init_fail
from algopy import GlobalState, LocalState, Txn, UInt64, arc4

class Baddie(arc4.ARC4Contract):
def __init__(self) -> None:
self.global_a = GlobalState(UInt64)
self.local_b = LocalState(UInt64)

@arc4.abimethod
def okay(self) -> None:
self.global_a.value = UInt64(123)
self.local_b[Txn.sender] = UInt64(456)

@arc4.abimethod()
def not_okay1(self) -> None:
self.global_c = GlobalState(UInt64) ## E: algopy.GlobalState can only be used in the __init__ method

@arc4.abimethod()
def not_okay2(self) -> None:
self.local_d = LocalState(UInt64) ## E: algopy.LocalState can only be used in the __init__ method

0 comments on commit d354d4e

Please sign in to comment.