Skip to content

Commit

Permalink
fix: prevent assertion error when using dynamic key with storage prox…
Browse files Browse the repository at this point in the history
…y and assinging to self member
  • Loading branch information
achidlow authored and daniel-makerx committed Jul 1, 2024
1 parent 0aade7a commit 351b51e
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 2 deletions.
1 change: 0 additions & 1 deletion src/puya/awst_build/contract_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def key(self) -> BytesConstant:
case invalid_kind:
typing.assert_never(invalid_kind)
if self.key_override is not None:
assert self.key_override.wtype == wtype
bytes_const = self.key_override
else:
bytes_const = BytesConstant(
Expand Down
3 changes: 2 additions & 1 deletion src/puya/awst_build/eb/storage/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,8 @@ def build_definition(
key_override = self.resolve()
if not isinstance(key_override, BytesConstant):
logger.error(
f"assigning {typ} to a member variable requires a constant value for key",
f"assigning {typ} to a member variable requires a constant value for"
f" key{'_prefix' if isinstance(typ, pytypes.StorageMapProxyType) else ''}",
location=location,
)
key_override = BytesConstant(
Expand Down
11 changes: 11 additions & 0 deletions tests/test_expected_output/box.test
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,14 @@ class MyContract(arc4.ARC4Contract):
def __init__(self) -> None:
self.my_box = Box(bool, key="")
assert not self.my_box.length, "length op fails because the key is empty" ## E: AVM does not support empty box keys


## case: dynamic_keys_with_self_assignment
from algopy import *

class MyContract(arc4.ARC4Contract):
def __init__(self) -> None:
dynamic = String("dynamic")
self.box = Box(UInt64, key=dynamic) ## E: assigning algopy.Box[algopy.UInt64] to a member variable requires a constant value for key
self.box_map = BoxMap(UInt64, UInt64, key_prefix=dynamic) ## E: assigning algopy.BoxMap[algopy.UInt64, algopy.UInt64] to a member variable requires a constant value for key_prefix
self.box_ref = BoxRef(key=dynamic) ## E: assigning algopy.BoxRef to a member variable requires a constant value for key
10 changes: 10 additions & 0 deletions tests/test_expected_output/global_proxy.test
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ class StateProxyContract4(ARC4Contract):


class StateProxyContract5(ARC4Contract):
def __init__(self) -> None:
dynamic = String("dynamic")
self._global = GlobalState(UInt64, key=dynamic) ## E: assigning algopy.GlobalState[algopy.UInt64] to a member variable requires a constant value for key
self.local_ = LocalState(UInt64, key=dynamic) ## E: assigning algopy.LocalState[algopy.UInt64] to a member variable requires a constant value for key


## case: test_global_stubs
from algopy import *

class StateProxyContract6(ARC4Contract):
def __init__(self) -> None:
self.global_ = GlobalState(UInt64(0), key=String("global3")) ## E: No overload variant of "GlobalState" matches argument types "UInt64", "String" [call-overload] \
## N: def [_TState] __init__(self, _TState, /, *, key: bytes | str = ..., description: str = ...) -> GlobalState[_TState] \
Expand Down

0 comments on commit 351b51e

Please sign in to comment.