> On 5 Jan 2020, at 22:20, hrfu...@gmail.com wrote:
> 
> The C API has a function PyObject_CallFunction( PyObject*, const char* fmt, 
> ... ). It is a variadic function hence I couldn't pass a va_list to it to 
> invoke the call. My question is, is it technically possible to provide a 
> companion PyObject_VaCallFunction which takes a va_list, just like 
> Py_VaBuildValue is to Py_BuildValue?
> 
> Here's what I have found so far. I read the Objects/call.c about 
> PyObject_CallFunction there, and actually found a function 
> _PyObject_CallFunctionVa, which is close to what I want, although it has two 
> additional parameters. By taking a look at the implementation of 
> PyObject_CallFunction, naively I was thinking a Va version of that could have 
> been similarly implemented ( I'm ignoring the size_t issue ). I'd appreciate 
> it if someone could enlighten me on this subject. Question rephrased: is 
> there a technical reason why there is no PyObject_VaCallFunction in the API? 
> If not, would it be possible to add it in?
> 
> Motivation: I write scientific simulation code to be run on large clusters. 
> The data generated can be huge. Although I know parallelization using C++, I 
> don't know it using Python. A direct consequence is formidable data 
> processing time with python, which is driving me nuts. I have two options, 
> either parallelize python code or embed the python in C++. I'm favoring the 
> latter, not just because I don't know about python parallelization, but more 
> importantly because by embedding python in C++, I get to keep using the 
> highly specialized C++ classes and some calculation routines, without having 
> to duplicate essentially the same thing in Python, which is very time-saving. 
> I could have just used the C API, but here is the all-time drawback of 
> linking with Python libraries --- it messes up the linker runtime search 
> path. Usually a Python installation has under its lib/ many common libraries 
> such as libz.so, libhdf5.so ( or I probably should have said earlier that I 
> primarily work on Linux )
> . They have different versions to, say, the libhdf5.so I'm using in the code. 
> The upshot is that by linking my program with both the major library in which 
> HDF5 links to one version, and the Python libraries in which HDF5 links to 
> another, the runtime search path is always mixed up, which is not safe. 
> 
> So what I thought about doing is that I'm gonna create a C++ wrapper on 
> Python, one that doesn't expose the raw Python to the client code at all. ( 
> For example, there is no #include <Python.h> in any header of that library. 
> Plus I could use C++ OOP to automate away keeping tracking of 
> Py_INCREF/Py_DECREF. ) In fact it's very doable. Everything is 
> straightforward, except variadic functions, such as PyObject_CallFunction, 
> Py_BuildValue, and so on. Let me use PyObject_CallFunction to illustrate the 
> problem.
> 
> Let's say that I want to provide a wrapper to PyObject_CallFunction to the 
> client, like this ( I'm taking the return type to void for simplicity )
> void MyCallFunction(PyObject* obj, const char* fmt, ... );
> I go ahead and put this line in the header "my_python_wrapper.h". Then in the 
> "my_python_wrapper.c" file I would like to write the following implementation.
> void MyCallFunction(PyObject* obj, const char* fmt, ... ) {
> va_list args;
> va_start(args,fmt);
> PyObject(obj, fmt, args);  // This function doesn't exist in the API ( yet? )
> va_end(args);
> }
> This way, only the "my_python_wrapper.c" needs to link with Python Libraries. 
> Any user of my_python_wrapper doesn't need to, which seems nice. ( In cmake 
> lingo, I only need to target_link_libraries( my_python_wrapper PRIVATE 
> ${PYTHON_LIBRARIES} ), instead of PUBLIC ) As one can see, the crux is that 
> not all variadic functions in the API has a companion Va-ed version. So far I 
> only found Py_VaBuildValue. 
> 
> I've worked out MyCallFunction() in my actual code in the same manner 
> described above, but with Py_VaBuildValue. What I did was I send all variadic 
> arguments to a MyBuildValue(PyObject*, const char*, ...), the in the .c file, 
> MyBuildValue will generate a va_list and pass it onto Py_VaBuildValue, then I 
> force the outcome to be a tuple and pass it to PyObject_CallObject and it 
> works! Nontheless, this approach seems less straightforward to having a 
> PyObject_VaCallFunction, so I'm guessing it may have performance penalty.
> 
> I really appreciate it whoever takes their time to read this essay of mine! I 
> apologize if I failed to use the idiomatic mark-up. Any comments, questions 
> on this subject are welcome!

I'm wondering if the PyCXX project would help you.

"PyCXX is a set of classes to help create extensions of Python in the C++ 
language.
The first part encapsulates the Python C API taking care of exceptions and ref 
counting. 
The second part supports the building of Python extension modules in C++."

Project page: https://sourceforge.net/projects/cxx/ 
<https://sourceforge.net/projects/cxx/>
Python2 docs: http://cxx.sourceforge.net/PyCXX-Python3.html 
<http://cxx.sourceforge.net/PyCXX-Python3.html>

Let me know if I can help, I maintain PyCXX.

Barry



> _______________________________________________
> Python-ideas mailing list -- python-ideas@python.org
> To unsubscribe send an email to python-ideas-le...@python.org
> https://mail.python.org/mailman3/lists/python-ideas.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-ideas@python.org/message/VHAUIILV3I7PULKZVILUVY5JEDK6OR2B/
> Code of Conduct: http://python.org/psf/codeofconduct/
> 

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/66K5MFYL7PIJ3WPCR7DMDXHAIHC47W24/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to