// NewTuple returns a new *Tuple of the specified size. However the entries are // all set to NULL, so the tuple should not be shared, especially with Python // code, until the entries have all been set. // // Return value: New Reference. func NewTuple(size int64) (*Tuple, error) { ret := C.PyTuple_New(C.Py_ssize_t(size)) if ret == nil { return nil, exception() } return newTuple(ret), nil }
// PackTuple returns a new *Tuple which contains the arguments. This tuple is // ready to use. // // Return value: New Reference. func PackTuple(items ...Object) (*Tuple, error) { ret := C.PyTuple_New(C.Py_ssize_t(len(items))) if ret == nil { return nil, exception() } // Since the ob_item array has a size of 1, Go won't let us index more than // a single entry, and if we try and use our own local type definition with // a flexible array member then cgo converts it to [0]byte which is even // less useful. So, we resort to pointer manipulation - which is // unfortunate, as it's messy in Go. // base is a pointer to the first item in the array of PyObject pointers. // step is the size of a PyObject * (i.e. the number of bytes we need to add // to get to the next item). base := unsafe.Pointer(&(*C.PyTupleObject)(unsafe.Pointer(ret)).ob_item[0]) step := uintptr(C.tupleItemSize()) for _, item := range items { item.Incref() *(**C.PyObject)(base) = c(item) // Move base to point to the next item, by incrementing by step bytes base = unsafe.Pointer(uintptr(base) + step) } return newTuple(ret), nil }
// encodeTuple translates a Go array to a Python object. func encodeTuple(array []interface{}) (pyTuple *C.PyObject, err error) { if len(array) == 0 { pyTuple = pyEmptyTuple C.INCREF(pyTuple) } else { pyTuple = C.PyTuple_New(C.Py_ssize_t(len(array))) var ok bool defer func() { if !ok { C.DECREF(pyTuple) pyTuple = nil } }() for i, item := range array { var pyItem *C.PyObject if pyItem, err = encode(item); err != nil { return } C.Tuple_SET_ITEM(pyTuple, C.Py_ssize_t(i), pyItem) } ok = true } return }
func threadInit() (defaultThreadState *C.PyThreadState) { initLock.Lock() defer initLock.Unlock() if !initialized { C.Py_InitializeEx(0) C.PyEval_InitThreads() C.PySys_SetArgvEx(0, nil, 0) pyEmptyTuple = C.PyTuple_New(0) falseObject = &object{C.False_INCREF()} trueObject = &object{C.True_INCREF()} defaultThreadState = C.PyEval_SaveThread() initialized = true } return }
func GenerateEnviron(r *http.Request) *C.PyObject { _environ := C.PyDict_New() for k, _items := range r.Header { _values_tuple := C.PyTuple_New(C.Py_ssize_t(len(_items))) for i, _item := range _items { C.PyTuple_SetItem( _values_tuple, C.Py_ssize_t(i), PyString_FromString(_item), ) } C.PyDict_SetItem( _environ, PyString_FromString(k), _values_tuple, ) } //_environ = upgrade_to_wsgi(r, _environ) return _environ }
func interfaceToPyObj(o interface{}) *C.PyObject { switch o.(type) { case int: return C.PyInt_FromLong(C.long(o.(int))) case int64: return C.PyInt_FromLong(C.long(o.(int64))) case string: strvalue := C.CString(o.(string)) defer C.free(unsafe.Pointer(strvalue)) return C.PyString_FromStringAndSize(strvalue, C.Py_ssize_t(len(o.(string)))) case map[interface{}]interface{}: dict := C.PyDict_New() for key, value := range o.(map[interface{}]interface{}) { dictAddItem(dict, key, value) } return dict case map[string]string: dict := C.PyDict_New() for key, value := range o.(map[string]string) { dictAddItem(dict, key, value) } return dict case map[string]interface{}: dict := C.PyDict_New() for key, value := range o.(map[string]interface{}) { dictAddItem(dict, key, value) } return dict case []interface{}: list := C.PyTuple_New(C.Py_ssize_t(len(o.([]interface{})))) for i := range o.([]interface{}) { C.PyTuple_SetItem(list, C.Py_ssize_t(i), interfaceToPyObj(o.([]interface{})[i])) } return list default: return C.PyNone() } }
// PyObject* PyTuple_New(Py_ssize_t len) // Return value: New reference. // Return a new tuple object of size len, or NULL on failure. // // Changed in version 2.5: This function used an int type for len. This might require changes in your code for properly supporting 64-bit systems. func PyTuple_New(sz int) *PyObject { return togo(C.PyTuple_New(C.Py_ssize_t(sz))) }
func upgrade_header_to_wsgi(r *http.Request) *C.PyObject { _environ := C.PyDict_New() for k, _items := range r.Header { _values_tuple := C.PyTuple_New(C.Py_ssize_t(len(_items))) for i, _item := range _items { C.PyTuple_SetItem( _values_tuple, C.Py_ssize_t(i), PyString_FromString(_item), ) } // convert header name _k := strings.ToUpper(strings.Replace(k, "-", "_", -1)) C.PyDict_SetItem( _environ, PyString_FromString("HTTP_"+_k), _values_tuple, ) } C.PyDict_SetItem( _environ, PyString_FromString("X_FROM"), PyString_FromString("gowsgi"), ) C.PyDict_SetItem( _environ, PyString_FromString("REQUEST_METHOD"), PyString_FromString(r.Method), ) C.PyDict_SetItem( _environ, PyString_FromString("SCRIPT_NAME"), PyString_FromString(r.URL.Path), ) C.PyDict_SetItem( _environ, PyString_FromString("PATH_INFO"), PyString_FromString(r.URL.Path), ) C.PyDict_SetItem( _environ, PyString_FromString("QUERY_STRING"), PyString_FromString(r.URL.RawQuery), ) C.PyDict_SetItem( _environ, PyString_FromString("CONTENT_TYPE"), PyString_FromString(""), ) C.PyDict_SetItem( _environ, PyString_FromString("CONTENT_LENGTH"), PyString_FromString("0"), ) _host, _port, _ := net.SplitHostPort(r.Host) C.PyDict_SetItem( _environ, PyString_FromString("SERVER_NAME"), PyString_FromString(_host), ) C.PyDict_SetItem( _environ, PyString_FromString("SERVER_PORT"), PyString_FromString(_port), ) C.PyDict_SetItem( _environ, PyString_FromString("SERVER_PROTOCOL"), PyString_FromString(r.Proto), ) C.PyDict_SetItem( _environ, PyString_FromString("wsgi.url_scheme"), PyString_FromString(strings.ToLower(strings.Split(r.Proto, "/")[0])), ) C.PyDict_SetItem( _environ, PyString_FromString("wsgi.multithread"), C.PyBool_FromLong(1), ) C.PyDict_SetItem( _environ, PyString_FromString("wsgi.multiprocess"), C.PyBool_FromLong(1), ) C.PyDict_SetItem( _environ, PyString_FromString("wsgi.run_once"), C.PyBool_FromLong(0), ) return _environ }
// NewTuple returns a new *PyObject of the specified size. However the entries // are all set to NULL, so the tuple should not be shared, especially with // Python code, until the entries have all been set. // // Return value: New Reference. func NewTuple(size int) *Tuple { return (*Tuple)(PyObjectToGO(C.PyTuple_New(C.Py_ssize_t(size)))) }
// NewTuple returns a new *Tuple of the specified size. However the entries are // all set to NULL, so the tuple should not be shared, especially with Python // code, until the entries have all been set. // // Return value: New Reference. func NewTuple(size int) *Tuple { ret := C.PyTuple_New(C.Py_ssize_t(size)) return newTuple(ret) }