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 }
// 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 getFunc(self unsafe.Pointer) interface{} { funcLock.RLock() defer funcLock.RUnlock() idx := int(C.PyInt_AsLong((*C.PyObject)(self))) if idx >= len(funcs) { return nil } return funcs[idx] }
//export goClassNatSet func goClassNatSet(obj unsafe.Pointer, idx int, obj2 unsafe.Pointer) int { field := getField(idx) item := unsafe.Pointer(uintptr(obj) + field.Offset) // This is the new value we are being asked to set value := newObject((*C.PyObject)(obj2)) switch field.Type.Kind() { case reflect.Int: v := int(C.PyInt_AsLong(c(value))) if exceptionRaised() { return -1 } i := (*int)(item) *i = v return 0 } raise(NotImplementedError.ErrV(None)) return -1 }
// long PyInt_AsLong(PyObject *io) // Will first attempt to cast the object to a PyIntObject, if it is not already one, and then return its value. If there is an error, -1 is returned, and the caller should check PyErr_Occurred() to find out whether there was an error, or whether the value just happened to be -1. func PyInt_AsLong(self *PyObject) int { return int(C.PyInt_AsLong(topy(self))) }
func (i *Int) Int() int { return int(C.PyInt_AsLong(c(i))) }