summaryrefslogtreecommitdiffstats
path: root/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
diff options
context:
space:
mode:
authorLawrence D'Anna <lawrence_danna@apple.com>2019-10-17 22:22:06 +0000
committerLawrence D'Anna <lawrence_danna@apple.com>2019-10-17 22:22:06 +0000
commitc86a6acaee55c98072ff06d372d049cb4a671fb5 (patch)
treeb2300fe71c5baff776cacda3a339b35fbd2f3760 /lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
parent3d737b642a3a0688de9ed6dd3fe599bc2ed79847 (diff)
downloadbcm5719-llvm-c86a6acaee55c98072ff06d372d049cb4a671fb5.tar.gz
bcm5719-llvm-c86a6acaee55c98072ff06d372d049cb4a671fb5.zip
clean up the implementation of PythonCallable::GetNumArguments
Summary: The current implementation of PythonCallable::GetNumArguments is not exception safe, has weird semantics, and is just plain incorrect for some kinds of functions. Python 3.3 introduces inspect.signature, which lets us easily query for function signatures in a sane and documented way. This patch leaves the old implementation in place for < 3.3, but uses inspect.signature for modern pythons. It also leaves the old weird semantics in place, but with FIXMEs grousing about it. We should update the callers and fix the semantics in a subsequent patch. It also adds some tests. Reviewers: JDevlieghere, clayborg, labath, jingham Reviewed By: labath Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D68995 llvm-svn: 375181
Diffstat (limited to 'lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp')
-rw-r--r--lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
index 5c3c6097007..3f0cb78b64c 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -20,6 +20,7 @@
#include "PythonTestSuite.h"
using namespace lldb_private;
+using namespace lldb_private::python;
class PythonDataObjectsTest : public PythonTestSuite {
public:
@@ -626,3 +627,116 @@ TEST_F(PythonDataObjectsTest, TestExtractingUInt64ThroughStructuredData) {
}
}
}
+
+TEST_F(PythonDataObjectsTest, TestCallable) {
+
+ PythonDictionary globals(PyInitialValue::Empty);
+ auto builtins = PythonModule::BuiltinsModule();
+ llvm::Error error = globals.SetItem("__builtins__", builtins);
+ ASSERT_FALSE(error);
+
+ {
+ PyObject *o = PyRun_String("lambda x : x", Py_eval_input, globals.get(),
+ globals.get());
+ ASSERT_FALSE(o == NULL);
+ auto lambda = Take<PythonCallable>(o);
+ auto arginfo = lambda.GetArgInfo();
+ ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+ EXPECT_EQ(arginfo.get().count, 1);
+ EXPECT_EQ(arginfo.get().has_varargs, false);
+ EXPECT_EQ(arginfo.get().is_bound_method, false);
+ }
+
+ {
+ PyObject *o = PyRun_String("lambda x,y=0: x", Py_eval_input, globals.get(),
+ globals.get());
+ ASSERT_FALSE(o == NULL);
+ auto lambda = Take<PythonCallable>(o);
+ auto arginfo = lambda.GetArgInfo();
+ ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+ EXPECT_EQ(arginfo.get().count, 2);
+ EXPECT_EQ(arginfo.get().has_varargs, false);
+ EXPECT_EQ(arginfo.get().is_bound_method, false);
+ }
+
+ {
+ PyObject *o = PyRun_String("lambda x,y=0, **kw: x", Py_eval_input,
+ globals.get(), globals.get());
+ ASSERT_FALSE(o == NULL);
+ auto lambda = Take<PythonCallable>(o);
+ auto arginfo = lambda.GetArgInfo();
+ ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+ EXPECT_EQ(arginfo.get().count, 2);
+ EXPECT_EQ(arginfo.get().has_varargs, false);
+ }
+
+ {
+ PyObject *o = PyRun_String("lambda x,y,*a: x", Py_eval_input, globals.get(),
+ globals.get());
+ ASSERT_FALSE(o == NULL);
+ auto lambda = Take<PythonCallable>(o);
+ auto arginfo = lambda.GetArgInfo();
+ ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+ EXPECT_EQ(arginfo.get().count, 2);
+ EXPECT_EQ(arginfo.get().has_varargs, true);
+ EXPECT_EQ(arginfo.get().is_bound_method, false);
+ }
+
+ {
+ PyObject *o = PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input,
+ globals.get(), globals.get());
+ ASSERT_FALSE(o == NULL);
+ auto lambda = Take<PythonCallable>(o);
+ auto arginfo = lambda.GetArgInfo();
+ ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+ EXPECT_EQ(arginfo.get().count, 2);
+ EXPECT_EQ(arginfo.get().has_varargs, true);
+ }
+
+ {
+ const char *script = R"(
+class Foo:
+ def bar(self, x):
+ return x
+bar_bound = Foo().bar
+bar_unbound = Foo.bar
+)";
+ PyObject *o =
+ PyRun_String(script, Py_file_input, globals.get(), globals.get());
+ ASSERT_FALSE(o == NULL);
+ Take<PythonObject>(o);
+
+ auto bar_bound = As<PythonCallable>(globals.GetItem("bar_bound"));
+ ASSERT_THAT_EXPECTED(bar_bound, llvm::Succeeded());
+ auto arginfo = bar_bound.get().GetArgInfo();
+ ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+ EXPECT_EQ(arginfo.get().count, 2); // FIXME, wrong
+ 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().has_varargs, false);
+ EXPECT_EQ(arginfo.get().is_bound_method, false);
+ }
+
+#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
+
+ // the old implementation of GetArgInfo just doesn't work on builtins.
+
+ {
+ auto builtins = PythonModule::BuiltinsModule();
+ auto hex = As<PythonCallable>(builtins.GetAttribute("hex"));
+ ASSERT_THAT_EXPECTED(hex, llvm::Succeeded());
+ auto arginfo = hex.get().GetArgInfo();
+ ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
+ EXPECT_EQ(arginfo.get().count, 1);
+ EXPECT_EQ(arginfo.get().has_varargs, false);
+ EXPECT_EQ(arginfo.get().is_bound_method, false);
+ }
+
+#endif
+} \ No newline at end of file
OpenPOWER on IntegriCloud