diff --git a/beaker/application.py b/beaker/application.py index ad3cbd0e..78350ea0 100644 --- a/beaker/application.py +++ b/beaker/application.py @@ -103,10 +103,10 @@ def __init__( all_deletes = [] all_opt_ins = [] all_close_outs = [] - all_clear_states = [] self.hints: dict[str, MethodHints] = {} self.bare_externals: dict[str, OnCompleteAction] = {} + self.bare_clear_state: Optional[HandlerFunc] = None self.methods: dict[str, tuple[ABIReturnSubroutine, Optional[MethodConfig]]] = {} self.precompiles: dict[str, AppPrecompile | LSigPrecompile] = {} @@ -189,6 +189,14 @@ def __init__( self.bare_externals[oc] = action + # Clear state + elif handler_config.clear_state is not None: + if self.bare_clear_state is not None: + raise BareOverwriteError("clear_state") + if handler_config.referenced_self: + handler_config.clear_state.subroutine.implementation = bound_attr + self.bare_clear_state = static_attr + # ABI externals elif handler_config.method_spec is not None and not handler_config.internal: # Create the ABIReturnSubroutine from the static attr @@ -210,8 +218,6 @@ def __init__( all_deletes.append(static_attr) if handler_config.is_opt_in(): all_opt_ins.append(static_attr) - if handler_config.is_clear_state(): - all_clear_states.append(static_attr) if handler_config.is_close_out(): all_close_outs.append(static_attr) @@ -229,13 +235,20 @@ def __init__( handler_config.subroutine(static_attr), ) - self.on_create = all_creates.pop() if len(all_creates) == 1 else None - self.on_update = all_updates.pop() if len(all_updates) == 1 else None - self.on_delete = all_deletes.pop() if len(all_deletes) == 1 else None - self.on_opt_in = all_opt_ins.pop() if len(all_opt_ins) == 1 else None - self.on_close_out = all_close_outs.pop() if len(all_close_outs) == 1 else None - self.on_clear_state = ( - all_clear_states.pop() if len(all_clear_states) == 1 else None + self.on_create: Optional[HandlerFunc] = ( + all_creates.pop() if len(all_creates) == 1 else None + ) + self.on_update: Optional[HandlerFunc] = ( + all_updates.pop() if len(all_updates) == 1 else None + ) + self.on_delete: Optional[HandlerFunc] = ( + all_deletes.pop() if len(all_deletes) == 1 else None + ) + self.on_opt_in: Optional[HandlerFunc] = ( + all_opt_ins.pop() if len(all_opt_ins) == 1 else None + ) + self.on_close_out: Optional[HandlerFunc] = ( + all_close_outs.pop() if len(all_close_outs) == 1 else None ) self.acct_state = AccountState(acct_vals) @@ -264,10 +277,16 @@ def compile(self, client: Optional[AlgodClient] = None) -> tuple[str, str]: for precompile in self.precompiles.values(): precompile.compile(client) # type: ignore + cs_ast = ( + get_handler_config(self.bare_clear_state).clear_state + if self.bare_clear_state + else None + ) self.router = Router( name=self.__class__.__name__, bare_calls=BareCallActions(**self.bare_externals), descr=self.__doc__, + clear_state=cs_ast, ) # Add method externals diff --git a/beaker/client/application_client.py b/beaker/client/application_client.py index 2f4370c5..14ff0ec8 100644 --- a/beaker/client/application_client.py +++ b/beaker/client/application_client.py @@ -324,31 +324,18 @@ def clear_state( sender = self.get_sender(sender, signer) atc = AtomicTransactionComposer() - if self.app.on_clear_state is not None: - self.add_method_call( - atc, - self.app.on_clear_state, - on_complete=transaction.OnComplete.ClearStateOC, - sender=sender, - suggested_params=sp, - index=self.app_id, - app_args=args, + atc.add_transaction( + TransactionWithSigner( + txn=transaction.ApplicationClearStateTxn( + sender=sender, + sp=sp, + index=self.app_id, + app_args=args, + **kwargs, + ), signer=signer, - **kwargs, - ) - else: - atc.add_transaction( - TransactionWithSigner( - txn=transaction.ApplicationClearStateTxn( - sender=sender, - sp=sp, - index=self.app_id, - app_args=args, - **kwargs, - ), - signer=signer, - ) ) + ) clear_state_result = atc.execute(self.client, 4) diff --git a/beaker/decorators.py b/beaker/decorators.py index 7f57eb6d..9b18103c 100644 --- a/beaker/decorators.py +++ b/beaker/decorators.py @@ -130,6 +130,8 @@ class HandlerConfig: read_only: bool = field(kw_only=True, default=False) internal: bool = field(kw_only=True, default=False) + clear_state: Optional[SubroutineFnWrapper] = field(kw_only=True, default=None) + def hints(self) -> "MethodHints": mh: dict[str, Any] = {"read_only": self.read_only} @@ -185,10 +187,7 @@ def is_opt_in(self) -> bool: ) def is_clear_state(self) -> bool: - return ( - self.method_config is not None - and self.method_config.clear_state != CallConfig.NEVER - ) + return self.clear_state is not None def is_close_out(self) -> bool: return ( @@ -530,7 +529,6 @@ def _impl(fn: HandlerFunc) -> HandlerFunc: def bare_external( no_op: CallConfig | None = None, opt_in: CallConfig | None = None, - clear_state: CallConfig | None = None, delete_application: CallConfig | None = None, update_application: CallConfig | None = None, close_out: CallConfig | None = None, @@ -540,7 +538,6 @@ def bare_external( Args: no_op: CallConfig to handle a `NoOp` opt_in: CallConfig to handle an `OptIn` - clear_state: CallConfig to handle a `ClearState` delete_application: CallConfig to handle a `DeleteApplication` update_application: CallConfig to handle a `UpdateApplication` close_out: CallConfig to handle a `CloseOut` @@ -574,9 +571,6 @@ def _impl(fun: HandlerFunc) -> HandlerFunc: close_out=OnCompleteAction(action=fn, call_config=close_out) if close_out is not None else OnCompleteAction.never(), - clear_state=OnCompleteAction(action=fn, call_config=clear_state) - if clear_state is not None - else OnCompleteAction.never(), ) set_handler_config(fun, bare_method=bca) @@ -789,42 +783,36 @@ def _impl(fn: HandlerFunc) -> HandlerFunc: @overload -def clear_state( - fn: HandlerFunc, /, *, authorize: SubroutineFnWrapper | None = None -) -> HandlerFunc: +def clear_state(fn: HandlerFunc, /) -> HandlerFunc: ... @overload -def clear_state(*, authorize: SubroutineFnWrapper | None = None) -> DecoratorFunc: +def clear_state() -> DecoratorFunc: ... -def clear_state( - fn: HandlerFunc | None = None, /, *, authorize: SubroutineFnWrapper | None = None -) -> HandlerFunc | DecoratorFunc: +def clear_state(fn: HandlerFunc | None = None, /) -> HandlerFunc | DecoratorFunc: """set method to be handled by an application call with it'ws :code:`OnComplete` set to :code:`ClearState` call Args: fn: The method to be wrapped. - authorize: a subroutine with input of ``Txn.sender()`` and output uint64 - interpreted as allowed if the output>0. Returns: The original method with changes made to its signature and attributes set in it's :code:`__handler_config__` """ - def _impl(fn: HandlerFunc) -> HandlerFunc: - if is_bare(fn): - if authorize is not None: - fn = _authorize(authorize)(fn) - return bare_external(clear_state=CallConfig.CALL)(fn) + def _impl(fun: HandlerFunc) -> HandlerFunc: + if is_bare(fun): + fun = _remove_self(fun) + fn = Subroutine(TealType.none)(fun) + set_handler_config(fun, clear_state=fn) + return fun else: - return external( - method_config=MethodConfig(clear_state=CallConfig.CALL), - authorize=authorize, - )(fn) + raise ValueError( + "clear_state cannot be expected to receive any arguments during runtime" + ) if fn is None: return _impl diff --git a/examples/amm/amm.py b/examples/amm/amm.py index c279d736..f1d52d63 100644 --- a/examples/amm/amm.py +++ b/examples/amm/amm.py @@ -37,7 +37,7 @@ # WARNING: This code is provided for example only. Do NOT deploy to mainnet. -pragma(compiler_version="^0.21.0") +pragma(compiler_version="^0.22.0") def commented_assert(conditions: list[tuple[Expr, str]]) -> list[Expr]: diff --git a/poetry.lock b/poetry.lock index 5928e041..6e7e3cfe 100644 --- a/poetry.lock +++ b/poetry.lock @@ -154,14 +154,14 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "bleach" -version = "5.0.1" +version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, - {file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, + {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, + {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, ] [package.dependencies] @@ -170,7 +170,6 @@ webencodings = "*" [package.extras] css = ["tinycss2 (>=1.1.0,<1.2)"] -dev = ["Sphinx (==4.3.2)", "black (==22.3.0)", "build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "mypy (==0.961)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)"] [[package]] name = "cachecontrol" @@ -523,63 +522,63 @@ test-no-images = ["pytest"] [[package]] name = "coverage" -version = "7.0.5" +version = "7.1.0" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "coverage-7.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a7f23bbaeb2a87f90f607730b45564076d870f1fb07b9318d0c21f36871932b"}, - {file = "coverage-7.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c18d47f314b950dbf24a41787ced1474e01ca816011925976d90a88b27c22b89"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef14d75d86f104f03dea66c13188487151760ef25dd6b2dbd541885185f05f40"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66e50680e888840c0995f2ad766e726ce71ca682e3c5f4eee82272c7671d38a2"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9fed35ca8c6e946e877893bbac022e8563b94404a605af1d1e6accc7eb73289"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d8d04e755934195bdc1db45ba9e040b8d20d046d04d6d77e71b3b34a8cc002d0"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e109f1c9a3ece676597831874126555997c48f62bddbcace6ed17be3e372de8"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0a1890fca2962c4f1ad16551d660b46ea77291fba2cc21c024cd527b9d9c8809"}, - {file = "coverage-7.0.5-cp310-cp310-win32.whl", hash = "sha256:be9fcf32c010da0ba40bf4ee01889d6c737658f4ddff160bd7eb9cac8f094b21"}, - {file = "coverage-7.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:cbfcba14a3225b055a28b3199c3d81cd0ab37d2353ffd7f6fd64844cebab31ad"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30b5fec1d34cc932c1bc04017b538ce16bf84e239378b8f75220478645d11fca"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1caed2367b32cc80a2b7f58a9f46658218a19c6cfe5bc234021966dc3daa01f0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d254666d29540a72d17cc0175746cfb03d5123db33e67d1020e42dae611dc196"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19245c249aa711d954623d94f23cc94c0fd65865661f20b7781210cb97c471c0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b05ed4b35bf6ee790832f68932baf1f00caa32283d66cc4d455c9e9d115aafc"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:29de916ba1099ba2aab76aca101580006adfac5646de9b7c010a0f13867cba45"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e057e74e53db78122a3979f908973e171909a58ac20df05c33998d52e6d35757"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:411d4ff9d041be08fdfc02adf62e89c735b9468f6d8f6427f8a14b6bb0a85095"}, - {file = "coverage-7.0.5-cp311-cp311-win32.whl", hash = "sha256:52ab14b9e09ce052237dfe12d6892dd39b0401690856bcfe75d5baba4bfe2831"}, - {file = "coverage-7.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:1f66862d3a41674ebd8d1a7b6f5387fe5ce353f8719040a986551a545d7d83ea"}, - {file = "coverage-7.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b69522b168a6b64edf0c33ba53eac491c0a8f5cc94fa4337f9c6f4c8f2f5296c"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436e103950d05b7d7f55e39beeb4d5be298ca3e119e0589c0227e6d0b01ee8c7"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c56bec53d6e3154eaff6ea941226e7bd7cc0d99f9b3756c2520fc7a94e6d96"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a38362528a9115a4e276e65eeabf67dcfaf57698e17ae388599568a78dcb029"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f67472c09a0c7486e27f3275f617c964d25e35727af952869dd496b9b5b7f6a3"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:220e3fa77d14c8a507b2d951e463b57a1f7810a6443a26f9b7591ef39047b1b2"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ecb0f73954892f98611e183f50acdc9e21a4653f294dfbe079da73c6378a6f47"}, - {file = "coverage-7.0.5-cp37-cp37m-win32.whl", hash = "sha256:d8f3e2e0a1d6777e58e834fd5a04657f66affa615dae61dd67c35d1568c38882"}, - {file = "coverage-7.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9e662e6fc4f513b79da5d10a23edd2b87685815b337b1a30cd11307a6679148d"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:790e4433962c9f454e213b21b0fd4b42310ade9c077e8edcb5113db0818450cb"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49640bda9bda35b057b0e65b7c43ba706fa2335c9a9896652aebe0fa399e80e6"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d66187792bfe56f8c18ba986a0e4ae44856b1c645336bd2c776e3386da91e1dd"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:276f4cd0001cd83b00817c8db76730938b1ee40f4993b6a905f40a7278103b3a"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95304068686545aa368b35dfda1cdfbbdbe2f6fe43de4a2e9baa8ebd71be46e2"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:17e01dd8666c445025c29684d4aabf5a90dc6ef1ab25328aa52bedaa95b65ad7"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea76dbcad0b7b0deb265d8c36e0801abcddf6cc1395940a24e3595288b405ca0"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:50a6adc2be8edd7ee67d1abc3cd20678987c7b9d79cd265de55941e3d0d56499"}, - {file = "coverage-7.0.5-cp38-cp38-win32.whl", hash = "sha256:e4ce984133b888cc3a46867c8b4372c7dee9cee300335e2925e197bcd45b9e16"}, - {file = "coverage-7.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:4a950f83fd3f9bca23b77442f3a2b2ea4ac900944d8af9993743774c4fdc57af"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c2155943896ac78b9b0fd910fb381186d0c345911f5333ee46ac44c8f0e43ab"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54f7e9705e14b2c9f6abdeb127c390f679f6dbe64ba732788d3015f7f76ef637"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee30375b409d9a7ea0f30c50645d436b6f5dfee254edffd27e45a980ad2c7f4"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b78729038abea6a5df0d2708dce21e82073463b2d79d10884d7d591e0f385ded"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13250b1f0bd023e0c9f11838bdeb60214dd5b6aaf8e8d2f110c7e232a1bff83b"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c407b1950b2d2ffa091f4e225ca19a66a9bd81222f27c56bd12658fc5ca1209"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c76a3075e96b9c9ff00df8b5f7f560f5634dffd1658bafb79eb2682867e94f78"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f26648e1b3b03b6022b48a9b910d0ae209e2d51f50441db5dce5b530fad6d9b1"}, - {file = "coverage-7.0.5-cp39-cp39-win32.whl", hash = "sha256:ba3027deb7abf02859aca49c865ece538aee56dcb4871b4cced23ba4d5088904"}, - {file = "coverage-7.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:949844af60ee96a376aac1ded2a27e134b8c8d35cc006a52903fc06c24a3296f"}, - {file = "coverage-7.0.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:b9727ac4f5cf2cbf87880a63870b5b9730a8ae3a4a360241a0fdaa2f71240ff0"}, - {file = "coverage-7.0.5.tar.gz", hash = "sha256:051afcbd6d2ac39298d62d340f94dbb6a1f31de06dfaf6fcef7b759dd3860c45"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c"}, + {file = "coverage-7.1.0-cp310-cp310-win32.whl", hash = "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352"}, + {file = "coverage-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e"}, + {file = "coverage-7.1.0-cp311-cp311-win32.whl", hash = "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7"}, + {file = "coverage-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c"}, + {file = "coverage-7.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3"}, + {file = "coverage-7.1.0-cp37-cp37m-win32.whl", hash = "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73"}, + {file = "coverage-7.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0"}, + {file = "coverage-7.1.0-cp38-cp38-win32.whl", hash = "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab"}, + {file = "coverage-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c"}, + {file = "coverage-7.1.0-cp39-cp39-win32.whl", hash = "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4"}, + {file = "coverage-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3"}, + {file = "coverage-7.1.0-pp37.pp38.pp39-none-any.whl", hash = "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda"}, + {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"}, ] [package.dependencies] @@ -853,14 +852,14 @@ lxml = ["lxml"] [[package]] name = "identify" -version = "2.5.13" +version = "2.5.15" description = "File identification library for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "identify-2.5.13-py2.py3-none-any.whl", hash = "sha256:8aa48ce56e38c28b6faa9f261075dea0a942dfbb42b341b4e711896cbb40f3f7"}, - {file = "identify-2.5.13.tar.gz", hash = "sha256:abb546bca6f470228785338a01b539de8a85bbf46491250ae03363956d8ebb10"}, + {file = "identify-2.5.15-py2.py3-none-any.whl", hash = "sha256:1f4b36c5f50f3f950864b2a047308743f064eaa6f6645da5e5c780d1c7125487"}, + {file = "identify-2.5.15.tar.gz", hash = "sha256:c22aa206f47cc40486ecf585d27ad5f40adbfc494a3fa41dc3ed0499a23b123f"}, ] [package.extras] @@ -1247,6 +1246,7 @@ packaging = ">=20.0" pillow = ">=6.2.0" pyparsing = ">=2.2.1" python-dateutil = ">=2.7" +setuptools_scm = ">=7" [[package]] name = "mccabe" @@ -1576,14 +1576,14 @@ files = [ [[package]] name = "pathspec" -version = "0.10.3" +version = "0.11.0" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, - {file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, + {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, + {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, ] [[package]] @@ -1699,14 +1699,14 @@ pip = "*" [[package]] name = "pip-audit" -version = "2.4.13" +version = "2.4.14" description = "A tool for scanning Python environments for known vulnerabilities" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pip_audit-2.4.13-py3-none-any.whl", hash = "sha256:3ea2fc5c70bf335362d4d81a7bd1084787efac34929e422f79bd8cf8804da2e2"}, - {file = "pip_audit-2.4.13.tar.gz", hash = "sha256:e0c9fe070a16aefdbb9c4d43df6a0183bc951375a293f58264c5e80b5edb57d7"}, + {file = "pip_audit-2.4.14-py3-none-any.whl", hash = "sha256:f9632b9f67bcf3fda78ef7651a03c8ed926d1eaeda474dcbdcb26a5518dd6ffc"}, + {file = "pip_audit-2.4.14.tar.gz", hash = "sha256:1259629fe24302e257052e977146f56bebf34927740d5efd184aaafa3b1b3b38"}, ] [package.dependencies] @@ -1721,8 +1721,9 @@ rich = ">=12.4" toml = ">=0.10" [package.extras] -dev = ["build", "bump (>=1.3.2)", "pip-audit[lint,test]"] -lint = ["black (>=22.3.0)", "interrogate", "isort", "mypy", "pdoc3", "ruff (<0.0.218)", "types-html5lib", "types-requests", "types-toml"] +dev = ["build", "bump (>=1.3.2)", "pip-audit[doc,lint,test]"] +doc = ["pdoc"] +lint = ["black (>=22.3.0)", "interrogate", "isort", "mypy", "ruff (<0.0.228)", "types-html5lib", "types-requests", "types-toml"] test = ["coverage[toml]", "pretend", "pytest", "pytest-cov"] [[package]] @@ -1939,7 +1940,7 @@ files = [ cffi = ">=1.4.1" [package.extras] -docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] +docs = ["sphinx (>=1.6.5)", "sphinx_rtd_theme"] tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] [[package]] @@ -1959,14 +1960,14 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pyteal" -version = "0.21.0" +version = "0.22.0" description = "Algorand Smart Contracts in Python" category = "main" optional = false python-versions = ">=3.10" files = [ - {file = "pyteal-0.21.0-py3-none-any.whl", hash = "sha256:5e5f2e4269848dab775ba68813914bd186059cf988b683ad3efa8a2df11ea4b9"}, - {file = "pyteal-0.21.0.tar.gz", hash = "sha256:405d3d605346caf6732f0104cf74f79304d61969e7aec3521baf89e80ab83509"}, + {file = "pyteal-0.22.0-py3-none-any.whl", hash = "sha256:d1fe6b6ffe6429fefacd766f02eb117075d2cb1385da443e3881dbd76a6a3cd4"}, + {file = "pyteal-0.22.0.tar.gz", hash = "sha256:308dab84bc9ea771bd38cecebb35affd48b19e163ee277e9ae9976a281ccaa4d"}, ] [package.dependencies] @@ -2313,14 +2314,14 @@ files = [ [[package]] name = "setuptools" -version = "66.0.0" +version = "66.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-66.0.0-py3-none-any.whl", hash = "sha256:a78d01d1e2c175c474884671dde039962c9d74c7223db7369771fcf6e29ceeab"}, - {file = "setuptools-66.0.0.tar.gz", hash = "sha256:bd6eb2d6722568de6d14b87c44a96fac54b2a45ff5e940e639979a3d1792adb6"}, + {file = "setuptools-66.1.1-py3-none-any.whl", hash = "sha256:6f590d76b713d5de4e49fe4fbca24474469f53c83632d5d0fd056f7ff7e8112b"}, + {file = "setuptools-66.1.1.tar.gz", hash = "sha256:ac4008d396bc9cd983ea483cb7139c0240a07bbc74ffb6232fceffedc6cf03a8"}, ] [package.extras] @@ -2328,6 +2329,28 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "setuptools-scm" +version = "7.1.0" +description = "the blessed package to manage your versions by scm tags" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools_scm-7.1.0-py3-none-any.whl", hash = "sha256:73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e"}, + {file = "setuptools_scm-7.1.0.tar.gz", hash = "sha256:6c508345a771aad7d56ebff0e70628bf2b0ec7573762be9960214730de278f27"}, +] + +[package.dependencies] +packaging = ">=20.0" +setuptools = "*" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +typing-extensions = "*" + +[package.extras] +test = ["pytest (>=6.2)", "virtualenv (>20)"] +toml = ["setuptools (>=42)"] + [[package]] name = "six" version = "1.16.0" @@ -2432,14 +2455,14 @@ dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"] [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.3" +version = "1.0.4" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "sphinxcontrib.applehelp-1.0.3-py3-none-any.whl", hash = "sha256:ba0f2a22e6eeada8da6428d0d520215ee8864253f32facf958cca81e426f661d"}, - {file = "sphinxcontrib.applehelp-1.0.3.tar.gz", hash = "sha256:83749f09f6ac843b8cb685277dbc818a8bf2d76cc19602699094fe9a74db529e"}, + {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, + {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, ] [package.extras] @@ -2790,4 +2813,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "1b7ab47ead0ed7199c5c18957e0de216183921aecd6f6dead168c356327eb800" +content-hash = "87da97639337afb9375c590b62f9c45988a594e8e6e366932f788ff313f92fef" diff --git a/pyproject.toml b/pyproject.toml index 59bf409d..25142c97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,7 @@ packages = [ [tool.poetry.dependencies] python = "^3.10" -pyteal = "~0.21.0" +pyteal = "~0.22.0" py-algorand-sdk = ">=2.0.0" [tool.poetry.group.dev.dependencies] diff --git a/tests/application_test.py b/tests/application_test.py index 3978fbff..fa4f8653 100644 --- a/tests/application_test.py +++ b/tests/application_test.py @@ -183,10 +183,6 @@ def opt_in(self, s: pt.abi.String): def close_out(self, s: pt.abi.String): return pt.Assert(pt.Len(s.get())) - @clear_state - def clear_state(self, s: pt.abi.String): - return pt.Assert(pt.Len(s.get())) - @update def update(self, s: pt.abi.String): return pt.Assert(pt.Len(s.get())) @@ -195,11 +191,15 @@ def update(self, s: pt.abi.String): def delete(self, s: pt.abi.String): return pt.Assert(pt.Len(s.get())) + @clear_state + def clear_state(self): + return pt.Assert(pt.Txn.application_args.length()) + be = BareExternal() assert len(be.bare_externals) == 0, "Should have no bare externals" assert ( - len(be.contract.methods) == 6 - ), "should have create, optin, closeout, clearstate, update, delete" + len(be.contract.methods) == 5 + ), "should have create, optin, closeout, update, delete" hc = get_handler_config(BareExternal.create) assert hc.method_config is not None @@ -222,13 +222,6 @@ def delete(self, s: pt.abi.String): del confs["close_out"] assert all([c == pt.CallConfig.NEVER for c in confs.values()]) - hc = get_handler_config(BareExternal.clear_state) - assert hc.method_config is not None - confs = asdict(hc.method_config) - assert confs["clear_state"] == pt.CallConfig.CALL - del confs["clear_state"] - assert all([c == pt.CallConfig.NEVER for c in confs.values()]) - hc = get_handler_config(BareExternal.update) assert hc.method_config is not None confs = asdict(hc.method_config) @@ -244,6 +237,33 @@ def delete(self, s: pt.abi.String): assert all([c == pt.CallConfig.NEVER for c in confs.values()]) +def test_clear_state_cannot_have_parameters(): + with pytest.raises( + ValueError, + match="clear_state cannot be expected to receive any arguments during runtime", + ): + + class ClearStateApp(Application): + @clear_state + def clear_state(self, s: pt.abi.String): + return pt.Assert(pt.Len(s.get())) + + +def test_clear_state_is_not_bare_nor_abi(): + class ClearStateApp(Application): + @create + def create(self, s: pt.abi.String): + return pt.Assert(pt.Len(s.get())) + + @clear_state + def clear_state(self): + return pt.Assert(pt.Txn.application_args.length()) + + csa = ClearStateApp() + assert len(csa.bare_externals) == 0 + assert len(csa.contract.methods) == 1 + + def test_subclass_application(): class SuperClass(Application): @external diff --git a/tests/client/application_client_test.py b/tests/client/application_client_test.py index 23b105cc..8f020179 100644 --- a/tests/client/application_client_test.py +++ b/tests/client/application_client_test.py @@ -65,7 +65,7 @@ def opt_in(self): @clear_state def clear_state(self): - return pt.Seq(pt.Assert(pt.Len(pt.Txn.note()) == pt.Int(0)), pt.Approve()) + return self.app_state_val_int.increment() @close_out def close_out(self): @@ -433,6 +433,7 @@ def test_clear_state(sb_accts: SandboxAccounts): new_ac = ac.prepare(signer=new_signer) new_ac.opt_in() + old_app_state = new_ac.get_application_state() tx_id = new_ac.clear_state() result_tx = client.pending_transaction_info(tx_id) expect_dict( @@ -448,6 +449,8 @@ def test_clear_state(sb_accts: SandboxAccounts): }, }, ) + new_app_state = new_ac.get_application_state() + assert new_app_state["app_state_val_int"] == old_app_state["app_state_val_int"] + 1 def test_call(sb_accts: SandboxAccounts): diff --git a/tests/decorators_test.py b/tests/decorators_test.py index eb88b853..7d29db2e 100644 --- a/tests/decorators_test.py +++ b/tests/decorators_test.py @@ -266,12 +266,15 @@ def impl(): hc = get_handler_config(impl) assert hc.bare_method.close_out.action.subroutine.implementation == impl + +def test_clear_state(): @clear_state def impl(): return pt.Assert(pt.Int(1)) hc = get_handler_config(impl) - assert hc.bare_method.clear_state.action.subroutine.implementation == impl + assert hc.method_config is None + assert hc.clear_state.subroutine.implementation == impl def test_resolvable():