From f577980eac06dc3bccdc7389e3a09410c734e65d Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 29 May 2024 16:15:25 +0000 Subject: [PATCH 1/4] Expanding Lark Support --- brewtils/choices.py | 7 ++- test/decorators_test.py | 96 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/brewtils/choices.py b/brewtils/choices.py index de297692..2cff8b4b 100644 --- a/brewtils/choices.py +++ b/brewtils/choices.py @@ -20,7 +20,6 @@ GrammarError = ParseError LexError = ParseError - choices_grammar = r""" func: CNAME [func_args] url: ADDRESS [url_args] @@ -30,12 +29,16 @@ url_args: "?" arg_pair ("&" arg_pair)* arg_pair: CNAME "=" ref - ?ref: "${" CNAME "}" + ?ref: var_ref + | ESCAPED_STRING + + var_ref: "${" CNAME "}" ADDRESS: /^http[^\?]*/ %import common.CNAME %import common.WS + %import common.ESCAPED_STRING %ignore WS """ diff --git a/test/decorators_test.py b/test/decorators_test.py index be417781..1db4b7cf 100644 --- a/test/decorators_test.py +++ b/test/decorators_test.py @@ -761,6 +761,102 @@ def test_bad_partial_call(self, basic_param): def func(foo): return foo +class TestDynamicParameters(object): + + def test_command_static_choices(self): + + STATIC_CHOICES = ["a", "b", "c"] + @parameter(key="key", type="String", choices=STATIC_CHOICES) + def func1(key): + return key + + cmd1 = _parse_method(func1) + + assert(cmd1.parameters[0].choices.value == STATIC_CHOICES) + assert(cmd1.parameters[0].choices.type == 'static') + + def test_command_url_choices(self): + + CHOICES_URL = "http://example.com/api/choices.json" + + @parameter(key="key", type="String", choices={"type": "url", "value": CHOICES_URL},) + def func1(key): + return key + + cmd1 = _parse_method(func1) + + assert(cmd1.parameters[0].choices.value == CHOICES_URL) + assert(cmd1.parameters[0].choices.type == 'url') + + def test_command_command_choices(self): + + @parameter(key="key", type="String", choices={"type": "command", "value": "get_choices"}) + def func1(key): + return key + + cmd1 = _parse_method(func1) + + assert(cmd1.parameters[0].choices.value == "get_choices") + assert(cmd1.parameters[0].choices.type == 'command') + + def test_command_reference_input(self): + + STATIC_CHOICES = ["a", "b", "c"] + + @parameter( + key="index", type="String", choices=STATIC_CHOICES, default="a" + ) + @parameter( + key="key", + type="String", + optional=False, + choices={ + "type": "command", + "display": "select", + "strict": True, + "value": "get_choices_with_argument(key=${index})", + }, + ) + def func1(index, key): + return {index: key} + + cmd1 = _parse_method(func1) + + assert(cmd1.parameters[0].choices.value == STATIC_CHOICES) + assert(cmd1.parameters[0].choices.type == 'static') + + assert(cmd1.parameters[1].choices.value == "get_choices_with_argument(key=${index})") + assert(cmd1.parameters[1].choices.type == 'command') + + def test_command_reference_and_static_inputs(self): + + STATIC_CHOICES = ["a", "b", "c"] + + @parameter( + key="index", type="String", choices=STATIC_CHOICES, default="a" + ) + @parameter( + key="key", + type="String", + optional=False, + choices={ + "type": "command", + "display": "select", + "strict": True, + "value": 'get_choices_with_argument(key=${index}, value="foo")', + }, + ) + def func1(index, key): + return {index: key} + + cmd1 = _parse_method(func1) + + assert(cmd1.parameters[0].choices.value == STATIC_CHOICES) + assert(cmd1.parameters[0].choices.type == 'static') + + assert(cmd1.parameters[1].choices.value == 'get_choices_with_argument(key=${index}, value="foo")') + assert(cmd1.parameters[1].choices.type == 'command') + class TestParseMethod(object): """Test the various ways of marking a method as a Command""" From 5d52ca0b28bb7ed29d1e59075aa3ceac2064ec15 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 29 May 2024 17:09:16 +0000 Subject: [PATCH 2/4] Fixed parsing --- brewtils/choices.py | 5 ++--- test/decorators_test.py | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/brewtils/choices.py b/brewtils/choices.py index 2cff8b4b..2f3c0eef 100644 --- a/brewtils/choices.py +++ b/brewtils/choices.py @@ -29,11 +29,9 @@ url_args: "?" arg_pair ("&" arg_pair)* arg_pair: CNAME "=" ref - ?ref: var_ref + ?ref: "${" CNAME "}" | ESCAPED_STRING - var_ref: "${" CNAME "}" - ADDRESS: /^http[^\?]*/ %import common.CNAME @@ -41,6 +39,7 @@ %import common.ESCAPED_STRING %ignore WS """ +## var_ref: "${" CNAME "}" parsers = { "func": Lark(choices_grammar, start="func"), diff --git a/test/decorators_test.py b/test/decorators_test.py index 1db4b7cf..b5645ee9 100644 --- a/test/decorators_test.py +++ b/test/decorators_test.py @@ -856,6 +856,8 @@ def func1(index, key): assert(cmd1.parameters[1].choices.value == 'get_choices_with_argument(key=${index}, value="foo")') assert(cmd1.parameters[1].choices.type == 'command') + assert(cmd1.parameters[1].choices.details['args'][1] == ('value','"foo"')) + assert(cmd1.parameters[1].choices.details['args'][0] == ('key','index')) class TestParseMethod(object): From 8e9b670d39b9767d5695c163cb5f664ab21b5e08 Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 29 May 2024 18:20:21 +0000 Subject: [PATCH 3/4] Formatting and change log --- CHANGELOG.rst | 6 ++++ test/decorators_test.py | 64 ++++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e2dcc9f5..b328d896 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ Brewtils Changelog ================== +3.26.2 +------ +TBD + +- Expanded Lark parsing to support static String values provided for command choices + 3.26.1 ------ 5/24/2024 diff --git a/test/decorators_test.py b/test/decorators_test.py index b5645ee9..2841344c 100644 --- a/test/decorators_test.py +++ b/test/decorators_test.py @@ -761,51 +761,59 @@ def test_bad_partial_call(self, basic_param): def func(foo): return foo + class TestDynamicParameters(object): def test_command_static_choices(self): STATIC_CHOICES = ["a", "b", "c"] + @parameter(key="key", type="String", choices=STATIC_CHOICES) def func1(key): return key cmd1 = _parse_method(func1) - assert(cmd1.parameters[0].choices.value == STATIC_CHOICES) - assert(cmd1.parameters[0].choices.type == 'static') + assert cmd1.parameters[0].choices.value == STATIC_CHOICES + assert cmd1.parameters[0].choices.type == "static" def test_command_url_choices(self): CHOICES_URL = "http://example.com/api/choices.json" - @parameter(key="key", type="String", choices={"type": "url", "value": CHOICES_URL},) + @parameter( + key="key", + type="String", + choices={"type": "url", "value": CHOICES_URL}, + ) def func1(key): return key cmd1 = _parse_method(func1) - assert(cmd1.parameters[0].choices.value == CHOICES_URL) - assert(cmd1.parameters[0].choices.type == 'url') + assert cmd1.parameters[0].choices.value == CHOICES_URL + assert cmd1.parameters[0].choices.type == "url" def test_command_command_choices(self): - @parameter(key="key", type="String", choices={"type": "command", "value": "get_choices"}) + @parameter( + key="key", + type="String", + choices={"type": "command", "value": "get_choices"}, + ) def func1(key): return key cmd1 = _parse_method(func1) - assert(cmd1.parameters[0].choices.value == "get_choices") - assert(cmd1.parameters[0].choices.type == 'command') + assert cmd1.parameters[0].choices.value == "get_choices" + assert cmd1.parameters[0].choices.type == "command" def test_command_reference_input(self): STATIC_CHOICES = ["a", "b", "c"] - @parameter( - key="index", type="String", choices=STATIC_CHOICES, default="a" - ) + @parameter(key="index", type="String", choices=STATIC_CHOICES, default="a") @parameter( key="key", type="String", @@ -819,22 +827,23 @@ def test_command_reference_input(self): ) def func1(index, key): return {index: key} - + cmd1 = _parse_method(func1) - assert(cmd1.parameters[0].choices.value == STATIC_CHOICES) - assert(cmd1.parameters[0].choices.type == 'static') + assert cmd1.parameters[0].choices.value == STATIC_CHOICES + assert cmd1.parameters[0].choices.type == "static" - assert(cmd1.parameters[1].choices.value == "get_choices_with_argument(key=${index})") - assert(cmd1.parameters[1].choices.type == 'command') + assert ( + cmd1.parameters[1].choices.value + == "get_choices_with_argument(key=${index})" + ) + assert cmd1.parameters[1].choices.type == "command" def test_command_reference_and_static_inputs(self): STATIC_CHOICES = ["a", "b", "c"] - @parameter( - key="index", type="String", choices=STATIC_CHOICES, default="a" - ) + @parameter(key="index", type="String", choices=STATIC_CHOICES, default="a") @parameter( key="key", type="String", @@ -848,16 +857,19 @@ def test_command_reference_and_static_inputs(self): ) def func1(index, key): return {index: key} - + cmd1 = _parse_method(func1) - assert(cmd1.parameters[0].choices.value == STATIC_CHOICES) - assert(cmd1.parameters[0].choices.type == 'static') + assert cmd1.parameters[0].choices.value == STATIC_CHOICES + assert cmd1.parameters[0].choices.type == "static" - assert(cmd1.parameters[1].choices.value == 'get_choices_with_argument(key=${index}, value="foo")') - assert(cmd1.parameters[1].choices.type == 'command') - assert(cmd1.parameters[1].choices.details['args'][1] == ('value','"foo"')) - assert(cmd1.parameters[1].choices.details['args'][0] == ('key','index')) + assert ( + cmd1.parameters[1].choices.value + == 'get_choices_with_argument(key=${index}, value="foo")' + ) + assert cmd1.parameters[1].choices.type == "command" + assert cmd1.parameters[1].choices.details["args"][1] == ("value", '"foo"') + assert cmd1.parameters[1].choices.details["args"][0] == ("key", "index") class TestParseMethod(object): From 8fcf52a0871ce4909f7b241a29edae5a936705ce Mon Sep 17 00:00:00 2001 From: TheBurchLog <5104941+TheBurchLog@users.noreply.github.com> Date: Wed, 29 May 2024 14:21:44 -0400 Subject: [PATCH 4/4] Cleanup --- brewtils/choices.py | 1 - 1 file changed, 1 deletion(-) diff --git a/brewtils/choices.py b/brewtils/choices.py index 2f3c0eef..9a954cd7 100644 --- a/brewtils/choices.py +++ b/brewtils/choices.py @@ -39,7 +39,6 @@ %import common.ESCAPED_STRING %ignore WS """ -## var_ref: "${" CNAME "}" parsers = { "func": Lark(choices_grammar, start="func"),