[LLDB] bugfix: command script add -f doesn't work for some callables

Summary:
When users define a debugger command from python, they provide a callable
object.   Because the signature of the function has been extended, LLDB
needs to inspect the number of parameters the callable can take.

The rule it was using to decide was weird, apparently not tested, and
giving wrong results for some kinds of python callables.

This patch replaces the weird rule with a simple one: if the callable can
take 5 arguments, it gets the 5 argument version of the signature.
Otherwise it gets the old 4 argument version.

It also adds tests with a bunch of different kinds of python callables
with both 4 and 5 arguments.

Reviewers: JDevlieghere, clayborg, labath, jingham

Reviewed By: labath

Subscribers: lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D69014

llvm-svn: 375333
This commit is contained in:
Lawrence D'Anna
2019-10-19 07:05:33 +00:00
parent 4a5df7312e
commit 2386537c24
7 changed files with 167 additions and 19 deletions

View File

@@ -643,8 +643,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
auto arginfo = lambda.GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 1);
EXPECT_EQ(arginfo.get().max_positional_args, 1u);
EXPECT_EQ(arginfo.get().has_varargs, false);
EXPECT_EQ(arginfo.get().is_bound_method, false);
}
{
@@ -655,8 +655,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
auto arginfo = lambda.GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 2);
EXPECT_EQ(arginfo.get().max_positional_args, 2u);
EXPECT_EQ(arginfo.get().has_varargs, false);
EXPECT_EQ(arginfo.get().is_bound_method, false);
}
{
@@ -667,6 +667,7 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
auto arginfo = lambda.GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 2);
EXPECT_EQ(arginfo.get().max_positional_args, 2u);
EXPECT_EQ(arginfo.get().has_varargs, false);
}
@@ -678,8 +679,9 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
auto arginfo = lambda.GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 2);
EXPECT_EQ(arginfo.get().max_positional_args,
PythonCallable::ArgInfo::UNBOUNDED);
EXPECT_EQ(arginfo.get().has_varargs, true);
EXPECT_EQ(arginfo.get().is_bound_method, false);
}
{
@@ -690,6 +692,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
auto arginfo = lambda.GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 2);
EXPECT_EQ(arginfo.get().max_positional_args,
PythonCallable::ArgInfo::UNBOUNDED);
EXPECT_EQ(arginfo.get().has_varargs, true);
}
@@ -698,7 +702,18 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
class Foo:
def bar(self, x):
return x
@classmethod
def classbar(cls, x):
return x
@staticmethod
def staticbar(x):
return x
def __call__(self, x):
return x
obj = Foo()
bar_bound = Foo().bar
bar_class = Foo().classbar
bar_static = Foo().staticbar
bar_unbound = Foo.bar
)";
PyObject *o =
@@ -711,16 +726,37 @@ bar_unbound = Foo.bar
auto arginfo = bar_bound.get().GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
EXPECT_EQ(arginfo.get().max_positional_args, 1u);
EXPECT_EQ(arginfo.get().has_varargs, false);
EXPECT_EQ(arginfo.get().is_bound_method, true);
auto bar_unbound = As<PythonCallable>(globals.GetItem("bar_unbound"));
ASSERT_THAT_EXPECTED(bar_unbound, llvm::Succeeded());
arginfo = bar_unbound.get().GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 2);
EXPECT_EQ(arginfo.get().max_positional_args, 2u);
EXPECT_EQ(arginfo.get().has_varargs, false);
auto bar_class = As<PythonCallable>(globals.GetItem("bar_class"));
ASSERT_THAT_EXPECTED(bar_class, llvm::Succeeded());
arginfo = bar_class.get().GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().max_positional_args, 1u);
EXPECT_EQ(arginfo.get().has_varargs, false);
auto bar_static = As<PythonCallable>(globals.GetItem("bar_static"));
ASSERT_THAT_EXPECTED(bar_static, llvm::Succeeded());
arginfo = bar_static.get().GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().max_positional_args, 1u);
EXPECT_EQ(arginfo.get().has_varargs, false);
auto obj = As<PythonCallable>(globals.GetItem("obj"));
ASSERT_THAT_EXPECTED(obj, llvm::Succeeded());
arginfo = obj.get().GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().max_positional_args, 1u);
EXPECT_EQ(arginfo.get().has_varargs, false);
EXPECT_EQ(arginfo.get().is_bound_method, false);
}
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
@@ -734,8 +770,8 @@ bar_unbound = Foo.bar
auto arginfo = hex.get().GetArgInfo();
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
EXPECT_EQ(arginfo.get().count, 1);
EXPECT_EQ(arginfo.get().max_positional_args, 1u);
EXPECT_EQ(arginfo.get().has_varargs, false);
EXPECT_EQ(arginfo.get().is_bound_method, false);
}
#endif