60 virtual ~FunctionImplBase() =
default;
61 virtual PyObject* call(PyObject* args)
const = 0;
64template <
typename R,
typename... Args>
65class FunctionImpl:
public FunctionImplBase
68 using TFunction = std::function<R(Args...)>;
70 FunctionImpl(TFunction func) : func_(std::move(func)) {}
72 PyObject* call(PyObject* args)
const override
74 return impl::callFunction(args, func_);
77 TFunction function()
const {
return func_; }
82class LASS_PYTHON_DLL Function:
public PyObjectPlus
86 using TPimpl = std::unique_ptr<FunctionImplBase>;
88 Function(TPimpl pimpl);
90 template <
typename R,
typename... Args>
91 Function(std::function<R(Args...)> v):
92 Function(TPimpl(new FunctionImpl<R, Args...>(std::move(v))))
96 template <
typename R,
typename... Args>
97 bool get(std::function<R(Args...)>& v)
99 if (
auto p =
dynamic_cast< FunctionImpl<R, Args...
>* >(pimpl_.get()))
107 static PyObject* _tp_call(PyObject* self, PyObject* args, PyObject* kwargs);
109 std::unique_ptr<FunctionImplBase> pimpl_;
112template <
typename R,
typename... Args>
117 callable_(std::move(callable))
121 R operator()(
typename util::CallTraits<Args>::TParam... args)
const
123 LockGIL LASS_UNUSED(lock);
124 LASS_ASSERT(callable_);
125 const TPyObjPtr oArgs = makeTuple(args...);
126 const TPyObjPtr result(PyObject_CallObject(callable_.get(), oArgs.get()));
131 typedef ArgumentTraits<R> TraitsR;
132 typename TraitsR::TStorage temp;
133 if (pyGetSimpleObject(result.get(), temp) != 0)
137 return TraitsR::arg(temp);
140 TPyObjPtr callable()
const {
return callable_; }
169template <
typename R,
typename... Args>
172 static constexpr const char* py_typing =
"Callable[[Args...], R]";
174 static PyObject* build(std::function<R(Args...)> v)
176 using TCallable = impl::Callable<R, Args...>;
177 if (TCallable* p = v.template target<TCallable>())
179 PyObject* r = p->callable().get();
183 return new impl::Function(std::move(v));
185 static int get(PyObject* obj, std::function<R(Args...)>& v)
187 impl::initLassModule();
188 if (PyType_IsSubtype(obj->ob_type, impl::Function::_lassPyClassDef.type()))
190 if (
static_cast<impl::Function*
>(obj)->get(v))
195 if (!PyCallable_Check(obj))
197 PyErr_SetString(PyExc_TypeError,
"Not callable");
200 using TCallable = impl::Callable<R, Args...>;
void fetchAndThrowPythonException(std::string loc)
Fetch the current Python exception and throw it as a C++ PythonException.
PyObjectPtr< PyObject >::Type TPyObjPtr
PyObjectPtr to a PyObject.
#define PY_HEADER(t_parentClass)
Place as first line of your Pythonized class.
lass::util::SharedPtr< T, PyObjectStorage, PyObjectCounter > fromNakedToSharedPtrCast(PyObject *object)
fromNakedToSharedPtrCast.
Comprehensive C++ to Python binding library.
by copy, general case assumes shadow type or PyObjectPlus based type.