Esempio n. 1
0
// 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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
// getError translates the current Python exception to a Go error, and clears
// the Python exception state.
func getError() error {
	var (
		pyType  *C.PyObject
		pyValue *C.PyObject
		pyTrace *C.PyObject
	)

	C.PyErr_Fetch(&pyType, &pyValue, &pyTrace)

	defer C.DECREF(pyType)
	defer C.DECREF(pyValue)
	defer xDECREF(pyTrace)

	C.PyErr_Clear()

	return fmt.Errorf("Python: %s", stringify(pyValue))
}
Esempio n. 4
0
// void PyErr_Clear()
// Clear the error indicator. If the error indicator is not set, there is no effect.
func PyErr_Clear() {
	C.PyErr_Clear()
}