Skip to content

Commit c219098

Browse files
authored
Merge pull request #44 from algorandfoundation/feat/native-funcs
feat: add .as_uint64 and .as_biguint methods to replace native property
2 parents 85e0b0c + 0f9c6c0 commit c219098

File tree

102 files changed

+7492
-13479
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+7492
-13479
lines changed

examples/marketplace/contract.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def deposit(self, xfer: gtxn.AssetTransferTransaction, nonce: arc4.UInt64) -> No
130130
assert xfer.asset_amount > 0
131131

132132
self.listings[key].deposited = arc4.UInt64(
133-
self.listings[key].deposited.native + xfer.asset_amount
133+
self.listings[key].deposited.as_uint64() + xfer.asset_amount
134134
)
135135

136136
@abimethod
@@ -161,14 +161,14 @@ def buy(
161161
listing = self.listings[key].copy()
162162

163163
amount_to_be_paid = self.quantity_price(
164-
quantity, listing.unitary_price.native, asset.decimals
164+
quantity, listing.unitary_price.as_uint64(), asset.decimals
165165
)
166166

167167
assert buy_pay.sender == Txn.sender
168168
assert buy_pay.receiver.bytes == owner.bytes
169169
assert buy_pay.amount == amount_to_be_paid
170170

171-
self.listings[key].deposited = arc4.UInt64(listing.deposited.native - quantity)
171+
self.listings[key].deposited = arc4.UInt64(listing.deposited.as_uint64() - quantity)
172172

173173
itxn.AssetTransfer(
174174
xfer_asset=asset,
@@ -187,8 +187,8 @@ def withdraw(self, asset: Asset, nonce: arc4.UInt64) -> None:
187187
listing = self.listings[key].copy()
188188
if listing.bidder != arc4.Address():
189189
current_bid_deposit = self.quantity_price(
190-
listing.bid.native,
191-
listing.bid_unitary_price.native,
190+
listing.bid.as_uint64(),
191+
listing.bid_unitary_price.as_uint64(),
192192
asset.decimals,
193193
)
194194
itxn.Payment(receiver=listing.bidder.native, amount=current_bid_deposit).submit()
@@ -200,7 +200,7 @@ def withdraw(self, asset: Asset, nonce: arc4.UInt64) -> None:
200200
itxn.AssetTransfer(
201201
xfer_asset=asset,
202202
asset_receiver=Txn.sender,
203-
asset_amount=listing.deposited.native,
203+
asset_amount=listing.deposited.as_uint64(),
204204
).submit()
205205

206206
@abimethod
@@ -220,13 +220,13 @@ def bid( # noqa: PLR0913
220220
assert unitary_price > listing.bid_unitary_price
221221

222222
current_bid_amount = self.quantity_price(
223-
listing.bid.native, listing.bid_unitary_price.native, asset.decimals
223+
listing.bid.as_uint64(), listing.bid_unitary_price.as_uint64(), asset.decimals
224224
)
225225

226226
itxn.Payment(receiver=listing.bidder.native, amount=current_bid_amount).submit()
227227

228228
amount_to_be_bid = self.quantity_price(
229-
quantity.native, unitary_price.native, asset.decimals
229+
quantity.as_uint64(), unitary_price.as_uint64(), asset.decimals
230230
)
231231

232232
assert bid_pay.sender == Txn.sender
@@ -245,12 +245,12 @@ def accept_bid(self, asset: Asset, nonce: arc4.UInt64) -> None:
245245
assert listing.bidder != arc4.Address()
246246

247247
min_quantity = (
248-
listing.deposited.native
249-
if listing.deposited.native < listing.bid.native
250-
else listing.bid.native
248+
listing.deposited.as_uint64()
249+
if listing.deposited.as_uint64() < listing.bid.as_uint64()
250+
else listing.bid.as_uint64()
251251
)
252252
best_bid_amount = self.quantity_price(
253-
min_quantity, listing.bid_unitary_price.native, asset.decimals
253+
min_quantity, listing.bid_unitary_price.as_uint64(), asset.decimals
254254
)
255255

256256
itxn.Payment(receiver=Txn.sender, amount=best_bid_amount).submit()
@@ -262,6 +262,6 @@ def accept_bid(self, asset: Asset, nonce: arc4.UInt64) -> None:
262262
).submit()
263263

264264
self.listings[key].deposited = arc4.UInt64(
265-
self.listings[key].deposited.native - min_quantity
265+
self.listings[key].deposited.as_uint64() - min_quantity
266266
)
267-
self.listings[key].bid = arc4.UInt64(self.listings[key].bid.native - min_quantity)
267+
self.listings[key].bid = arc4.UInt64(self.listings[key].bid.as_uint64() - min_quantity)

examples/marketplace/test_contract.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -162,19 +162,19 @@ def test_buy(
162162
buy_pay=context.any.txn.payment(
163163
receiver=context.default_sender,
164164
amount=contract.quantity_price(
165-
quantity=test_buy_quantity.native,
166-
price=test_unitary_price.native,
165+
quantity=test_buy_quantity.as_uint64(),
166+
price=test_unitary_price.as_uint64(),
167167
asset_decimals=test_asset.decimals,
168168
),
169169
),
170-
quantity=test_buy_quantity.native,
170+
quantity=test_buy_quantity.as_uint64(),
171171
)
172172

173173
# Assert
174174
updated_listing = ListingValue.from_bytes(
175175
context.ledger.get_box(contract, b"listings" + listing_key.bytes)
176176
)
177-
assert updated_listing.deposited == initial_deposit.native - test_buy_quantity.native
177+
assert updated_listing.deposited == initial_deposit.as_uint64() - test_buy_quantity.as_uint64()
178178
assert (
179179
context.txn.last_group.get_itxn_group(0).asset_transfer(0).asset_receiver
180180
== context.default_sender
@@ -215,7 +215,7 @@ def test_withdraw(
215215
asset_transfer_txn = context.txn.last_group.get_itxn_group(1).asset_transfer(0)
216216
assert asset_transfer_txn.xfer_asset == test_asset
217217
assert asset_transfer_txn.asset_receiver == test_owner.native
218-
assert asset_transfer_txn.asset_amount == initial_deposit.native
218+
assert asset_transfer_txn.asset_amount == initial_deposit.as_uint64()
219219

220220

221221
def test_bid(
@@ -240,12 +240,12 @@ def test_bid(
240240
)
241241

242242
bidder = context.any.account()
243-
bid_quantity = context.any.arc4.uint64(max_value=int(initial_deposit.native))
243+
bid_quantity = context.any.arc4.uint64(max_value=int(initial_deposit.as_uint64()))
244244
bid_price = context.any.arc4.uint64(
245-
min_value=int(initial_price.native) + 1, max_value=int(10e6)
245+
min_value=int(initial_price.as_uint64()) + 1, max_value=int(10e6)
246246
)
247247
bid_amount = contract.quantity_price(
248-
bid_quantity.native, bid_price.native, test_asset.decimals
248+
bid_quantity.as_uint64(), bid_price.as_uint64(), test_asset.decimals
249249
)
250250

251251
# Act
@@ -277,7 +277,7 @@ def test_accept_bid(
277277
# Arrange
278278
owner = context.default_sender
279279
initial_deposit = context.any.arc4.uint64(min_value=1, max_value=int(1e6))
280-
bid_quantity = context.any.arc4.uint64(max_value=int(initial_deposit.native))
280+
bid_quantity = context.any.arc4.uint64(max_value=int(initial_deposit.as_uint64()))
281281
bid_price = context.any.arc4.uint64(max_value=int(10e6))
282282
bidder = context.any.account()
283283

@@ -294,10 +294,10 @@ def test_accept_bid(
294294
bid_unitary_price=bid_price,
295295
)
296296

297-
min_quantity = min(initial_deposit.native, bid_quantity.native)
297+
min_quantity = min(initial_deposit.as_uint64(), bid_quantity.as_uint64())
298298
expected_payment = contract.quantity_price(
299299
min_quantity,
300-
bid_price.native,
300+
bid_price.as_uint64(),
301301
asset_decimals=test_asset.decimals,
302302
)
303303

@@ -306,7 +306,7 @@ def test_accept_bid(
306306

307307
# Assert
308308
updated_listing = contract.listings[listing_key]
309-
assert updated_listing.deposited == initial_deposit.native - min_quantity
309+
assert updated_listing.deposited == initial_deposit.as_uint64() - min_quantity
310310

311311
assert len(context.txn.last_group.itxn_groups) == 2
312312

pyproject.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dependencies = [
3232
"coincurve>=19.0.1",
3333
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
3434
# "algorand-python>=3",
35-
"algorand-python@git+https://github.com/algorandfoundation/[email protected].6#subdirectory=stubs",
35+
"algorand-python@git+https://github.com/algorandfoundation/[email protected].7#subdirectory=stubs",
3636
]
3737

3838
[project.urls]
@@ -54,7 +54,7 @@ python = "3.12"
5454
dependencies = [
5555
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
5656
# "puyapy>=5",
57-
"puyapy@git+https://github.com/algorandfoundation/[email protected].6",
57+
"puyapy@git+https://github.com/algorandfoundation/[email protected].7",
5858
"pytest>=7.4",
5959
"pytest-mock>=3.10.0",
6060
"pytest-xdist[psutil]>=3.3",
@@ -138,7 +138,7 @@ dependencies = [
138138
"algokit-utils>=3.0.0",
139139
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
140140
# "puyapy>=5",
141-
"puyapy@git+https://github.com/algorandfoundation/[email protected].6",
141+
"puyapy@git+https://github.com/algorandfoundation/[email protected].7",
142142
]
143143

144144
[tool.hatch.envs.test.scripts]
@@ -191,7 +191,7 @@ post-install-commands = [
191191
dependencies = [
192192
# TODO: uncomment below and remove direct git reference once puya 5.0 is released
193193
# "algorand-python>=3",
194-
"algorand-python@git+https://github.com/algorandfoundation/[email protected].6#subdirectory=stubs",
194+
"algorand-python@git+https://github.com/algorandfoundation/[email protected].7#subdirectory=stubs",
195195
"pytest>=7.4",
196196
"pytest-mock>=3.10.0",
197197
"pytest-xdist[psutil]>=3.3",

src/_algopy_testing/arc4.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import algosdk
1010
from Cryptodome.Hash import SHA512
11+
from typing_extensions import deprecated
1112

1213
from _algopy_testing.constants import (
1314
ARC4_RETURN_PREFIX,
@@ -313,31 +314,44 @@ class UIntN(_UIntN, typing.Generic[_TBitSize]): # type: ignore[type-arg]
313314
"""
314315

315316
@property
317+
@deprecated("Use `as_uint64` instead")
316318
def native(self) -> algopy.UInt64:
317319
"""Return the UInt64 representation of the value after ARC4 decoding."""
318320
import algopy
319321

320322
return algopy.UInt64(int.from_bytes(self._value))
321323

324+
def as_uint64(self) -> algopy.UInt64:
325+
"""Return the UInt64 representation of the value after ARC4 decoding."""
326+
import algopy
327+
328+
return algopy.UInt64(int.from_bytes(self._value))
329+
330+
def as_biguint(self) -> algopy.BigUInt:
331+
"""Return the BigUInt representation of the value after ARC4 decoding."""
332+
import algopy
333+
334+
return algopy.BigUInt.from_bytes(self._value)
335+
322336
def __eq__(self, other: object) -> bool:
323337
try:
324338
other_int = as_int64(other)
325339
except (TypeError, ValueError):
326340
return NotImplemented
327-
return as_int64(self.native) == other_int
341+
return as_int64(self.as_uint64()) == other_int
328342

329343
def __lt__(self, other: object) -> bool:
330344
try:
331345
other_int = as_int64(other)
332346
except (TypeError, ValueError):
333347
return NotImplemented
334-
return as_int64(self.native) < other_int
348+
return as_int64(self.as_uint64()) < other_int
335349

336350
def __bool__(self) -> bool:
337-
return bool(self.native)
351+
return bool(self.as_uint64())
338352

339353
def __str__(self) -> str:
340-
return str(self.native)
354+
return str(self.as_uint64())
341355

342356
def __repr__(self) -> str:
343357
return _arc4_repr(self)
@@ -351,31 +365,47 @@ class BigUIntN(_UIntN, typing.Generic[_TBitSize]): # type: ignore[type-arg]
351365
"""
352366

353367
@property
368+
@deprecated("Use `as_biguint` instead")
354369
def native(self) -> algopy.BigUInt:
370+
"""Return the BigUInt representation of the value after ARC4 decoding."""
371+
import algopy
372+
373+
return algopy.BigUInt.from_bytes(self._value)
374+
375+
def as_uint64(self) -> algopy.UInt64:
355376
"""Return the UInt64 representation of the value after ARC4 decoding."""
356377
import algopy
357378

379+
biguint = algopy.BigUInt.from_bytes(self._value)
380+
if biguint.value > MAX_UINT64:
381+
raise OverflowError("value too large to fit in UInt64")
382+
return algopy.UInt64(biguint.value)
383+
384+
def as_biguint(self) -> algopy.BigUInt:
385+
"""Return the BigUInt representation of the value after ARC4 decoding."""
386+
import algopy
387+
358388
return algopy.BigUInt.from_bytes(self._value)
359389

360390
def __eq__(self, other: object) -> bool:
361391
try:
362392
other_int = as_int512(other)
363393
except (TypeError, ValueError):
364394
return NotImplemented
365-
return as_int512(self.native) == other_int
395+
return as_int512(self.as_biguint()) == other_int
366396

367397
def __lt__(self, other: object) -> bool:
368398
try:
369399
other_int = as_int512(other)
370400
except (TypeError, ValueError):
371401
return NotImplemented
372-
return as_int512(self.native) < other_int
402+
return as_int512(self.as_biguint()) < other_int
373403

374404
def __bool__(self) -> bool:
375-
return bool(self.native)
405+
return bool(self.as_biguint())
376406

377407
def __str__(self) -> str:
378-
return str(self.native)
408+
return str(self.as_biguint())
379409

380410
def __repr__(self) -> str:
381411
return _arc4_repr(self)
@@ -959,7 +989,7 @@ def __init__(self, *value: algopy.Bytes | bytes | Byte | UInt8 | int):
959989
raise ValueError("expected single Bytes value")
960990
items.extend([Byte(b) for b in as_bytes(x)])
961991
case UIntN(_type_info=_UIntTypeInfo(bit_size=8)) as uint:
962-
items.append(Byte(as_int(uint.native, max=2**8)))
992+
items.append(Byte(as_int(uint.as_uint64(), max=2**8)))
963993
case int(int_value):
964994
items.append(Byte(int_value))
965995
case _:

src/_algopy_testing/op/pure.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def extract_uint64(a: Bytes | bytes, b: UInt64 | int, /) -> UInt64:
109109
return UInt64(result_int)
110110

111111

112-
def getbit(a: Bytes | UInt64 | bytes | int, b: UInt64 | int, /) -> UInt64:
112+
def getbit(a: Bytes | UInt64 | bytes | int, b: UInt64 | int, /) -> bool:
113113
if isinstance(a, Bytes | bytes):
114114
return _getbit_bytes(a, b)
115115
if isinstance(a, UInt64 | int):
@@ -162,11 +162,11 @@ def select_uint64(a: UInt64 | int, b: UInt64 | int, c: bool | UInt64 | int, /) -
162162
return UInt64(b if c != 0 else a)
163163

164164

165-
def setbit_bytes(a: Bytes | bytes, b: UInt64 | int, c: UInt64 | int, /) -> Bytes:
165+
def setbit_bytes(a: Bytes | bytes, b: UInt64 | int, c: bool, /) -> Bytes: # noqa: FBT001
166166
return _setbit_bytes(a, b, c)
167167

168168

169-
def setbit_uint64(a: UInt64 | int, b: UInt64 | int, c: UInt64 | int, /) -> UInt64:
169+
def setbit_uint64(a: UInt64 | int, b: UInt64 | int, c: bool, /) -> UInt64: # noqa: FBT001
170170
a_bytes = _uint64_to_bytes(a)
171171
result = _setbit_bytes(a_bytes, b, c, "little")
172172
return UInt64(int.from_bytes(result.value))
@@ -241,7 +241,7 @@ def _int_list_to_bytes(a: list[int]) -> bytes:
241241

242242
def _getbit_bytes(
243243
a: Bytes | bytes, b: UInt64 | int, byteorder: typing.Literal["little", "big"] = "big"
244-
) -> UInt64:
244+
) -> bool:
245245
a = as_bytes(a)
246246
if byteorder != "big": # reverse bytes if NOT big endian
247247
a = bytes(reversed(a))
@@ -256,13 +256,13 @@ def _getbit_bytes(
256256
bit_index = 7 - bit_index
257257
bit = _get_bit(int_list[byte_index], bit_index)
258258

259-
return UInt64(bit)
259+
return bit != 0
260260

261261

262262
def _setbit_bytes(
263263
a: Bytes | bytes,
264264
b: UInt64 | int,
265-
c: UInt64 | int,
265+
c: bool, # noqa: FBT001
266266
byteorder: typing.Literal["little", "big"] = "big",
267267
) -> Bytes:
268268
a = as_bytes(a)
@@ -272,7 +272,6 @@ def _setbit_bytes(
272272
int_list = list(a)
273273
max_index = len(int_list) * BITS_IN_BYTE - 1
274274
b = as_int(b, max=max_index)
275-
c = as_int(c, max=1)
276275

277276
byte_index = b // BITS_IN_BYTE
278277
bit_index = b % BITS_IN_BYTE
@@ -291,7 +290,7 @@ def _get_bit(v: int, index: int) -> int:
291290
return (v >> index) & 1
292291

293292

294-
def _set_bit(v: int, index: int, x: int) -> int:
293+
def _set_bit(v: int, index: int, x: bool) -> int: # noqa: FBT001
295294
"""Set the index:th bit of v to 1 if x is truthy, else to 0, and return the new
296295
value."""
297296
mask = 1 << index # Compute mask, an integer with just bit 'index' set.

src/_algopy_testing/serialize.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ def get_native_to_arc4_serializer( # noqa: PLR0911
5050
return _Serializer(
5151
arc4_type=simple_arc4_type,
5252
native_to_arc4=simple_arc4_type,
53-
arc4_to_native=lambda n: n.native,
53+
arc4_to_native=lambda n: (
54+
n.as_uint64()
55+
if isinstance(n, arc4.UIntN)
56+
else n.as_biguint() if isinstance(n, arc4.BigUIntN) else n.native
57+
),
5458
)
5559
if issubclass(typ, UInt64Backed):
5660
return _Serializer(

0 commit comments

Comments
 (0)