Author: zturner Date: Thu Nov 12 10:23:16 2015 New Revision: 252906 URL: http://llvm.org/viewvc/llvm-project?rev=252906&view=rev Log: Begin converting uses of PyCallable to PythonCallable.
PyCallable is a class that exists solely within the swig wrapper code. PythonCallable is a more generic implementation of the same idea that can be used by any Python-related interop code, and lives in PythonDataObjects.h The CL is mostly mechanical, and it doesn't cover every possible user of PyCallable, because I want to minimize the impact of this change (as well as making it easier to figure out what went wrong in case this causes a failure). I plan to finish up the rest of the changes in a subsequent patch, culminating in the removal of PyCallable entirely. Modified: lldb/trunk/scripts/Python/python-wrapper.swig lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h Modified: lldb/trunk/scripts/Python/python-wrapper.swig URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/python-wrapper.swig?rev=252906&r1=252905&r2=252906&view=diff ============================================================================== --- lldb/trunk/scripts/Python/python-wrapper.swig (original) +++ lldb/trunk/scripts/Python/python-wrapper.swig Thu Nov 12 10:23:16 2015 @@ -191,21 +191,19 @@ LLDBSwigPythonBreakpointCallbackFunction bool stop_at_breakpoint = true; PyErr_Cleaner py_err_cleaner(true); - PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>(); + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict); - PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,dict.get()); - - if (!pfunc) + if (!pfunc.IsAllocated()) return stop_at_breakpoint; - PyObject* pvalue = NULL; - pvalue = pfunc(sb_frame, sb_bp_loc, dict.get()); + PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame)); + PythonObject bp_loc_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_bp_loc)); + PythonObject result = pfunc(frame_arg, bp_loc_arg, dict); - if (pvalue == Py_False) + if (result.get() == Py_False) stop_at_breakpoint = false; - Py_XDECREF (pvalue); - return stop_at_breakpoint; } @@ -229,21 +227,19 @@ LLDBSwigPythonWatchpointCallbackFunction PyErr_Cleaner py_err_cleaner(true); - PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>(); - - PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,dict.get()); + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict); - if (!pfunc) + if (!pfunc.IsAllocated()) return stop_at_watchpoint; - PyObject* pvalue = NULL; - pvalue = pfunc(sb_frame, sb_wp, dict.get()); + PythonObject frame_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_frame)); + PythonObject wp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_wp)); + PythonObject result = pfunc(frame_arg, wp_arg, dict); - if (pvalue == Py_False) + if (result.get() == Py_False) stop_at_watchpoint = false; - Py_XDECREF (pvalue); - return stop_at_watchpoint; } @@ -294,7 +290,7 @@ LLDBSwigPythonCallTypeScript if (!python_function_name || !session_dictionary) return false; - PyObject *pfunc_impl = NULL, *pvalue = NULL; + PyObject *pfunc_impl = nullptr; if (pyfunct_wrapper && *pyfunct_wrapper && PyFunction_Check (*pyfunct_wrapper)) { @@ -314,33 +310,33 @@ LLDBSwigPythonCallTypeScript PyErr_Cleaner pyerr_cleanup(true); // show Python errors - if (!pfunc_impl) + PythonCallable pfunc(PyRefType::Borrowed, pfunc_impl); + + if (!pfunc.IsAllocated()) { - pfunc_impl = PythonObject::ResolveNameWithDictionary(python_function_name, dict).release(); - if (!pfunc_impl || !PyCallable_Check (pfunc_impl)) + pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict); + if (!pfunc.IsAllocated()) return false; - else + + if (pyfunct_wrapper) { - if (pyfunct_wrapper) - *pyfunct_wrapper = pfunc_impl; + *pyfunct_wrapper = pfunc.get(); + Py_XINCREF(pfunc.get()); } } - PyCallable pfunc = PyCallable::FindWithPythonObject(pfunc_impl); - - if (!pfunc) - return false; - + PythonObject result; + auto argc = pfunc.GetNumArguments(); // if the third argument is supported, or varargs are allowed - PyCallable::argc argc = pfunc.GetNumArguments(); - if (argc.num_args == 3 || argc.varargs == true) - pvalue = pfunc(sb_value,dict.get(),sb_options); + PythonObject value_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value)); + PythonObject options_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_options)); + if (argc.count == 3 || argc.has_varargs) + result = pfunc(value_arg,dict,options_arg); else - pvalue = pfunc(sb_value,dict.get()); + result = pfunc(value_arg,dict); - PyObjectToString(pvalue,retval); + PyObjectToString(result.get(), retval); - Py_XDECREF (pvalue); return true; } @@ -353,38 +349,33 @@ LLDBSwigPythonCreateSyntheticProvider ) { using namespace lldb_private; - PyObject* retval = NULL; if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; + PyErr_Cleaner py_err_cleaner(true); + + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name,dict); + + if (!pfunc.IsAllocated()) + Py_RETURN_NONE; + // I do not want the SBValue to be deallocated when going out of scope because python // has ownership of it and will manage memory for this object by itself lldb::SBValue *sb_value = new lldb::SBValue(valobj_sp); sb_value->SetPreferSyntheticValue(false); - PyObject *ValObj_PyObj = SBTypeToSWIGWrapper(sb_value); - if (ValObj_PyObj == NULL) + PythonObject val_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_value)); + if (!val_arg.IsAllocated()) Py_RETURN_NONE; - PyErr_Cleaner py_err_cleaner(true); - - PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>(); - PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name,dict.get()); + PythonObject result = pfunc(val_arg, dict); - if (!pfunc) - return retval; + if (result.IsAllocated()) + return result.release(); - Py_INCREF(ValObj_PyObj); - - retval = pfunc(sb_value, dict.get()); - - Py_XINCREF(retval); - - if (retval) - return retval; - else - Py_RETURN_NONE; + Py_RETURN_NONE; } SWIGEXPORT void* @@ -396,28 +387,25 @@ LLDBSwigPythonCreateCommandObject ) { using namespace lldb_private; - PyObject* retval = NULL; if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; - lldb::SBDebugger debugger_sb(debugger_sp); - PyErr_Cleaner py_err_cleaner(true); - PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>(); - PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name,dict.get()); + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict); - if (!pfunc) - return retval; + if (!pfunc.IsAllocated()) + return nullptr; - retval = pfunc(debugger_sb, dict.get()); + lldb::SBDebugger debugger_sb(debugger_sp); + PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); + PythonObject result = pfunc(debugger_arg, dict); - Py_XINCREF(retval); + if (result.IsAllocated()) + return result.release(); - if (retval) - return retval; - else - Py_RETURN_NONE; + Py_RETURN_NONE; } SWIGEXPORT void* @@ -429,7 +417,6 @@ LLDBSwigPythonCreateScriptedThreadPlan ) { using namespace lldb_private; - PyObject* retval = NULL; if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name) Py_RETURN_NONE; @@ -438,32 +425,26 @@ LLDBSwigPythonCreateScriptedThreadPlan // has ownership of it and will manage memory for this object by itself lldb::SBThreadPlan *tp_value = new lldb::SBThreadPlan(thread_plan_sp); - PyObject *ThreadPlan_PyObj = SBTypeToSWIGWrapper(tp_value); - - if (ThreadPlan_PyObj == NULL) - Py_RETURN_NONE; - PyErr_Cleaner py_err_cleaner(true); - PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>(); - PyCallable pfunc = PyCallable::FindWithFunctionName(python_class_name, dict.get()); + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_class_name, dict); - if (!pfunc) - return retval; + if (!pfunc.IsAllocated()) + return nullptr; - Py_INCREF(ThreadPlan_PyObj); + PythonObject tp_arg(PyRefType::Owned, SBTypeToSWIGWrapper(tp_value)); - retval = pfunc(tp_value, dict.get()); + if (!tp_arg.IsAllocated()) + Py_RETURN_NONE; + PythonObject result = pfunc(tp_arg, dict); // FIXME: At this point we should check that the class we found supports all the methods // that we need. - Py_XINCREF(retval); - - if (retval) - return retval; - else - Py_RETURN_NONE; + if (result.IsAllocated()) + return result.release(); + Py_RETURN_NONE; } SWIGEXPORT bool @@ -475,74 +456,64 @@ LLDBSWIGPythonCallThreadPlan bool &got_error ) { - bool ret_val = false; - got_error = false; + using namespace lldb_private; + got_error = false; PyErr_Cleaner py_err_cleaner(false); + PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor)); + auto pfunc = self.ResolveName<PythonCallable>(method_name); - PyCallable pfunc = PyCallable::FindWithMemberFunction((PyObject *) implementor, method_name); - - if (!pfunc) - { - return ret_val; - } - - PyObject* py_return = Py_None; + if (!pfunc.IsAllocated()) + return false; - if (event != NULL) + PythonObject result; + if (event != nullptr) { lldb::SBEvent sb_event(event); - - PyObject *py_obj_event = SBTypeToSWIGWrapper(sb_event); - - py_return = pfunc(py_obj_event); + PythonObject event_arg(PyRefType::Owned, SBTypeToSWIGWrapper(sb_event)); + result = pfunc(event_arg); } else - { - py_return = pfunc(); - } + result = pfunc(); if (PyErr_Occurred()) { got_error = true; printf ("Return value was neither false nor true for call to %s.\n", method_name); PyErr_Print(); - } - else - { - if (py_return == Py_True) - ret_val = true; - else if (py_return == Py_False) - ret_val = false; - else - { - // Somebody returned the wrong thing... - got_error = true; - printf ("Wrong return value type for call to %s.\n", method_name); - } + return false; } - Py_XDECREF(py_return); + if (result.get() == Py_True) + return true; + else if (result.get() == Py_False) + return false; - return ret_val; + // Somebody returned the wrong thing... + got_error = true; + printf ("Wrong return value type for call to %s.\n", method_name); + return false; } // wrapper that calls an optional instance member of an object taking no arguments static PyObject* LLDBSwigPython_CallOptionalMember ( - PyObject* self, + PyObject* implementor, char* callee_name, PyObject* ret_if_not_found = Py_None, bool* was_found = NULL ) { + using namespace lldb_private; + PyErr_Cleaner py_err_cleaner(false); - PyCallable pfunc = PyCallable::FindWithMemberFunction(self,callee_name); + PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor)); + auto pfunc = self.ResolveName<PythonCallable>(callee_name); - if (!pfunc) + if (!pfunc.IsAllocated()) { if (was_found) *was_found = false; @@ -553,8 +524,8 @@ LLDBSwigPython_CallOptionalMember if (was_found) *was_found = true; - PyObject* py_return = pfunc(); - return py_return; + PythonObject result = pfunc(); + return result.release(); } SWIGEXPORT size_t @@ -564,47 +535,29 @@ LLDBSwigPython_CalculateNumChildren uint32_t max ) { - size_t ret_val = 0; - bool int_match = false; + using namespace lldb_private; - PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor, "num_children"); + PythonObject self(PyRefType::Borrowed, implementor); + auto pfunc = self.ResolveName<PythonCallable>("num_children"); - if (!pfunc) - return ret_val; + if (!pfunc.IsAllocated()) + return 0; - PyObject* py_return = NULL; + PythonObject result; auto argc = pfunc.GetNumArguments(); - if (argc.num_args == 1) - py_return = pfunc(); - else if (argc.num_args == 2) - py_return = pfunc(max); - - if (!py_return) - return ret_val; - - // PyInt_* are not available for Python 3 and above. -#if PY_MAJOR_VERSION < 3 - if (PyInt_Check (py_return)) - { - int_match = true; - ret_val = static_cast<size_t> (PyInt_AsLong (py_return)); - } -#endif - - // We want to check for PyLong only if the return value did not - // match PyInt. This is because we do not want to call PyLong_Check if - // PyInt_Check returns true but PyInt_AsLong generates an error. - if (!int_match && PyLong_Check (py_return)) - { -#if PY_MAJOR_VERSION < 3 - ret_val = static_cast<size_t> (PyLong_AsUnsignedLong (py_return)); -#else - // PyLong_AsSize_t is available only for Python 3 and above. - ret_val = PyLong_AsSize_t (py_return); -#endif - } + if (argc.count == 1) + result = pfunc(); + else if (argc.count == 2) + result = pfunc(PythonInteger(max)); + + if (!result.IsAllocated()) + return 0; + + PythonInteger int_result = result.AsType<PythonInteger>(); + if (!int_result.IsAllocated()) + return 0; - Py_XDECREF(py_return); + size_t ret_val = int_result.GetInteger(); if (PyErr_Occurred()) { @@ -612,8 +565,8 @@ LLDBSwigPython_CalculateNumChildren PyErr_Clear(); } - if (argc.num_args == 1 && ret_val > max) - ret_val = max; + if (argc.count == 1) + ret_val = std::min(ret_val, max); return ret_val; } @@ -625,34 +578,28 @@ LLDBSwigPython_GetChildAtIndex uint32_t idx ) { + using namespace lldb_private; PyErr_Cleaner py_err_cleaner(true); - PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"get_child_at_index"); + PythonObject self(PyRefType::Borrowed, implementor); + auto pfunc = self.ResolveName<PythonCallable>("get_child_at_index"); - if (!pfunc) - return NULL; + if (!pfunc.IsAllocated()) + return nullptr; - PyObject *py_return = NULL; - py_return = pfunc(idx); + PythonObject result = pfunc(PythonInteger(idx)); - if (py_return == NULL || py_return == Py_None) - { - Py_XDECREF(py_return); - return NULL; - } - - lldb::SBValue* sbvalue_ptr = NULL; + if (!result.IsAllocated()) + return nullptr; - if (SWIG_ConvertPtr(py_return, (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1) - { - Py_XDECREF(py_return); - return NULL; - } + lldb::SBValue* sbvalue_ptr = nullptr; + if (SWIG_ConvertPtr(result.get(), (void**)&sbvalue_ptr, SWIGTYPE_p_lldb__SBValue, 0) == -1) + return nullptr; - if (sbvalue_ptr == NULL) - return NULL; + if (sbvalue_ptr == nullptr) + return nullptr; - return py_return; + return result.release(); } SWIGEXPORT int @@ -662,25 +609,25 @@ LLDBSwigPython_GetIndexOfChildWithName const char* child_name ) { + using namespace lldb_private; PyErr_Cleaner py_err_cleaner(true); - PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"get_child_index"); + PythonObject self(PyRefType::Borrowed, implementor); + auto pfunc = self.ResolveName<PythonCallable>("get_child_index"); - if (!pfunc) + if (!pfunc.IsAllocated()) return UINT32_MAX; - PyObject *py_return = NULL; - py_return = pfunc(child_name); + PythonObject result = pfunc(PythonString(child_name)); - if (py_return == NULL || py_return == Py_None) - { - Py_XDECREF(py_return); + if (!result.IsAllocated()) return UINT32_MAX; - } - long retval = PyInt_AsLong(py_return); - Py_XDECREF(py_return); + PythonInteger int_result = result.AsType<PythonInteger>(); + if (!int_result.IsAllocated()) + return UINT32_MAX; + int64_t retval = int_result.GetInteger(); if (retval >= 0) return (uint32_t)retval; @@ -812,30 +759,26 @@ LLDBSwigPythonCallCommand lldb::SBDebugger debugger_sb(debugger); lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp); - bool retval = false; - PyErr_Cleaner py_err_cleaner(true); - PythonDictionary dict = PythonModule::MainModule().ResolveName(session_dictionary_name).AsType<PythonDictionary>(); - PyCallable pfunc = PyCallable::FindWithFunctionName(python_function_name,dict.get()); + auto dict = PythonModule::MainModule().ResolveName<PythonDictionary>(session_dictionary_name); + auto pfunc = PythonObject::ResolveNameWithDictionary<PythonCallable>(python_function_name, dict); - if (!pfunc) - return retval; + if (!pfunc.IsAllocated()) + return false; // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you // see comment above for SBCommandReturnObjectReleaser for further details - PyObject* pvalue = NULL; + auto argc = pfunc.GetNumArguments(); + PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); + PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb)); + PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb)); - PyCallable::argc argc = pfunc.GetNumArguments(); - if (argc.num_args == 5 || argc.varargs == true) - pvalue = pfunc(debugger_sb, args, exe_ctx_sb, &cmd_retobj_sb, dict.get()); + if (argc.count == 5 || argc.has_varargs) + pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict); else - pvalue = pfunc(debugger_sb, args, &cmd_retobj_sb, dict.get()); - - Py_XDECREF (pvalue); + pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict); - retval = true; - - return retval; + return true; } SWIGEXPORT bool @@ -848,7 +791,7 @@ LLDBSwigPythonCallCommandObject lldb::ExecutionContextRefSP exe_ctx_ref_sp ) { - + using namespace lldb_private; lldb::SBCommandReturnObject cmd_retobj_sb(&cmd_retobj); SBCommandReturnObjectReleaser cmd_retobj_sb_releaser(cmd_retobj_sb); lldb::SBDebugger debugger_sb(debugger); @@ -856,18 +799,19 @@ LLDBSwigPythonCallCommandObject PyErr_Cleaner py_err_cleaner(true); - PyCallable pfunc = PyCallable::FindWithMemberFunction(implementor,"__call__"); + PythonObject self(PyRefType::Borrowed, implementor); + auto pfunc = self.ResolveName<PythonCallable>("__call__"); - if (!pfunc) + if (!pfunc.IsAllocated()) return false; // pass the pointer-to cmd_retobj_sb or watch the underlying object disappear from under you // see comment above for SBCommandReturnObjectReleaser for further details - PyObject* pvalue = NULL; - - pvalue = pfunc(debugger_sb, args, exe_ctx_sb, &cmd_retobj_sb); + PythonObject debugger_arg(PyRefType::Owned, SBTypeToSWIGWrapper(debugger_sb)); + PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb)); + PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb)); - Py_XDECREF (pvalue); + pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg); return true; } Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp?rev=252906&r1=252905&r2=252906&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (original) +++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp Thu Nov 12 10:23:16 2015 @@ -904,31 +904,35 @@ PythonCallable::Reset(PyRefType type, Py } -void -PythonCallable::GetNumArguments(size_t &num_args, bool &has_varargs, bool &has_kwargs) const +PythonCallable::ArgInfo +PythonCallable::GetNumArguments() const { - num_args = 0; - has_varargs = false; - has_kwargs = false; + ArgInfo result = { 0, false, false }; if (!IsValid()) - return; + return result; PyObject *py_func_obj = m_py_obj; if (PyMethod_Check(py_func_obj)) py_func_obj = PyMethod_GET_FUNCTION(py_func_obj); if (!py_func_obj) - return; + return result; PyCodeObject* code = (PyCodeObject*)PyFunction_GET_CODE(py_func_obj); if (!code) - return; + return result; - num_args = code->co_argcount; - if (code->co_flags & CO_VARARGS) - has_varargs = true; - if (code->co_flags & CO_VARKEYWORDS) - has_kwargs = true; + result.count = code->co_argcount; + result.has_varargs = !!(code->co_flags & CO_VARARGS); + result.has_kwargs = !!(code->co_flags & CO_VARKEYWORDS); + return result; +} + +PythonObject +PythonCallable::operator ()() +{ + return PythonObject(PyRefType::Owned, + PyObject_CallObject(m_py_obj, nullptr)); } PythonObject Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h?rev=252906&r1=252905&r2=252906&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (original) +++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h Thu Nov 12 10:23:16 2015 @@ -207,9 +207,23 @@ public: static PythonObject ResolveNameWithDictionary(llvm::StringRef name, PythonDictionary dict); + template<typename T> + static T + ResolveNameWithDictionary(llvm::StringRef name, PythonDictionary dict) + { + return ResolveNameWithDictionary(name, dict).AsType<T>(); + } + PythonObject ResolveName(llvm::StringRef name) const; + template<typename T> + T + ResolveName(llvm::StringRef name) const + { + return ResolveName(name).AsType<T>(); + } + bool HasAttribute(llvm::StringRef attribute) const; @@ -410,6 +424,12 @@ class PythonModule : public PythonObject class PythonCallable : public PythonObject { public: + struct ArgInfo { + size_t count; + bool has_varargs : 1; + bool has_kwargs : 1; + }; + PythonCallable(); PythonCallable(PyRefType type, PyObject *o); PythonCallable(const PythonCallable &dict); @@ -425,14 +445,24 @@ public: void Reset(PyRefType type, PyObject *py_obj) override; - void - GetNumArguments(size_t &num_args, bool &has_varargs, bool &has_kwargs) const; + ArgInfo + GetNumArguments() const; + + PythonObject + operator ()(); PythonObject operator ()(std::initializer_list<PyObject*> args); PythonObject operator ()(std::initializer_list<PythonObject> args); + + template<typename Arg, typename... Args> + PythonObject + operator ()(const Arg &arg, Args... args) + { + return operator()({ arg, args... }); + } }; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits