Update error API for high level to expose Go error
parent
16c451d086
commit
dd07c4aa3b
|
@ -0,0 +1,27 @@
|
|||
go-python3
|
||||
==========
|
||||
|
||||
Golang bindings for the C-API of CPython-3.
|
||||
|
||||
This package provides a ``go`` package named "python" under which most of the
|
||||
``PyXYZ`` functions and macros of the public C-API of CPython have been
|
||||
exposed. Theoretically, you should be able use https://docs.python.org/3/c-api
|
||||
and know what to type in your ``go`` program.
|
||||
|
||||
API
|
||||
---
|
||||
|
||||
Some functions mix go code and call to Python function. Those functions will
|
||||
return and `int` and `error` type. The `int` represent the Python result code
|
||||
and the `error` represent any issue from the Go layer.
|
||||
|
||||
Example:
|
||||
|
||||
`func PyRun_AnyFile(filename string)` open `filename` and then call CPython API
|
||||
function `int PyRun_AnyFile(FILE *fp, const char *filename)`.
|
||||
|
||||
Therefore its signature is `func PyRun_AnyFile(filename string) (int, error)`,
|
||||
the `int` represent the error code from the CPython `PyRun_AnyFile` function
|
||||
and error will be set if we failed to open `filename`.
|
||||
|
||||
If an error is raise before calling th CPython function `int` default to `-1`.
|
|
@ -10,7 +10,8 @@ import (
|
|||
)
|
||||
|
||||
//Py_Main : https://docs.python.org/3/c-api/veryhigh.html?highlight=pycompilerflags#c.Py_Main
|
||||
func Py_Main(args []string) int {
|
||||
// "error" will be set if we fail to call "Py_DecodeLocale" on every "args".
|
||||
func Py_Main(args []string) (int, error) {
|
||||
argc := C.int(len(args))
|
||||
argv := make([]*C.wchar_t, argc, argc)
|
||||
for i, arg := range args {
|
||||
|
@ -19,32 +20,33 @@ func Py_Main(args []string) int {
|
|||
|
||||
warg := C.Py_DecodeLocale(carg, nil)
|
||||
if warg == nil {
|
||||
return -1
|
||||
return -1, fmt.Errorf("fail to call Py_DecodeLocale on '%s'", arg)
|
||||
}
|
||||
// Py_DecodeLocale requires a call to PyMem_RawFree to free the memory
|
||||
defer C.PyMem_RawFree(unsafe.Pointer(warg))
|
||||
argv[i] = warg
|
||||
}
|
||||
|
||||
return int(C.Py_Main(argc, (**C.wchar_t)(unsafe.Pointer(&argv[0]))))
|
||||
return int(C.Py_Main(argc, (**C.wchar_t)(unsafe.Pointer(&argv[0])))), nil
|
||||
}
|
||||
|
||||
//PyRun_AnyFile : https://docs.python.org/3/c-api/veryhigh.html?highlight=pycompilerflags#c.PyRun_AnyFile
|
||||
func PyRun_AnyFile(filename string) int {
|
||||
// "error" will be set if we fail to open "filename".
|
||||
func PyRun_AnyFile(filename string) (int, error) {
|
||||
cfilename := C.CString(filename)
|
||||
defer C.free(unsafe.Pointer(cfilename))
|
||||
|
||||
mode := C.CString("r")
|
||||
defer C.free(unsafe.Pointer(mode))
|
||||
|
||||
cfile := C.fopen(cfilename, mode)
|
||||
if cfile == nil {
|
||||
return 1
|
||||
cfile, err := C.fopen(cfilename, mode)
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("fail to open '%s': %s", filename, err)
|
||||
}
|
||||
defer C.fclose(cfile)
|
||||
|
||||
// C.PyRun_AnyFile is a macro, using C.PyRun_AnyFileFlags instead
|
||||
return int(C.PyRun_AnyFileFlags(cfile, cfilename, nil))
|
||||
return int(C.PyRun_AnyFileFlags(cfile, cfilename, nil)), nil
|
||||
}
|
||||
|
||||
//PyRun_SimpleString : https://docs.python.org/3/c-api/veryhigh.html?highlight=pycompilerflags#c.PyRun_SimpleString
|
||||
|
|
Loading…
Reference in New Issue