DataDog / go-python3

Go bindings to the CPython-3 API
MIT License
376 stars 140 forks source link

How might I pass in a http.ResponseWriter object as a *PyObject into PyObject_Call? #26

Open lightbaseio opened 4 years ago

lightbaseio commented 4 years ago

Describe what happened: python3.PyTuple_SetItem(tuple, 0, w) testfunc := pyMod.GetAttrString("serve") pyret := testfunc.Call(tuple, ret)

running this results in: cannot use w (type http.ResponseWriter) as type *python3.PyObject in argument to python3.PyTuple_SetItem

Describe what you expected: I did not expect this to work, but would be interested in getting this to work so that http.ResponseWriter.Write could be called within the Python code. Is this possible?

Steps to reproduce the issue:

hush-hush commented 4 years ago

Hi @lightbaseio,

It's possible but this will require some/a lot of wrapping. You need to extend python using CPython and there call any Go function exposed to C. You can't just pass a Go pointer and use it in Python.

In the datadog-agent we don't use this repo (because we want to embed both Python2 and Python3 at the same time, so we need to open shared library dynamically). But you can look into it to get some idea on how to do this.

rtloader is the C bridge between Go and Python: it embed AND extend Python. rtloader/common is where we extend python. For example the python function datadog_agent.get_version is created here https://github.com/DataDog/datadog-agent/blob/master/rtloader/common/builtins/datadog_agent.c#L42. We then call a callback here, that callback is actually a Go function exported to C (the agent at startup init all the callbacks).

We then export Go function to C here for example and init the C callback here.

As you can see embedding python is easy in Go, extending it requires some works.

In you example, I think, the simplest solution would be to create a Python Callable class, that internally store a C pointer and call a C method with that pointer when being called. Then in C you will actually call the Go function.

lightbaseio commented 4 years ago

Thanks for the explanation. My C is rusty but the code makes sense. Will give it a go when I have time!