Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/state_ops' into docs/improv…
Browse files Browse the repository at this point in the history
…ing-docs
  • Loading branch information
aorumbayev committed Aug 5, 2024
2 parents e29e6f5 + eaad3f5 commit d4980bb
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 15 deletions.
3 changes: 2 additions & 1 deletion examples/htlc_logicsig/test_signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def test_seller_receives_payment(context: AlgopyTestContext) -> None:
)

# Act
result = context.execute_logicsig(hashed_time_locked_lsig, lsig_args=[algopy.Bytes(b"secret")])
with context.scoped_lsig_args([algopy.Bytes(b"secret")]):
result = context.execute_logicsig(hashed_time_locked_lsig)

# Assert
assert result is True
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ detached = true
path = ".venv.lint"
dependencies = [
"black",
"ruff==0.4.2",
"ruff==0.5.6",
"ruff-lsp",
"docformatter",
]
Expand Down Expand Up @@ -240,6 +240,8 @@ ignore = [
"RET504",
"RET505", # stylistic choices for readability
"S101", # allow asserts
"C901", # allow >10 args in a method
"N805", # allow using `cls` as a firstparameter name
]
unfixable = [
"F841", # don't delete unused local variables automatically
Expand All @@ -248,6 +250,7 @@ unfixable = [
"src/**" = [
"PT", # no pytest rules
]
"src/algopy_testing/models/logicsig.py" = ["ARG002"]
"scripts/**/*.py" = ["T201"]
"scripts/refresh_test_artifacts.py" = ["S603"]
"scripts/validate_examples.py" = ["S603"]
Expand Down
4 changes: 2 additions & 2 deletions src/algopy_testing/arc4.py
Original file line number Diff line number Diff line change
Expand Up @@ -1237,7 +1237,7 @@ def emit_swapped(self, a: arc4.UInt64, b: arc4.UInt64) -> None:
)


def _cast_arg_as_arc4(arg: object) -> _TABIArg: # noqa: C901, PLR0911
def _cast_arg_as_arc4(arg: object) -> _TABIArg: # noqa: PLR0911
import algopy

if isinstance(arg, bool):
Expand Down Expand Up @@ -1440,7 +1440,7 @@ def _encode(
return values_length_bytes + b"".join(heads) + b"".join(tails)


def _decode( # noqa: PLR0912, C901
def _decode( # noqa: PLR0912
value: bytes, child_types: typing.Sequence[_TypeInfo]
) -> list[typing.Any]:
dynamic_segments: list[list[int]] = [] # Store the start and end of a dynamic element
Expand Down
56 changes: 53 additions & 3 deletions src/algopy_testing/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -1444,15 +1444,65 @@ def set_box(self, name: algopy.Bytes | bytes, content: algopy.Bytes | bytes) ->
content_bytes = content if isinstance(content, bytes) else content.value
self._boxes[name_bytes] = content_bytes

@contextmanager
def scoped_lsig_args(
self, lsig_args: Sequence[algopy.Bytes] | None = None
) -> Generator[None, None, None]:
"""Temporarily set the active logic signature arguments within a
context.
This context manager allows you to set logic signature arguments
for the duration of a specific block of code. When the context
is exited, the previous arguments are restored.
:param lsig_args: The logic signature arguments to set. If None,
an empty list will be used.
:type lsig_args: Sequence[algopy.Bytes] | None
:yield: None
:rtype: Generator[None, None, None]
"""
last_lsig_args = self._active_lsig_args
self._active_lsig_args = lsig_args or []
try:
yield
finally:
self._active_lsig_args = last_lsig_args

def execute_logicsig(
self, lsig: algopy.LogicSig, lsig_args: Sequence[algopy.Bytes] | None = None
self,
lsig: algopy.LogicSig,
) -> bool | algopy.UInt64:
self._active_lsig_args = lsig_args or []
# TODO: refine LogicSig class to handle injects into context
"""Execute a logic signature.
This method executes the given logic signature. If the logic
signature is not already in the context's list of logic
signatures, it adds it before execution.
:param lsig: The logic signature to execute.
:type lsig: algopy.LogicSig
:return: The result of executing the logic signature function.
:rtype: bool | algopy.UInt64
"""
if lsig not in self._lsigs:
self._lsigs[lsig] = lsig.func
return lsig.func()

def add_logicsig(self, lsig: algopy.LogicSig) -> None:
"""Add a logic signature to the context.
This method adds the given logic signature to the context's list of logic signatures.
:param lsig: The logic signature to add.
:type lsig: algopy.LogicSig
:return: None
:raises TypeError: If `lsig` is not an instance of `algopy.LogicSig`.
"""
if not isinstance(lsig, algopy_testing.LogicSig):
raise TypeError("lsig must be an instance of algopy.LogicSig")
if lsig in self._lsigs:
raise ValueError(f"Logic signature {lsig} already exists in the context!")
self._lsigs[lsig] = lsig.func

def clear_box(self, name: algopy.Bytes | bytes) -> bool:
"""Clear all data, including accounts, applications, assets, inner
transactions, transaction groups, and application logs.
Expand Down
2 changes: 1 addition & 1 deletion src/algopy_testing/utilities/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from algopy_testing.utils import int_to_bytes


def log( # noqa: C901
def log(
*args: UInt64 | Bytes | BytesBacked | str | bytes | int,
sep: Bytes | bytes | str = b"",
) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/algopy_testing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def is_instance(obj: object, class_or_tuple: type | UnionType) -> bool:
return isinstance(obj, class_or_tuple)


def abi_type_name_for_arg( # noqa: PLR0912, C901, PLR0911
def abi_type_name_for_arg( # noqa: PLR0912, PLR0911
*, arg: object, is_return_type: bool = False
) -> str:
"""Returns the ABI type name for the given argument.
Expand Down
8 changes: 2 additions & 6 deletions tests/artifacts/CryptoOps/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,13 @@ def verify_ed25519verify_bare(self, a: Bytes, b: Bytes, c: Bytes) -> arc4.Bool:
return arc4.Bool(result)

@arc4.abimethod()
def verify_ecdsa_verify_k1( # noqa: PLR0913
self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes
) -> bool:
def verify_ecdsa_verify_k1(self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes) -> bool:
ensure_budget(3000, OpUpFeeSource.GroupCredit)
result_k1 = op.ecdsa_verify(op.ECDSA.Secp256k1, a, b, c, d, e)
return result_k1

@arc4.abimethod()
def verify_ecdsa_verify_r1( # noqa: PLR0913
self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes
) -> bool:
def verify_ecdsa_verify_r1(self, a: Bytes, b: Bytes, c: Bytes, d: Bytes, e: Bytes) -> bool:
ensure_budget(3000, OpUpFeeSource.GroupCredit)
result_r1 = op.ecdsa_verify(op.ECDSA.Secp256r1, a, b, c, d, e)
return result_r1
Expand Down

0 comments on commit d4980bb

Please sign in to comment.