func main() { log.Info("python embedding test in golang, using `pthreads`.") n := 400 var _wg sync.WaitGroup _wg.Add(n) for i := 0; i < n; i++ { go create_thread(func(result *C.PyObject) { defer _wg.Done() _result_string := C.GoString(C.PyString_AsString(result)) log.Debug("< got result string: %v (%T)", _result_string, _result_string) var _parsed []interface{} if _err := json.Unmarshal([]byte(_result_string), &_parsed); _err != nil { panic(fmt.Errorf("got invalid result from python function, `%v`", _result_string)) } log.Debug( "< got thread_id=%v\tnow=%s", int64(_parsed[0].(float64)), _parsed[1].(string), ) }) } _wg.Wait() }
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 }
func write_response_body(w http.ResponseWriter, iterator *C.PyObject) { _iterator := C.PyObject_GetIter(iterator) defer func() { C.Py_DecRef(_iterator) C.Py_DecRef(iterator) }() if _iterator == nil { return } for { item := C.PyIter_Next(_iterator) if item == nil || C._PyString_Check(item) != 1 { C.Py_DecRef(item) break } length := C.PyString_Size(item) if length < 1 { C.Py_DecRef(item) break } _s := C.PyString_AsString(item) w.Write([]byte(C.GoString(_s))) C.Py_DecRef(item) } }
func (s *String) String() string { if s == nil { return "<nil>" } ret := C.PyString_AsString(s.c()) return C.GoString(ret) }
func (t *Type) String() string { pyS := C.PyObject_Str(c(t)) if pyS == nil { return "<unknown type>" } return C.GoString(C.PyString_AsString(pyS)) }
// decodeType translates a Python object to a Go value. Its type must be // non-zero. func decodeType(pyType C.int, pyValue *C.PyObject) (value interface{}, err error) { switch pyType { case 0: err = getError() case 1: // nil case 2: value = false case 3: value = true case 4: value = C.GoString(C.PyString_AsString(pyValue)) case 5: value = int(C.PyInt_AsLong(pyValue)) case 6: var overflow C.int i := int64(C.PyLong_AsLongLongAndOverflow(pyValue, &overflow)) switch overflow { case -1: err = fmt.Errorf("Python integer %s is too small", stringify(pyValue)) case 0: value = i case 1: n := uint64(C.PyLong_AsUnsignedLongLong(pyValue)) if n == 0xffffffffffffffff { C.PyErr_Clear() err = fmt.Errorf("Python integer %s is too large", stringify(pyValue)) } else { value = n } } case 7: value = float64(C.PyFloat_AsDouble(pyValue)) case 8: value = complex(C.PyComplex_RealAsDouble(pyValue), C.PyComplex_ImagAsDouble(pyValue)) case 9: return decodeSequence(pyValue) case 10: return decodeMapping(pyValue) default: err = fmt.Errorf("unable to translate %s from Python", stringify(C.PyObject_Type(pyValue))) return } return }
func (s *String) String() string { if s == nil { return "<nil>" } ret := C.PyString_AsString(c(s)) if ret == nil { panic(exception()) } return C.GoString(ret) }
// Error() returns a string representation of the Python exception represented // by the Error e. This is the same as the final line of the Python output from // an uncaught exception. func (e *Error) Error() string { ts := "" en := C.excName(c(e.Kind)) if en.c == nil { tpyS := C.PyObject_Str(c(e.Kind)) defer C.decref(tpyS) ts = C.GoString(C.PyString_AsString(tpyS)) } else { if en.m != nil { ts = C.GoString(en.m) + "." } ts += C.GoString(en.c) } pyS := C.PyObject_Str(c(e.Value)) defer C.decref(pyS) s := C.GoString(C.PyString_AsString(pyS)) return fmt.Sprintf("%s: %s", ts, s) }
func stringify(pyObject *C.PyObject) (s string) { if pyResult := C.PyObject_Str(pyObject); pyResult != nil { defer C.DECREF(pyResult) if cString := C.PyString_AsString(pyResult); cString != nil { s = C.GoString(cString) } } C.PyErr_Clear() return }
func PickleDumps(v interface{}) []byte { pickleLock.Lock() if initialized == 0 { pickleInit() } obj := interfaceToPyObj(v) str := C.PyObject_CallFunction2(pickleDumps, obj, highestProtocol) gobytes := C.GoBytes(unsafe.Pointer(C.PyString_AsString(str)), C.int(C.PyString_Size(str))) C.Py_DecRef(obj) C.Py_DecRef(str) pickleLock.Unlock() return gobytes }
func (u *Unicode) String() string { if u == nil { return "<nil>" } s := C.PyUnicode_AsUTF8String(c(u)) if s == nil { panic(exception()) } defer C.decref(s) ret := C.PyString_AsString(s) if ret == nil { panic(exception()) } return C.GoString(ret) }
func main() { logging.SetLevel(logging.INFO, "pyingo") logging.SetLevel(logging.DEBUG, "pyingo") log.Info("main") python := pyingo.NewPython(1) _result, _err := python.Run("json_dumps:run") _unsafed := (*C.PyObject)(unsafe.Pointer(_result.Ptr)) fmt.Printf(" C.PyString_AsString: %s, %T\n", C.GoString(C.PyString_AsString(_unsafed)), _unsafed) fmt.Printf("pyingo.PyString_AsString: %s, %T\n", pyingo.PyString_AsString(_result), _unsafed) fmt.Printf("result: %v, err: %v\n", _result, _err) }
func PyString_AsString(s *C.PyObject) string { return C.GoString(C.PyString_AsString(s)) }
// char* PyString_AsString(PyObject *string) // Return a NUL-terminated representation of the contents of string. The pointer refers to the internal buffer of string, not a copy. The data must not be modified in any way, unless the string was just created using PyString_FromStringAndSize(NULL, size). It must not be deallocated. If string is a Unicode object, this function computes the default encoding of string and operates on that. If string is not a string object at all, PyString_AsString() returns NULL and raises TypeError. func PyString_AsString(self *PyObject) string { c_str := C.PyString_AsString(self.ptr) // we dont own c_str... //defer C.free(unsafe.Pointer(c_str)) return C.GoString(c_str) }
func PyString_AsString(s *PyObject) string { return C.GoString(C.PyString_AsString(s.Ptr)) }