// decodeMapping translates a Python object to a Go map. func decodeMapping(pyMapping *C.PyObject) (mapping map[interface{}]interface{}, err error) { mapping = make(map[interface{}]interface{}) pyItems := C.Mapping_Items(pyMapping) if pyItems == nil { err = getError() return } length := int(C.PyList_Size(pyItems)) for i := 0; i < length; i++ { pyPair := C.PyList_GetItem(pyItems, C.Py_ssize_t(i)) var ( key interface{} value interface{} ) if key, err = decode(C.PyTuple_GetItem(pyPair, 0)); err != nil { return } if value, err = decode(C.PyTuple_GetItem(pyPair, 1)); err != nil { return } mapping[key] = value } return }
func pyObjToInterface(o *C.PyObject) interface{} { if C.myPyString_Check(o) != 0 { return C.GoStringN(C.PyString_AsString(o), C.int(C.PyString_Size(o))) } else if C.myPyInt_Check(o) != 0 { return int64(C.PyInt_AsLong(o)) } else if C.myPyDict_Check(o) != 0 { v := make(map[interface{}]interface{}) items := C.PyDict_Items(o) for i := 0; i < int(C.PyList_Size(items)); i++ { item := C.PyList_GetItem(items, C.Py_ssize_t(i)) key := C.PyTuple_GetItem(item, 0) value := C.PyTuple_GetItem(item, 1) v[pyObjToInterface(key)] = pyObjToInterface(value) } C.Py_DecRef(items) return v } return nil }
//export createThreadCallback func createThreadCallback(pid *C.pthread_t) { runtime.LockOSThread() defer runtime.UnlockOSThread() _gstate := C.start_thread() _cb, _r, _w, _ok := callbacks.Get(pid) defer callbacks.Delete(pid) if !_ok { panic(fmt.Errorf("failed to found thread callback for `%v`", pid)) } // TODO: add special headers for WSGI. _environ := GenerateEnviron(_r) _response := C.run_wsgi_application(_environ) // parse header for i := 0; i < int(C.PyList_Size(_response.headers)); i++ { _h := C.PyList_GetItem(_response.headers, C.Py_ssize_t(i)) _k := C.PyTuple_GetItem(_h, C.Py_ssize_t(0)) _v := C.PyTuple_GetItem(_h, C.Py_ssize_t(1)) _w.Header().Set( PyString_AsString(_k), PyString_AsString(_v), ) } _body := C.GoString(_response.body) if len(_body) < 1 { panic(fmt.Errorf("failed to import python wsgi module.")) } C.end_thread(_gstate) // write body _w.WriteHeader(int(_response.status)) _w.Write([]byte(_body)) _cb() }
func wsgi_callback(r *http.Request, w http.ResponseWriter) { _environ := upgrade_header_to_wsgi(r) _body_request, _ := ioutil.ReadAll(r.Body) _body_c := C.CString(string(_body_request)) defer C.free(unsafe.Pointer(_body_c)) _response := C.run_wsgi_application(_body_c, _environ) defer func() { C.Py_DecRef(_response.body) C.Py_DecRef(_response.headers) C.Py_DecRef(_response.error) }() if _response.headers == nil || int(_response.status) == 0 { w.WriteHeader(500) log_wsgi.Error("failed to run python wsgi module.") return } // parse header for i := 0; i < int(C.PyList_Size(_response.headers)); i++ { _h := C.PyList_GetItem(_response.headers, C.Py_ssize_t(i)) _k := C.PyTuple_GetItem(_h, C.Py_ssize_t(0)) _v := C.PyTuple_GetItem(_h, C.Py_ssize_t(1)) w.Header().Set( PyString_AsString(_k), PyString_AsString(_v), ) } // write body w.WriteHeader(int(_response.status)) if _response.body == nil { return } write_response_body(w, _response.body) }
// PyObject* PyList_GetItem(PyObject *list, Py_ssize_t index) // Return value: Borrowed reference. // Return the object at position pos in the list pointed to by p. The position must be positive, indexing from the end of the list is not supported. If pos is out of bounds, return NULL and set an IndexError exception. // // Changed in version 2.5: This function used an int for index. This might require changes in your code for properly supporting 64-bit systems. func PyList_GetItem(self *PyObject, index int) *PyObject { return togo(C.PyList_GetItem(topy(self), C.Py_ssize_t(index))) }
// GetItem returns the Object contained in list l at index idx. If idx is out // of bounds for l, then an IndexError will be returned. // // Return value: Borrowed Reference. func (l *List) GetItem(idx int64) (Object, error) { ret := C.PyList_GetItem(c(l), C.Py_ssize_t(idx)) return obj2ObjErr(ret) }