Skip to content
Merged
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
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ dependencies = [
"coincurve>=19.0.1",
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "algorand-python>=3",
"algorand-python@git+https://github.com/algorandfoundation/[email protected].10#subdirectory=stubs",
"algorand-python@git+https://github.com/algorandfoundation/[email protected].11#subdirectory=stubs",
]

[project.urls]
Expand All @@ -54,7 +54,7 @@ python = "3.12"
dependencies = [
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "puyapy>=5",
"puyapy@git+https://github.com/algorandfoundation/[email protected].10",
"puyapy@git+https://github.com/algorandfoundation/[email protected].11",
"pytest>=7.4",
"pytest-mock>=3.10.0",
"pytest-xdist[psutil]>=3.3",
Expand Down Expand Up @@ -138,7 +138,7 @@ dependencies = [
"algokit-utils>=3.0.0",
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "puyapy>=5",
"puyapy@git+https://github.com/algorandfoundation/[email protected].10",
"puyapy@git+https://github.com/algorandfoundation/[email protected].11",
]

[tool.hatch.envs.test.scripts]
Expand Down Expand Up @@ -191,7 +191,7 @@ post-install-commands = [
dependencies = [
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
# "algorand-python>=3",
"algorand-python@git+https://github.com/algorandfoundation/[email protected].10#subdirectory=stubs",
"algorand-python@git+https://github.com/algorandfoundation/[email protected].11#subdirectory=stubs",
"pytest>=7.4",
"pytest-mock>=3.10.0",
"pytest-xdist[psutil]>=3.3",
Expand Down
19 changes: 11 additions & 8 deletions src/_algopy_testing/primitives/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,22 +281,25 @@ class ImmutableArray(Serializable, typing.Generic[_TArrayItem], metaclass=_Immut
_element_type: typing.ClassVar[type]

# ensure type is fully parameterized by looking up type from metaclass
def __new__(cls, *items: _TArrayItem) -> typing.Self:

def __new__(cls, values: Iterable[_TArrayItem] = ()) -> typing.Self:
from _algopy_testing.serialize import type_of

try:
assert cls._element_type
except AttributeError:
try:
items = list(values)
item = items[0]
except IndexError:
raise TypeError("array must have an item type") from None
cls = cls[type_of(item)]
instance = super().__new__(cls)
return instance

def __init__(self, *items: _TArrayItem):
def __init__(self, values: Iterable[_TArrayItem] = ()):
super().__init__()
items = list(values)
for item in items:
if not isinstance(item, typing.get_origin(self._element_type) or self._element_type):
raise TypeError(f"expected items of type {self._element_type}")
Expand Down Expand Up @@ -347,7 +350,7 @@ def _from_iter(self, items: Iterable[_TArrayItem]) -> "ImmutableArray[_TArrayIte
preserved."""
el_type = self._element_type
typ = ImmutableArray[el_type] # type: ignore[valid-type]
return typ(*items)
return typ(items)

def __bool__(self) -> bool:
return bool(self._items)
Expand All @@ -361,8 +364,8 @@ def from_bytes(cls, value: bytes, /) -> typing.Self:


class ReferenceArray(Reversible[_TArrayItem]):
def __init__(self, *items: _TArrayItem):
self._items = list(items)
def __init__(self, values: Iterable[_TArrayItem] = ()):
self._items = list(values)

def __iter__(self) -> Iterator[_TArrayItem]:
return iter(list(self._items))
Expand Down Expand Up @@ -391,10 +394,10 @@ def pop(self) -> _TArrayItem:
return self._items.pop()

def copy(self) -> "ReferenceArray[_TArrayItem]":
return ReferenceArray(*self._items)
return ReferenceArray(self._items)

def freeze(self) -> ImmutableArray[_TArrayItem]:
return ImmutableArray(*self._items)
return ImmutableArray(self._items)

def __bool__(self) -> bool:
return bool(self._items)
Expand Down Expand Up @@ -488,7 +491,7 @@ def copy(self) -> typing.Self:
return self.__class__.from_bytes(self.serialize())

def freeze(self) -> ImmutableArray[_TArrayItem]:
return ImmutableArray(*self._items)
return ImmutableArray(self._items)

def _from_iter(self, items: Iterable[_TArrayItem]) -> "Array[_TArrayItem]":
"""Returns a new array populated with items, also ensures element type info is
Expand Down
2 changes: 0 additions & 2 deletions src/_algopy_testing/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,6 @@ def get_native_to_arc4_serializer( # noqa: PLR0911
),
arc4_to_native=lambda arr: (
typ([element_serializer.arc4_to_native(e) for e in arr])
if issubclass(typ, Array)
else typ(*[element_serializer.arc4_to_native(e) for e in arr])
),
)
if issubclass(typ, FixedArray | ImmutableFixedArray):
Expand Down
272 changes: 272 additions & 0 deletions tests/artifacts/Arrays/data/DynamicArrayInitContract.approval.teal
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
#pragma version 10
#pragma typetrack false

// algopy.arc4.ARC4Contract.approval_program() -> uint64:
main:
intcblock 8 3 1 0
bytecblock 0x000000000000000100000000000000020000000000000003
// tests/artifacts/Arrays/immutable.py:479
// class DynamicArrayInitContract(arc4.ARC4Contract):
txn NumAppArgs
bz main___algopy_default_create@11
txn OnCompletion
!
assert // OnCompletion must be NoOp
txn ApplicationID
assert
pushbytess 0x8434ba2a 0x63aabba0 0xdbaf034e 0xa9d14554 // method "test_immutable_array_init()void", method "test_immutable_array_init_without_type_generic()void", method "test_reference_array_init()void", method "test_reference_array_init_without_type_generic()void"
txna ApplicationArgs 0
match test_immutable_array_init test_immutable_array_init_without_type_generic test_reference_array_init test_reference_array_init_without_type_generic
err

main___algopy_default_create@11:
txn OnCompletion
!
txn ApplicationID
!
&&
return // on error: OnCompletion must be NoOp && can only call when creating


// tests.artifacts.Arrays.immutable.DynamicArrayInitContract.test_immutable_array_init[routing]() -> void:
test_immutable_array_init:
// tests/artifacts/Arrays/immutable.py:490
// a3 = ImmutableArray[UInt64](ReferenceArray((UInt64(1), UInt64(2), UInt64(3))))
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
// tests/artifacts/Arrays/immutable.py:480
// @arc4.abimethod()
intc_2 // 1
return


// tests.artifacts.Arrays.immutable.DynamicArrayInitContract.test_immutable_array_init_without_type_generic[routing]() -> void:
test_immutable_array_init_without_type_generic:
// tests/artifacts/Arrays/immutable.py:512
// a3 = ImmutableArray(ReferenceArray((UInt64(1), UInt64(2), UInt64(3))))
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
// tests/artifacts/Arrays/immutable.py:502
// @arc4.abimethod()
intc_2 // 1
return


// tests.artifacts.Arrays.immutable.DynamicArrayInitContract.test_reference_array_init[routing]() -> void:
test_reference_array_init:
// tests/artifacts/Arrays/immutable.py:526
// a1 = ReferenceArray[UInt64]((UInt64(1), UInt64(2), UInt64(3)))
bytec_0 // 0x000000000000000100000000000000020000000000000003
// tests/artifacts/Arrays/immutable.py:528
// a2 = ReferenceArray[UInt64](FixedArray((UInt64(1), UInt64(2), UInt64(3))))
dup
pop
dupn 2
// tests/artifacts/Arrays/immutable.py:529
// assert a1.length == a2.length
len
intc_0 // 8
/
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:530
// assert a1[0] == a2[0]
dup
intc_3 // 0
extract_uint64
intc_2 // 1
==
assert
// tests/artifacts/Arrays/immutable.py:531
// assert a1[1] == a2[1]
dup
intc_0 // 8
extract_uint64
pushint 2 // 2
==
assert
// tests/artifacts/Arrays/immutable.py:532
// assert a1[2] == a2[2]
pushint 16 // 16
extract_uint64
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:534
// a3 = ReferenceArray[UInt64](ImmutableArray((UInt64(1), UInt64(2), UInt64(3))))
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
dupn 2
// tests/artifacts/Arrays/immutable.py:536
// assert a1[0] == a3[0]
intc_3 // 0
extract_uint64
intc_2 // 1
==
assert
// tests/artifacts/Arrays/immutable.py:537
// assert a1[1] == a3[1]
dup
intc_0 // 8
extract_uint64
pushint 2 // 2
==
assert
// tests/artifacts/Arrays/immutable.py:538
// assert a1[2] == a3[2]
pushint 16 // 16
extract_uint64
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:526
// a1 = ReferenceArray[UInt64]((UInt64(1), UInt64(2), UInt64(3)))
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
// tests/artifacts/Arrays/immutable.py:541
// assert a1.length == a4.length
dup
len
intc_0 // 8
/
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:542
// assert a1[0] == a4[0]
dup
intc_3 // 0
extract_uint64
intc_2 // 1
==
assert
// tests/artifacts/Arrays/immutable.py:543
// assert a1[1] == a4[1]
dup
intc_0 // 8
extract_uint64
pushint 2 // 2
==
assert
// tests/artifacts/Arrays/immutable.py:544
// assert a1[2] == a4[2]
pushint 16 // 16
extract_uint64
intc_1 // 3
==
// tests/artifacts/Arrays/immutable.py:524
// @arc4.abimethod()
return


// tests.artifacts.Arrays.immutable.DynamicArrayInitContract.test_reference_array_init_without_type_generic[routing]() -> void:
test_reference_array_init_without_type_generic:
// tests/artifacts/Arrays/immutable.py:548
// a1 = ReferenceArray((UInt64(1), UInt64(2), UInt64(3)))
bytec_0 // 0x000000000000000100000000000000020000000000000003
// tests/artifacts/Arrays/immutable.py:550
// a2 = ReferenceArray(FixedArray((UInt64(1), UInt64(2), UInt64(3))))
dup
pop
dupn 2
// tests/artifacts/Arrays/immutable.py:551
// assert a1.length == a2.length
len
intc_0 // 8
/
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:552
// assert a1[0] == a2[0]
dup
intc_3 // 0
extract_uint64
intc_2 // 1
==
assert
// tests/artifacts/Arrays/immutable.py:553
// assert a1[1] == a2[1]
dup
intc_0 // 8
extract_uint64
pushint 2 // 2
==
assert
// tests/artifacts/Arrays/immutable.py:554
// assert a1[2] == a2[2]
pushint 16 // 16
extract_uint64
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:556
// a3 = ReferenceArray(ImmutableArray((UInt64(1), UInt64(2), UInt64(3))))
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
dupn 2
// tests/artifacts/Arrays/immutable.py:558
// assert a1[0] == a3[0]
intc_3 // 0
extract_uint64
intc_2 // 1
==
assert
// tests/artifacts/Arrays/immutable.py:559
// assert a1[1] == a3[1]
dup
intc_0 // 8
extract_uint64
pushint 2 // 2
==
assert
// tests/artifacts/Arrays/immutable.py:560
// assert a1[2] == a3[2]
pushint 16 // 16
extract_uint64
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:548
// a1 = ReferenceArray((UInt64(1), UInt64(2), UInt64(3)))
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
bytec_0 // 0x000000000000000100000000000000020000000000000003
pop
// tests/artifacts/Arrays/immutable.py:563
// assert a1.length == a4.length
dup
len
intc_0 // 8
/
intc_1 // 3
==
assert
// tests/artifacts/Arrays/immutable.py:564
// assert a1[0] == a4[0]
dup
intc_3 // 0
extract_uint64
intc_2 // 1
==
assert
// tests/artifacts/Arrays/immutable.py:565
// assert a1[1] == a4[1]
dup
intc_0 // 8
extract_uint64
pushint 2 // 2
==
assert
// tests/artifacts/Arrays/immutable.py:566
// assert a1[2] == a4[2]
pushint 16 // 16
extract_uint64
intc_1 // 3
==
// tests/artifacts/Arrays/immutable.py:546
// @arc4.abimethod()
return
Loading