From bb50a5baa6e605fd2882dd9313c7a88239a8c09e Mon Sep 17 00:00:00 2001 From: Andrew Date: Sun, 22 Jan 2023 15:03:02 -0500 Subject: [PATCH 1/7] add nre instance to plugins --- src/nile/nre.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nile/nre.py b/src/nile/nre.py index 9db69481..1e67191e 100644 --- a/src/nile/nre.py +++ b/src/nile/nre.py @@ -1,5 +1,7 @@ """Nile runtime environment.""" +from functools import partial + from nile import deployments from nile.common import is_alias from nile.core.call_or_invoke import call_or_invoke @@ -19,7 +21,8 @@ def __init__(self, network="localhost"): """Construct NRE object.""" self.network = network for name, object in get_installed_plugins("nre").items(): - setattr(self, name, skip_click_exit(object)) + partial_obj = partial(object, nre=self) + setattr(self, name, skip_click_exit(partial_obj)) def compile(self, contracts, cairo_path=None): """Compile a list of contracts.""" From 9316931d571e594063f0763af02cbfedaa7196b1 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 23 Jan 2023 02:28:26 -0500 Subject: [PATCH 2/7] move standalone_mode to cli --- src/nile/cli.py | 7 ++++++- src/nile/core/plugins.py | 5 +---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/nile/cli.py b/src/nile/cli.py index 457c53bd..cb3fe019 100644 --- a/src/nile/cli.py +++ b/src/nile/cli.py @@ -38,7 +38,12 @@ def enable_stack_trace(f): """Enable stack trace swapping for commands.""" @click.pass_context - async def new_func(ctx, *args, **kwargs): + async def new_func(ctx, *args, standalone_mode=False, **kwargs): + """ + Add standalone_mode=False to enable command returns in NRE. + + See: https://click.palletsprojects.com/en/5.x/commands/?highlight=standalone_mode#command-return-values # noqa: E501 + """ if ctx.obj["STACK_TRACE"]: return await ctx.invoke(f, ctx.obj, *args, **kwargs) else: diff --git a/src/nile/core/plugins.py b/src/nile/core/plugins.py index f404249e..cb95c375 100644 --- a/src/nile/core/plugins.py +++ b/src/nile/core/plugins.py @@ -17,11 +17,8 @@ def skip_click_exit(func): @functools.wraps(func) def wrapper(*args, **kwargs): - # add standalone_mode=False to command execution - # this enables command returns - # more info: https://click.palletsprojects.com/en/5.x/commands/?highlight=standalone_mode#command-return-values # noqa: E501 try: - return func(*args, standalone_mode=False, **kwargs) + return func(*args, **kwargs) # click commands always raise a SystemExit # this avoid exiting the command execution in NRE except SystemExit: From 9daf6cb406936a7b3d3f42a9112f3039240debd5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 23 Jan 2023 02:29:36 -0500 Subject: [PATCH 3/7] set partial object with pos arg --- src/nile/nre.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nile/nre.py b/src/nile/nre.py index 1e67191e..932f3a38 100644 --- a/src/nile/nre.py +++ b/src/nile/nre.py @@ -21,7 +21,7 @@ def __init__(self, network="localhost"): """Construct NRE object.""" self.network = network for name, object in get_installed_plugins("nre").items(): - partial_obj = partial(object, nre=self) + partial_obj = partial(object, self) setattr(self, name, skip_click_exit(partial_obj)) def compile(self, contracts, cairo_path=None): From faa0cfa21e2ac356f1e14fcd1af2917ddedc74bb Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 23 Jan 2023 02:30:37 -0500 Subject: [PATCH 4/7] check for nre instance in plugin --- tests/test_nre.py | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/tests/test_nre.py b/tests/test_nre.py index e9f21bdf..e5a6ac37 100644 --- a/tests/test_nre.py +++ b/tests/test_nre.py @@ -6,28 +6,40 @@ from unittest.mock import patch -import click +import pytest from nile.nre import NileRuntimeEnvironment -def test_nre_loaded_plugins(): - @click.command() - def dummy(): - print("dummy_result") +def dummy(): + print("dummy_result") - @click.command() - @click.argument("a", type=int) - @click.argument("b", type=int) - def dummy_params(a, b): - return a + b - with patch( - "nile.nre.get_installed_plugins", - return_value={"dummy": dummy, "dummy_params": dummy_params}, - ): - nre = NileRuntimeEnvironment() - assert callable(nre.dummy) +def dummy_params(nre, a, b): + return a + b - nre_result = nre.dummy_params(["1", "2"]) + +def bad_params(a, b): + return a + b + + +@pytest.mark.parametrize( + "plugin_name_and_object, will_fail", + [ + ({"dummy": dummy, "dummy_params": dummy_params}, False), + ({"dummy": dummy, "dummy_params": bad_params}, True), + ], +) +@patch("nile.nre.get_installed_plugins") +def test_nre_loaded_plugins(mock_plugins, plugin_name_and_object, will_fail): + mock_plugins.return_value = plugin_name_and_object + nre = NileRuntimeEnvironment() + + assert callable(nre.dummy) + + if will_fail is True: + with pytest.raises(TypeError): + nre.dummy_params(1, 2) + else: + nre_result = nre.dummy_params(1, 2) assert 3 == nre_result From deb1c7b8b1b66cc397c3badbf43753a20faddd1a Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 23 Jan 2023 17:04:47 -0500 Subject: [PATCH 5/7] fix plugin test --- tests/core/test_plugins.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/core/test_plugins.py b/tests/core/test_plugins.py index 2981c6c2..825727cf 100644 --- a/tests/core/test_plugins.py +++ b/tests/core/test_plugins.py @@ -12,20 +12,17 @@ def test_skip_click_exit(): - @click.command() - @click.argument("a", type=int) - @click.argument("b", type=int) def dummy_method(a, b): return a + b decorated = skip_click_exit(dummy_method) - decorated_result = decorated(["1", "2"]) + decorated_result = decorated(1, 2) assert callable(decorated) assert decorated_result == 3 -def testget_installed_plugins(): +def test_get_installed_plugins(): class Dummy: value = "nile.core.plugins.get_installed_plugins" name = "get_installed_plugins" From 10db43e47b24891dce1a19af22b986b5798a1799 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 23 Jan 2023 18:20:34 -0500 Subject: [PATCH 6/7] add function sig note to plugin section --- docs/modules/ROOT/pages/create_plugin.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/modules/ROOT/pages/create_plugin.adoc b/docs/modules/ROOT/pages/create_plugin.adoc index e09d2f94..5c5be79a 100644 --- a/docs/modules/ROOT/pages/create_plugin.adoc +++ b/docs/modules/ROOT/pages/create_plugin.adoc @@ -44,6 +44,8 @@ def greet(): [tool.poetry.plugins."nile_plugins.nre"] "greet" = "nile_greet.nre.greet" ---- +NOTE: Before specifying plugin entry points for the NRE, be sure to set the first parameter of the functon signature as a class instance i.e. `self`. +This allows the plugin function to access the NRE instance. + . Done! To better understand python entry points through setuptools, https://setuptools.pypa.io/en/latest/userguide/entry_point.html#entry-points-for-plugins[check this documentation]. From ae9fafe414fc62ae8ec76836f8fe1e6c6365b738 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 23 Jan 2023 18:24:22 -0500 Subject: [PATCH 7/7] fix test conditional --- tests/test_nre.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_nre.py b/tests/test_nre.py index e5a6ac37..e2e0cc54 100644 --- a/tests/test_nre.py +++ b/tests/test_nre.py @@ -37,7 +37,7 @@ def test_nre_loaded_plugins(mock_plugins, plugin_name_and_object, will_fail): assert callable(nre.dummy) - if will_fail is True: + if will_fail: with pytest.raises(TypeError): nre.dummy_params(1, 2) else: