[Lldb-commits] [lldb] Add the ability to define custom completers to the parsed_cmd template. (PR #109062)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Sep 17 16:34:04 PDT 2024
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {darker}-->
:warning: Python code formatter, darker found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
darker --check --diff -r 090850f15dba926e2436089ff679b7015bb59e11...a0b5801ab231670215657ec720fa0c89bc262c04 lldb/examples/python/cmdtemplate.py lldb/examples/python/templates/parsed_cmd.py lldb/test/API/commands/command/script/add/TestAddParsedCommand.py lldb/test/API/commands/command/script/add/test_commands.py
``````````
</details>
<details>
<summary>
View the diff from darker here.
</summary>
``````````diff
--- examples/python/templates/parsed_cmd.py 2024-09-17 23:24:25.000000 +0000
+++ examples/python/templates/parsed_cmd.py 2024-09-17 23:33:31.276094 +0000
@@ -282,17 +282,17 @@
object.__setattr__(self, elem["dest"], value)
elem["_value_set"] = True
return True
def was_set(self, opt_name):
- """ Call this in the __call__ method of your command to determine
- whether this option was set on the command line. It is sometimes
- useful to know whether an option has the default value because the
- user set it explicitly (was_set -> True) or not.
- You can also call this in a handle_completion method, but it will
- currently only report true values for the options mentioned
- BEFORE the cursor point in the command line.
+ """Call this in the __call__ method of your command to determine
+ whether this option was set on the command line. It is sometimes
+ useful to know whether an option has the default value because the
+ user set it explicitly (was_set -> True) or not.
+ You can also call this in a handle_completion method, but it will
+ currently only report true values for the options mentioned
+ BEFORE the cursor point in the command line.
"""
elem = self.get_option_element(opt_name)
if not elem:
return False
@@ -300,12 +300,12 @@
return elem["_value_set"]
except AttributeError:
return False
def dest_for_option(self, opt_name):
- """ This will return the value of the dest variable you defined for opt_name.
- Mostly useful for handle_completion where you get passed the long option.
+ """This will return the value of the dest variable you defined for opt_name.
+ Mostly useful for handle_completion where you get passed the long option.
"""
elem = self.get_option_element(opt_name)
if not elem:
return None
value = self.__dict__[elem["dest"]]
@@ -329,12 +329,12 @@
value_type: one of the lldb.eArgType enum values. Some of the common arg
types also have default completers, which will be applied automatically.
completion_type: currently these are values form the lldb.CompletionType enum. If
you need custom completions, implement handle_option_argument_completion.
enum_values: An array of duples: ["element_name", "element_help"]. If provided,
- only one of the enum elements is allowed. The value will be the
- element_name for the chosen enum element as a string.
+ only one of the enum elements is allowed. The value will be the
+ element_name for the chosen enum element as a string.
"""
if not dest:
dest = long_option
if not completion_type:
--- test/API/commands/command/script/add/TestAddParsedCommand.py 2024-09-17 23:24:25.000000 +0000
+++ test/API/commands/command/script/add/TestAddParsedCommand.py 2024-09-17 23:33:31.376819 +0000
@@ -66,43 +66,61 @@
self.assertEqual(n_errors, expected_num_errors)
return results
- def handle_completion(self, cmd_str, exp_num_completions, exp_matches, exp_descriptions, match_description):
+ def handle_completion(
+ self,
+ cmd_str,
+ exp_num_completions,
+ exp_matches,
+ exp_descriptions,
+ match_description,
+ ):
matches = lldb.SBStringList()
descriptions = lldb.SBStringList()
interp = self.dbg.GetCommandInterpreter()
num_completions = interp.HandleCompletionWithDescriptions(
cmd_str, len(cmd_str), 0, 1000, matches, descriptions
)
- self.assertEqual(num_completions, exp_num_completions, "Number of completions is right.")
+ self.assertEqual(
+ num_completions, exp_num_completions, "Number of completions is right."
+ )
num_matches = matches.GetSize()
- self.assertEqual(num_matches, exp_matches.GetSize(), "matches and expected matches of different lengths")
+ self.assertEqual(
+ num_matches,
+ exp_matches.GetSize(),
+ "matches and expected matches of different lengths",
+ )
num_descriptions = descriptions.GetSize()
if match_description:
- self.assertEqual(num_descriptions, exp_descriptions.GetSize(), "descriptions and expected of different lengths")
-
- self.assertEqual(
- matches.GetSize(), num_completions + 1, "The first element is the complete additional text"
- )
-
+ self.assertEqual(
+ num_descriptions,
+ exp_descriptions.GetSize(),
+ "descriptions and expected of different lengths",
+ )
+
+ self.assertEqual(
+ matches.GetSize(),
+ num_completions + 1,
+ "The first element is the complete additional text",
+ )
for idx in range(0, num_matches):
match = matches.GetStringAtIndex(idx)
exp_match = exp_matches.GetStringAtIndex(idx)
self.assertEqual(
- match, exp_match , f"{match} did not match expectation: {exp_match}"
+ match, exp_match, f"{match} did not match expectation: {exp_match}"
)
if match_description:
desc = descriptions.GetStringAtIndex(idx)
exp_desc = exp_descriptions.GetStringAtIndex(idx)
self.assertEqual(
desc, exp_desc, f"{desc} didn't match expectation: {exp_desc}"
)
-
+
def pycmd_tests(self):
source_dir = self.getSourceDir()
test_file_path = os.path.join(source_dir, "test_commands.py")
self.runCmd("command script import " + test_file_path)
self.expect("help", substrs=["no-args", "one-arg-no-opt", "two-args"])
@@ -206,30 +224,25 @@
interp = self.dbg.GetCommandInterpreter()
matches = lldb.SBStringList()
descriptions = lldb.SBStringList()
-
# First try an enum completion:
# Note - this is an enum so all the values are returned:
matches.AppendList(["oo ", "foo"], 2)
-
- self.handle_completion(
- "no-args -e f", 1, matches, descriptions, False
- )
+
+ self.handle_completion("no-args -e f", 1, matches, descriptions, False)
# Now try an internal completer, the on disk file one is handy:
partial_name = os.path.join(source_dir, "test_")
cmd_str = f"no-args -d '{partial_name}'"
matches.Clear()
descriptions.Clear()
matches.AppendList(["commands.py' ", test_file_path], 2)
# We don't have descriptions for the file path completer:
- self.handle_completion(
- cmd_str, 1, matches, descriptions, False
- )
+ self.handle_completion(cmd_str, 1, matches, descriptions, False)
# Try a command with arguments.
# FIXME: It should be enough to define an argument and it's type to get the completer
# wired up for that argument type if it is a known type. But that isn't wired up in the
# command parser yet, so I don't have any tests for that. We also don't currently check
@@ -245,11 +258,11 @@
matches.Clear()
descriptions.Clear()
cmd_str = "two-args -p something -c other_"
matches.AppendString("something ")
matches.AppendString("other_something")
- # This is a full match so no descriptions:
+ # This is a full match so no descriptions:
self.handle_completion(cmd_str, 1, matches, descriptions, False)
matches.Clear()
descriptions.Clear()
cmd_str = "two-args -c other_"
@@ -275,11 +288,11 @@
cmd_str = "two-args correct_"
matches.Clear()
descriptions.Clear()
matches.AppendList(["answer ", "correct_answer"], 2)
self.handle_completion(cmd_str, 1, matches, descriptions, False)
-
+
# Now make sure get_repeat_command works properly:
# no-args turns off auto-repeat
results = self.run_one_repeat("no-args\n\n", 1)
self.assertIn("No auto repeat", results, "Got auto-repeat error")
--- test/API/commands/command/script/add/test_commands.py 2024-09-17 23:24:25.000000 +0000
+++ test/API/commands/command/script/add/test_commands.py 2024-09-17 23:33:31.452716 +0000
@@ -199,33 +199,31 @@
ov_parser.add_argument_set(
[
ov_parser.make_argument_element(
lldb.eArgTypePythonClass, "plain", [3, 4]
),
- ov_parser.make_argument_element(
- lldb.eArgTypePid, "optional", [3, 4]
- ),
+ ov_parser.make_argument_element(lldb.eArgTypePid, "optional", [3, 4]),
]
)
def get_repeat_command(self, command):
global two_arg_repeat
two_arg_repeat = command
return command + " THIRD_ARG"
def handle_option_argument_completion(self, long_option, cursor_pos):
ov_parser = self.get_parser()
- value = ov_parser.dest_for_option(long_option)[0:cursor_pos+1]
+ value = ov_parser.dest_for_option(long_option)[0 : cursor_pos + 1]
proc_value = ov_parser.proc_name
if proc_value != None:
- new_str = value+proc_value
- ret_arr = {"completion" : new_str, "mode" : "partial"}
+ new_str = value + proc_value
+ ret_arr = {"completion": new_str, "mode": "partial"}
return ret_arr
- ret_arr = {"values" : [value+"nice", value+"not_nice", value+"mediocre"]}
+ ret_arr = {"values": [value + "nice", value + "not_nice", value + "mediocre"]}
return ret_arr
-
+
def handle_argument_completion(self, args, arg_pos, cursor_pos):
ov_parser = self.get_parser()
orig_arg = args[arg_pos][0:cursor_pos]
if orig_arg == "correct_":
ret_arr = {"completion": "correct_answer"}
@@ -233,11 +231,14 @@
if ov_parser.was_set("process-name"):
# No completions if proc_name was set.
return True
- ret_arr = {"values" : [orig_arg + "cool", orig_arg+"yuck"], "descriptions" : ["good idea", "bad idea"]}
+ ret_arr = {
+ "values": [orig_arg + "cool", orig_arg + "yuck"],
+ "descriptions": ["good idea", "bad idea"],
+ }
return ret_arr
def get_short_help(self):
return "This is my short help string"
``````````
</details>
https://github.com/llvm/llvm-project/pull/109062
More information about the lldb-commits
mailing list