Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Add nre instance to plugins #343

Merged
merged 7 commits into from
Feb 6, 2023
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
2 changes: 2 additions & 0 deletions docs/modules/ROOT/pages/create_plugin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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].

Expand Down
7 changes: 6 additions & 1 deletion src/nile/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 1 addition & 4 deletions src/nile/core/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 4 additions & 1 deletion src/nile/nre.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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, self)
setattr(self, name, skip_click_exit(partial_obj))

def compile(self, contracts, cairo_path=None):
"""Compile a list of contracts."""
Expand Down
7 changes: 2 additions & 5 deletions tests/core/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
46 changes: 29 additions & 17 deletions tests/test_nre.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
with pytest.raises(TypeError):
nre.dummy_params(1, 2)
else:
nre_result = nre.dummy_params(1, 2)
assert 3 == nre_result