// 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.PyTuple_Size(items)); i++ { item := C.PyTuple_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 } else if C.myPyTuple_Check(o) != 0 { length := int(C.PyTuple_Size(o)) list := make([]interface{}, length) for i := 0; i < length; i++ { list[i] = pyObjToInterface(C.PyTuple_GetItem(o, C.Py_ssize_t(i))) } return list } return nil }
//export goClassCallMethod func goClassCallMethod(obj, unused unsafe.Pointer) unsafe.Pointer { // Unpack context and self pointer from obj t := (*C.PyObject)(obj) pyobj := unsafe.Pointer(C.PyTuple_GetItem(t, 0)) m := C.PyCapsule_GetPointer(C.PyTuple_GetItem(t, 1), nil) // Now call the actual struct method by pulling the method out of the // reflect.Type object stored in the context f := (*func(p unsafe.Pointer) (Object, error))(unsafe.Pointer(&m)) ret, err := (*f)(pyobj) if err != nil { raise(err) return nil } return unsafe.Pointer(c(ret)) }
//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() }
//export goClassCallMethodArgs func goClassCallMethodArgs(obj, args unsafe.Pointer) unsafe.Pointer { // Unpack context and self pointer from obj t := (*C.PyObject)(obj) pyobj := unsafe.Pointer(C.PyTuple_GetItem(t, 0)) m := C.PyCapsule_GetPointer(C.PyTuple_GetItem(t, 1), nil) // Get args ready to use, by turning it into a pointer of the appropriate // type a := newTuple((*C.PyObject)(args)) // Now call the actual struct method by pulling the method out of the // reflect.Type object stored in the context f := (*func(p unsafe.Pointer, a *Tuple) (Object, error))(unsafe.Pointer(&m)) ret, err := (*f)(pyobj, a) if err != nil { raise(err) return nil } return unsafe.Pointer(c(ret)) }
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) }
//export goClassGetProp func goClassGetProp(obj, closure unsafe.Pointer) unsafe.Pointer { // Unpack set function from closure t := (*C.PyObject)(closure) m := C.PyCapsule_GetPointer(C.PyTuple_GetItem(t, 0), nil) // Turn the function into something we can call f := (*func(p unsafe.Pointer) (Object, error))(unsafe.Pointer(&m)) ret, err := (*f)(obj) if err != nil { raise(err) return nil } return unsafe.Pointer(c(ret)) }
//export goClassSetProp func goClassSetProp(obj, arg, closure unsafe.Pointer) int { // Unpack set function from closure t := (*C.PyObject)(closure) m := C.PyCapsule_GetPointer(C.PyTuple_GetItem(t, 1), nil) // Turn arg into something usable a := newObject((*C.PyObject)(arg)) // Turn the function into something we can call f := (*func(p unsafe.Pointer, a Object) error)(unsafe.Pointer(&m)) err := (*f)(obj, a) if err != nil { raise(err) return -1 } return 0 }
// PyObject* PyTuple_GetItem(PyObject *p, Py_ssize_t pos) // Return value: Borrowed reference. // Return the object at position pos in the tuple pointed to by p. If pos is out of bounds, return NULL and sets an IndexError exception. // // Changed in version 2.5: This function used an int type for pos. This might require changes in your code for properly supporting 64-bit systems. func PyTuple_GetItem(self *PyObject, pos int) *PyObject { return togo(C.PyTuple_GetItem(topy(self), C.Py_ssize_t(pos))) }
func (t *Tuple) GetItem(pos int64) (Object, error) { ret := C.PyTuple_GetItem(c(t), C.Py_ssize_t(pos)) return obj2ObjErr(ret) }
// Return the object at position pos in the tuple pointed to by p. If pos is out of bounds, // return NULL and sets an IndexError exception. // // Return value: Borrowed reference. func (t *Tuple) GetItem(pos int) (*Base, error) { ret := C.PyTuple_GetItem(t.c(), C.Py_ssize_t(pos)) return obj2ObjErr(ret) }