diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..06b518b --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,33 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" + name = "github.com/davecgh/go-spew" + packages = ["spew"] + pruneopts = "UT" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" + +[[projects]] + digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" + name = "github.com/pmezard/go-difflib" + packages = ["difflib"] + pruneopts = "UT" + revision = "792786c7400a136282c1664665ae0a8db921c6c2" + version = "v1.0.0" + +[[projects]] + digest = "1:18752d0b95816a1b777505a97f71c7467a8445b8ffb55631a7bf779f6ba4fa83" + name = "github.com/stretchr/testify" + packages = ["assert"] + pruneopts = "UT" + revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686" + version = "v1.2.2" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + input-imports = ["github.com/stretchr/testify/assert"] + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..844c8e7 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,7 @@ +[prune] + go-tests = true + unused-packages = true + +[[constraint]] + name = "github.com/stretchr/testify" + version = "1.2.2" diff --git a/boolean.go b/boolean.go new file mode 100644 index 0000000..33fba38 --- /dev/null +++ b/boolean.go @@ -0,0 +1,27 @@ +package python3 + +/* +#include "Python.h" +#include "macro.h" +#include "type.h" +*/ +import "C" + +//python boolean constants +var ( + Py_False = togo(C.Py_False) + Py_True = togo(C.Py_True) +) + +//Bool : https://docs.python.org/3/c-api/bool.html#c.PyBool_Type +var Bool = togo(C._go_PyBool_Type) + +//PyBool_Check : https://docs.python.org/3/c-api/bool.html#c.PyBool_Check +func PyBool_Check(o *PyObject) bool { + return C._go_PyBool_Check(toc(o)) != 0 +} + +//PyBool_FromLong : https://docs.python.org/3/c-api/bool.html#c.PyBool_FromLong +func PyBool_FromLong(v int) *PyObject { + return togo(C.PyBool_FromLong(C.long(v))) +} diff --git a/boolean_test.go b/boolean_test.go new file mode 100644 index 0000000..7eee22a --- /dev/null +++ b/boolean_test.go @@ -0,0 +1,21 @@ +package python3 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBoolCheck(t *testing.T) { + Py_Initialize() + + assert.True(t, PyBool_Check(Py_True)) + assert.True(t, PyBool_Check(Py_False)) +} + +func TestBoolFromLong(t *testing.T) { + Py_Initialize() + + assert.Equal(t, Py_True, PyBool_FromLong(1)) + assert.Equal(t, Py_False, PyBool_FromLong(0)) +} diff --git a/dict.go b/dict.go new file mode 100644 index 0000000..35ff74c --- /dev/null +++ b/dict.go @@ -0,0 +1,121 @@ +package python3 + +/* +#include "Python.h" +#include "macro.h" +#include "type.h" +*/ +import "C" +import ( + "unsafe" +) + +//Dict : https://docs.python.org/3/c-api/dict.html#c.PyDict_Type +var Dict = togo(C._go_PyDict_Type) + +//PyDict_Check : https://docs.python.org/3/c-api/dict.html#c.PyDict_Check +func PyDict_Check(p *PyObject) bool { + return C._go_PyDict_Check(toc(p)) != 0 +} + +//PyDict_CheckExact : https://docs.python.org/3/c-api/dict.html#c.PyDict_CheckExact +func PyDict_CheckExact(p *PyObject) bool { + return C._go_PyDict_CheckExact(toc(p)) != 0 +} + +//PyDict_New : https://docs.python.org/3/c-api/dict.html#c.PyDict_New +func PyDict_New() *PyObject { + return togo(C.PyDict_New()) +} + +//PyDictProxy_New : https://docs.python.org/3/c-api/dict.html#c.PyDictProxy_New +func PyDictProxy_New(mapping *PyObject) *PyObject { + return togo(C.PyDictProxy_New(toc(mapping))) +} + +//PyDict_Clear : https://docs.python.org/3/c-api/dict.html#c.PyDict_Clear +func PyDict_Clear(p *PyObject) { + C.PyDict_Clear(toc(p)) +} + +//PyDict_Contains : https://docs.python.org/3/c-api/dict.html#c.PyDict_Contains +func PyDict_Contains(p, key *PyObject) int { + return int(C.PyDict_Contains(toc(p), toc(key))) +} + +//PyDict_Copy : https://docs.python.org/3/c-api/dict.html#c.PyDict_Copy +func PyDict_Copy(p *PyObject) *PyObject { + return togo(C.PyDict_Copy(toc(p))) +} + +//PyDict_SetItem : https://docs.python.org/3/c-api/dict.html#c.PyDict_SetItem +func PyDict_SetItem(p, key, val *PyObject) int { + return int(C.PyDict_SetItem(toc(p), toc(key), toc(val))) +} + +//PyDict_SetItemString : https://docs.python.org/3/c-api/dict.html#c.PyDict_SetItemString +func PyDict_SetItemString(p *PyObject, key string, val *PyObject) int { + ckey := C.CString(key) + defer C.free(unsafe.Pointer(ckey)) + return int(C.PyDict_SetItemString(toc(p), ckey, toc(val))) +} + +//PyDict_DelItem : https://docs.python.org/3/c-api/dict.html#c.PyDict_DelItem +func PyDict_DelItem(p, key *PyObject) int { + return int(C.PyDict_DelItem(toc(p), toc(key))) +} + +//PyDict_DelItemString : https://docs.python.org/3/c-api/dict.html#c.PyDict_DelItemString +func PyDict_DelItemString(p *PyObject, key string) int { + ckey := C.CString(key) + defer C.free(unsafe.Pointer(ckey)) + return int(C.PyDict_DelItemString(toc(p), ckey)) +} + +//PyDict_GetItem : https://docs.python.org/3/c-api/dict.html#c.PyDict_GetItem +func PyDict_GetItem(p, key *PyObject) *PyObject { + return togo(C.PyDict_GetItem(toc(p), toc(key))) +} + +//PyDict_GetItemWithError : https://docs.python.org/3/c-api/dict.html#c.PyDict_GetItemWithError +func PyDict_GetItemWithError(p, key *PyObject) *PyObject { + return togo(C.PyDict_GetItemWithError(toc(p), toc(key))) +} + +//PyDict_GetItemString : https://docs.python.org/3/c-api/dict.html#c.PyDict_GetItemString +func PyDict_GetItemString(p *PyObject, key string) *PyObject { + ckey := C.CString(key) + defer C.free(unsafe.Pointer(ckey)) + + return togo(C.PyDict_GetItemString(toc(p), ckey)) +} + +//PyDict_SetDefault : https://docs.python.org/3/c-api/dict.html#c.PyDict_SetDefault +func PyDict_SetDefault(p, key, pyDefault *PyObject) *PyObject { + return togo(C.PyDict_SetDefault(toc(p), toc(key), toc(pyDefault))) +} + +//PyDict_Items : https://docs.python.org/3/c-api/dict.html#c.PyDict_Items +func PyDict_Items(p *PyObject) *PyObject { + return togo(C.PyDict_Items(toc(p))) +} + +//PyDict_Keys : https://docs.python.org/3/c-api/dict.html#c.PyDict_Keys +func PyDict_Keys(p *PyObject) *PyObject { + return togo(C.PyDict_Keys(toc(p))) +} + +//PyDict_Values : https://docs.python.org/3/c-api/dict.html#c.PyDict_Values +func PyDict_Values(p *PyObject) *PyObject { + return togo(C.PyDict_Values(toc(p))) +} + +//PyDict_Size : https://docs.python.org/3/c-api/dict.html#c.PyDict_Size +func PyDict_Size(p *PyObject) int { + return int(C.PyDict_Size(toc(p))) +} + +//PyDict_ClearFreeList : https://docs.python.org/3/c-api/dict.html#c.PyDict_ClearFreeList +func PyDict_ClearFreeList() int { + return int(C.PyDict_ClearFreeList()) +} diff --git a/dict_test.go b/dict_test.go new file mode 100644 index 0000000..2b06c84 --- /dev/null +++ b/dict_test.go @@ -0,0 +1,89 @@ +package python3 + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDict(t *testing.T) { + Py_Initialize() + + dict := PyDict_New() + assert.True(t, PyDict_Check(dict)) + assert.True(t, PyDict_CheckExact(dict)) + defer dict.DecRef() + + proxy := PyDictProxy_New(dict) + assert.NotNil(t, proxy) + proxy.DecRef() + + key1 := "key1" + value1 := PyUnicode_FromString("value1") + assert.NotNil(t, value1) + defer value1.DecRef() + + key2 := PyUnicode_FromString("key2") + assert.NotNil(t, key2) + defer key2.DecRef() + value2 := PyUnicode_FromString("value2") + assert.NotNil(t, value2) + defer value2.DecRef() + + key3 := PyUnicode_FromString("key3") + assert.NotNil(t, key3) + defer key3.DecRef() + value3 := PyUnicode_FromString("value3") + assert.NotNil(t, value3) + defer value3.DecRef() + + err := PyDict_SetItem(dict, key2, value2) + assert.Zero(t, err) + + err = PyDict_SetItemString(dict, key1, value1) + assert.Zero(t, err) + + assert.Equal(t, value2, PyDict_GetItem(dict, key2)) + assert.Equal(t, value2, PyDict_SetDefault(dict, key2, Py_None)) + assert.Equal(t, value1, PyDict_GetItemString(dict, key1)) + assert.Nil(t, PyDict_GetItemWithError(dict, key3)) + b := PyDict_Contains(dict, key2) != 0 + assert.True(t, b) + + assert.Equal(t, 2, PyDict_Size(dict)) + + keys := PyDict_Keys(dict) + assert.True(t, PyList_Check(keys)) + keys.DecRef() + + values := PyDict_Values(dict) + assert.True(t, PyList_Check(values)) + values.DecRef() + + items := PyDict_Items(dict) + assert.True(t, PyList_Check(items)) + items.DecRef() + + err = PyDict_SetItem(dict, key3, value3) + assert.Zero(t, err) + + newDict := PyDict_Copy(dict) + assert.Equal(t, 3, PyDict_Size(newDict)) + defer newDict.DecRef() + + err = PyDict_DelItem(dict, key2) + assert.Zero(t, err) + + err = PyDict_DelItemString(dict, key1) + assert.Zero(t, err) + + assert.Equal(t, 1, PyDict_Size(dict)) + + PyDict_Clear(dict) + assert.Equal(t, 0, PyDict_Size(dict)) + + dict.DecRef() + + PyDict_ClearFreeList() + +} diff --git a/helper.go b/helper.go new file mode 100644 index 0000000..7d6261a --- /dev/null +++ b/helper.go @@ -0,0 +1,16 @@ +package python3 + +//go:generate go run script/variadic.go + +//#include "Python.h" +import "C" + +//togo converts a *C.PyObject to a *PyObject +func togo(cobject *C.PyObject) *PyObject { + return (*PyObject)(cobject) +} + +func toc(object *PyObject) *C.PyObject { + return (*C.PyObject)(object) +} + diff --git a/integer.go b/integer.go new file mode 100644 index 0000000..704c328 --- /dev/null +++ b/integer.go @@ -0,0 +1,136 @@ +package python3 + +/* +#include "Python.h" +#include "macro.h" +#include "type.h" +*/ +import "C" +import ( + "unsafe" +) + +//Long : https://docs.python.org/3/c-api/long.html#c.PyLong_Type +var Long = togo(C._go_PyLong_Type) + +//PyLong_Check : https://docs.python.org/3/c-api/long.html#c.PyLong_Check +func PyLong_Check(p *PyObject) bool { + return C._go_PyLong_Check(toc(p)) != 0 +} + +//PyLong_CheckExact : https://docs.python.org/3/c-api/long.html#c.PyLong_CheckExact +func PyLong_CheckExact(p *PyObject) bool { + return C._go_PyLong_CheckExact(toc(p)) != 0 +} + +//PyLong_FromLong : https://docs.python.org/3/c-api/long.html#c.PyLong_FromLong +func PyLong_FromLong(v int) *PyObject { + return togo(C.PyLong_FromLong(C.long(v))) +} + +//PyLong_FromUnsignedLong : https://docs.python.org/3/c-api/long.html#c.PyLong_FromUnsignedLong +func PyLong_FromUnsignedLong(v uint) *PyObject { + return togo(C.PyLong_FromUnsignedLong(C.ulong(v))) +} + +//PyLong_FromLongLong : https://docs.python.org/3/c-api/long.html#c.PyLong_FromLongLong +func PyLong_FromLongLong(v int64) *PyObject { + return togo(C.PyLong_FromLongLong(C.longlong(v))) +} + +//PyLong_FromUnsignedLongLong : https://docs.python.org/3/c-api/long.html#c.PyLong_FromUnsignedLongLong +func PyLong_FromUnsignedLongLong(v uint64) *PyObject { + return togo(C.PyLong_FromUnsignedLongLong(C.ulonglong(v))) +} + +//PyLong_FromDouble : https://docs.python.org/3/c-api/long.html#c.PyLong_FromDouble +func PyLong_FromDouble(v float64) *PyObject { + return togo(C.PyLong_FromDouble(C.double(v))) +} + +//PyLong_FromString : https://docs.python.org/3/c-api/long.html#c.PyLong_FromString +func PyLong_FromString(str string, base int) *PyObject { + cstr := C.CString(str) + defer C.free(unsafe.Pointer(cstr)) + + return togo(C.PyLong_FromString(cstr, nil, C.int(base))) +} + +//PyLong_FromUnicodeObject : https://docs.python.org/3/c-api/long.html#c.PyLong_FromUnicodeObject +func PyLong_FromUnicodeObject(u *PyObject, base int) *PyObject { + return togo(C.PyLong_FromUnicodeObject(toc(u), C.int(base))) +} + +//PyLong_FromGoInt ensures the go integer type does not overflow +func PyLong_FromGoInt(v int) *PyObject { + return togo(C.PyLong_FromLongLong(C.longlong(v))) +} + +//PyLong_FromGoUint ensures the go integer type does not overflow +func PyLong_FromGoUint(v uint) *PyObject { + return togo(C.PyLong_FromUnsignedLongLong(C.ulonglong(v))) +} + +//PyLong_FromGoInt64 ensures the go integer type does not overflow +func PyLong_FromGoInt64(v int64) *PyObject { + return togo(C.PyLong_FromLongLong(C.longlong(v))) +} + +//PyLong_FromGoUint64 ensures the go integer type does not overflow +func PyLong_FromGoUint64(v uint64) *PyObject { + return togo(C.PyLong_FromUnsignedLongLong(C.ulonglong(v))) +} + +//PyLong_FromGoFloat64 ensures the go integer type does not overflow +func PyLong_FromGoFloat64(v float64) *PyObject { + return togo(C.PyLong_FromDouble(C.double(v))) +} + +//PyLong_AsLong : https://docs.python.org/3/c-api/long.html#c.PyLong_AsLong +func PyLong_AsLong(obj *PyObject) int { + return int(C.PyLong_AsLong(toc(obj))) +} + +//PyLong_AsLongAndOverflow : https://docs.python.org/3/c-api/long.html#c.PyLong_AsLongAndOverflow +func PyLong_AsLongAndOverflow(obj *PyObject) (int, int) { + overflow := C.int(0) + ret := C.PyLong_AsLongAndOverflow(toc(obj), &overflow) + return int(ret), int(overflow) +} + +//PyLong_AsLongLong : https://docs.python.org/3/c-api/long.html#c.PyLong_AsLongLong +func PyLong_AsLongLong(obj *PyObject) int64 { + return int64(C.PyLong_AsLongLong(toc(obj))) +} + +//PyLong_AsLongLongAndOverflow : https://docs.python.org/3/c-api/long.html#c.PyLong_AsLongLongAndOverflow +func PyLong_AsLongLongAndOverflow(obj *PyObject) (int64, int) { + overflow := C.int(0) + ret := C.PyLong_AsLongLongAndOverflow(toc(obj), &overflow) + return int64(ret), int(overflow) +} + +//PyLong_AsUnsignedLong : https://docs.python.org/3/c-api/long.html#c.PyLong_AsUnsignedLong +func PyLong_AsUnsignedLong(obj *PyObject) uint { + return uint(C.PyLong_AsUnsignedLong(toc(obj))) +} + +//PyLong_AsUnsignedLongLong : https://docs.python.org/3/c-api/long.html#c.PyLong_AsUnsignedLongLong +func PyLong_AsUnsignedLongLong(obj *PyObject) uint64 { + return uint64(C.PyLong_AsUnsignedLongLong(toc(obj))) +} + +//PyLong_AsUnsignedLongMask : https://docs.python.org/3/c-api/long.html#c.PyLong_AsUnsignedLongMask +func PyLong_AsUnsignedLongMask(obj *PyObject) uint { + return uint(C.PyLong_AsUnsignedLongMask(toc(obj))) +} + +//PyLong_AsUnsignedLongLongMask : https://docs.python.org/3/c-api/long.html#c.PyLong_AsUnsignedLongLongMask +func PyLong_AsUnsignedLongLongMask(obj *PyObject) uint64 { + return uint64(C.PyLong_AsUnsignedLongLongMask(toc(obj))) +} + +//PyLong_AsDouble : https://docs.python.org/3/c-api/long.html#c.PyLong_AsDouble +func PyLong_AsDouble(obj *PyObject) float64 { + return float64(C.PyLong_AsDouble(toc(obj))) +} diff --git a/integer_test.go b/integer_test.go new file mode 100644 index 0000000..68c2e5b --- /dev/null +++ b/integer_test.go @@ -0,0 +1,121 @@ +package python3 + +import ( + "strconv" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPyLongCheck(t *testing.T) { + Py_Initialize() + + pyLong := PyLong_FromGoInt(345) + assert.True(t, PyLong_Check(pyLong)) + assert.True(t, PyLong_CheckExact(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsLong(t *testing.T) { + Py_Initialize() + v := 2354 + pyLong := PyLong_FromLong(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsUnsignedLong(t *testing.T) { + Py_Initialize() + v := uint(2354) + pyLong := PyLong_FromUnsignedLong(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsUnsignedLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsLongLong(t *testing.T) { + Py_Initialize() + v := int64(2354) + pyLong := PyLong_FromLongLong(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsLongLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsUnsignedLongLong(t *testing.T) { + Py_Initialize() + v := uint64(2354) + pyLong := PyLong_FromUnsignedLongLong(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsUnsignedLongLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsDouble(t *testing.T) { + Py_Initialize() + v := float64(2354.0) + pyLong := PyLong_FromDouble(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsDouble(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsString(t *testing.T) { + Py_Initialize() + v := 2354 + s := strconv.Itoa(v) + pyLong := PyLong_FromString(s, 10) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsUnicodeObject(t *testing.T) { + Py_Initialize() + v := 2354 + s := strconv.Itoa(v) + pyUnicode := PyUnicode_FromString(s) + assert.NotNil(t, pyUnicode) + pyLong := PyLong_FromUnicodeObject(pyUnicode, 10) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsLong(pyLong)) + pyLong.DecRef() + pyUnicode.DecRef() +} + +func TestPyLongFromAsGoInt(t *testing.T) { + Py_Initialize() + v := 2354 + pyLong := PyLong_FromGoInt(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsGoUint(t *testing.T) { + Py_Initialize() + v := uint(2354) + pyLong := PyLong_FromGoUint(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsUnsignedLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsGoInt64(t *testing.T) { + Py_Initialize() + v := int64(2354) + pyLong := PyLong_FromGoInt64(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsLongLong(pyLong)) + pyLong.DecRef() +} + +func TestPyLongFromAsGoUint64(t *testing.T) { + Py_Initialize() + v := uint64(2354) + pyLong := PyLong_FromGoUint64(v) + assert.NotNil(t, pyLong) + assert.Equal(t, v, PyLong_AsUnsignedLongLong(pyLong)) + pyLong.DecRef() +} diff --git a/list.go b/list.go new file mode 100644 index 0000000..4d9a501 --- /dev/null +++ b/list.go @@ -0,0 +1,81 @@ +package python3 + +/* +#include "Python.h" +#include "macro.h" +#include "type.h" +*/ +import "C" + +//List : https://docs.python.org/3/c-api/list.html#c.PyList_Type +var List = togo(C._go_PyList_Type) + +//PyList_Check : https://docs.python.org/3/c-api/list.html#c.PyList_Check +func PyList_Check(p *PyObject) bool { + return C._go_PyList_Check(toc(p)) != 0 +} + +//PyList_CheckExact : https://docs.python.org/3/c-api/list.html#c.PyList_CheckExact +func PyList_CheckExact(p *PyObject) bool { + return C._go_PyList_CheckExact(toc(p)) != 0 +} + +//PyList_New : https://docs.python.org/3/c-api/list.html#c.PyList_New +func PyList_New(len int) *PyObject { + return togo(C.PyList_New(C.Py_ssize_t(len))) +} + +//PyList_Size : https://docs.python.org/3/c-api/list.html#c.PyList_Size +func PyList_Size(p *PyObject) int { + return int(C.PyList_Size(toc(p))) +} + +//PyList_GetItem : https://docs.python.org/3/c-api/list.html#c.PyList_GetItem +func PyList_GetItem(p *PyObject, pos int) *PyObject { + return togo(C.PyList_GetItem(toc(p), C.Py_ssize_t(pos))) +} + +//PyList_SetItem : https://docs.python.org/3/c-api/list.html#c.PyList_SetItem +func PyList_SetItem(p *PyObject, pos int, o *PyObject) { + C.PyList_SetItem(toc(p), C.Py_ssize_t(pos), toc(o)) +} + +//PyList_Insert : https://docs.python.org/3/c-api/list.html#c.PyList_Insert +func PyList_Insert(p *PyObject, index int, item *PyObject) int { + return int(C.PyList_Insert(toc(p), C.Py_ssize_t(index), toc(item))) +} + +//PyList_Append : https://docs.python.org/3/c-api/list.html#c.PyList_Append +func PyList_Append(p, item *PyObject) int { + return int(C.PyList_Append(toc(p), toc(item))) +} + +//PyList_GetSlice : https://docs.python.org/3/c-api/list.html#c.PyList_GetSlice +func PyList_GetSlice(p *PyObject, low, high int) *PyObject { + return togo(C.PyList_GetSlice(toc(p), C.Py_ssize_t(low), C.Py_ssize_t(high))) +} + +//PyList_SetSlice : https://docs.python.org/3/c-api/list.html#c.PyList_SetSlice +func PyList_SetSlice(p *PyObject, low, high int, itemlist *PyObject) int { + return int(C.PyList_SetSlice(toc(p), C.Py_ssize_t(low), C.Py_ssize_t(high), toc(itemlist))) +} + +//PyList_Sort : https://docs.python.org/3/c-api/list.html#c.PyList_Sort +func PyList_Sort(list *PyObject) int { + return int(C.PyList_Sort(toc(list))) +} + +//PyList_Reverse : https://docs.python.org/3/c-api/list.html#c.PyList_Reverse +func PyList_Reverse(list *PyObject) int { + return int(C.PyList_Reverse(toc(list))) +} + +//PyList_AsTuple : https://docs.python.org/3/c-api/list.html#c.PyList_AsTuple +func PyList_AsTuple(list *PyObject) *PyObject { + return togo(C.PyList_AsTuple(toc(list))) +} + +//PyList_ClearFreeList : https://docs.python.org/3/c-api/list.html#c.PyList_ClearFreeList +func PyList_ClearFreeList() int { + return int(C.PyList_ClearFreeList()) +} diff --git a/macro.c b/macro.c new file mode 100644 index 0000000..cd243cf --- /dev/null +++ b/macro.c @@ -0,0 +1,105 @@ +#include "macro.h" + +int _go_Py_EnterRecursiveCall(const char *where) { + return Py_EnterRecursiveCall(where); +} + +void _go_Py_LeaveRecursiveCall() { + Py_LeaveRecursiveCall(); +} + +int _go_PyType_Check(PyObject *o) { + return PyType_Check(o); +} +int _go_PyType_CheckExact(PyObject *o) { + return PyType_CheckExact(o); +} + + + +int _go_PyLong_Check(PyObject *p) { + return PyLong_Check(p); +} +int _go_PyLong_CheckExact(PyObject *p) { + return PyLong_CheckExact(p); +} + +int _go_PyBool_Check(PyObject *o) { + return PyBool_Check(o); +} + +int _go_PyFloat_Check(PyObject *p) { + return PyFloat_Check(p); +} + +int _go_PyFloat_CheckExact(PyObject *p) { + return PyFloat_CheckExact(p); +} + +int _go_PyComplex_Check(PyObject *p) { + return PyComplex_Check(p); +} + +int _go_PyComplex_CheckExact(PyObject *p) { + return PyComplex_CheckExact(p); +} + +int _go_PyBytes_Check(PyObject *o) { + return PyBytes_Check(o); +} +int _go_PyBytes_CheckExact(PyObject *o) { + return PyBytes_CheckExact(o); +} + +int _go_PyByteArray_Check(PyObject *o) { + return PyByteArray_Check(o); +} +int _go_PyByteArray_CheckExact(PyObject *o) { + return PyByteArray_CheckExact(o); +} + +int _go_PyUnicode_Check(PyObject *o) { + return PyUnicode_Check(o); +} +int _go_PyUnicode_CheckExact(PyObject *o) { + return PyUnicode_CheckExact(o); +} + +int _go_PyTuple_Check(PyObject *p) { + return PyTuple_Check(p); +} +int _go_PyTuple_CheckExact(PyObject *p) { + return PyTuple_CheckExact(p); +} + +int _go_PyList_Check(PyObject *p) { + return PyList_Check(p); +} +int _go_PyList_CheckExact(PyObject *p) { + return PyList_CheckExact(p); +} + +int _go_PyDict_Check(PyObject *p) { + return PyDict_Check(p); +} +int _go_PyDict_CheckExact(PyObject *p) { + return PyDict_CheckExact(p); +} + +int _go_PyModule_Check(PyObject *p) { + return PyModule_Check(p); +} +int _go_PyModule_CheckExact(PyObject *p) { + return PyModule_CheckExact(p); +} + +int _go_PyObject_DelAttr(PyObject *o, PyObject *attr_name) { + return PyObject_DelAttr(o, attr_name); +} +int _go_PyObject_DelAttrString(PyObject *o, const char *attr_name) { + return PyObject_DelAttrString(o, attr_name); +} + +int _go_PyObject_TypeCheck(PyObject *o, PyTypeObject *type) { + return PyObject_TypeCheck(o, type); +} \ No newline at end of file diff --git a/macro.h b/macro.h new file mode 100644 index 0000000..ca7486a --- /dev/null +++ b/macro.h @@ -0,0 +1,49 @@ +#ifndef MACRO_H +#define MACRO_H + +#include "Python.h" + +int _go_Py_EnterRecursiveCall(const char *where); +void _go_Py_LeaveRecursiveCall(); + +int _go_PyType_Check(PyObject *o); +int _go_PyType_CheckExact(PyObject *o); + +int _go_PyLong_Check(PyObject *p); +int _go_PyLong_CheckExact(PyObject *p); + +int _go_PyBool_Check(PyObject *o); + +int _go_PyFloat_Check(PyObject *p); +int _go_PyFloat_CheckExact(PyObject *p); + +int _go_PyComplex_Check(PyObject *p); +int _go_PyComplex_CheckExact(PyObject *p); + +int _go_PyBytes_Check(PyObject *o); +int _go_PyBytes_CheckExact(PyObject *o); + +int _go_PyByteArray_Check(PyObject *o); +int _go_PyByteArray_CheckExact(PyObject *o); + +int _go_PyUnicode_Check(PyObject *o); +int _go_PyUnicode_CheckExact(PyObject *o); + +int _go_PyTuple_Check(PyObject *p); +int _go_PyTuple_CheckExact(PyObject *p); + +int _go_PyList_Check(PyObject *p); +int _go_PyList_CheckExact(PyObject *p); + +int _go_PyDict_Check(PyObject *p); +int _go_PyDict_CheckExact(PyObject *p); + +int _go_PyModule_Check(PyObject *p); +int _go_PyModule_CheckExact(PyObject *p); + +int _go_PyObject_DelAttr(PyObject *o, PyObject *attr_name); +int _go_PyObject_DelAttrString(PyObject *o, const char *attr_name); + +int _go_PyObject_TypeCheck(PyObject *o, PyTypeObject *type); + +#endif \ No newline at end of file diff --git a/object.go b/object.go new file mode 100644 index 0000000..d9088c1 --- /dev/null +++ b/object.go @@ -0,0 +1,261 @@ +package python3 + +//go:generate go run script/variadic.go + +/* +#include "Python.h" +#include "macro.h" +#include "variadic.h" +*/ +import "C" +import ( + "unsafe" +) + +//MaxVariadicLength is the maximum number of arguments that can be passed to a variadic C function due to a cgo limitation +const MaxVariadicLength = 20 + +// Constants used for comparison in PyObject_RichCompareBool +var ( + Py_LT = int(C.Py_LT) + Py_LE = int(C.Py_LE) + Py_EQ = int(C.Py_EQ) + Py_NE = int(C.Py_NE) + Py_GT = int(C.Py_GT) + Py_GE = int(C.Py_GE) +) + +//None : https://docs.python.org/3/c-api/none.html#c.Py_None +var Py_None = togo(C.Py_None) + +//PyObject : https://docs.python.org/3/c-api/structures.html?highlight=pyobject#c.PyObject +type PyObject C.PyObject + +//IncRef : https://docs.python.org/3/c-api/refcounting.html#c.Py_INCREF +func (pyObject *PyObject) IncRef() { + C.Py_IncRef(toc(pyObject)) +} + +//DecRef : https://docs.python.org/3/c-api/refcounting.html#c.Py_DECREF +func (pyObject *PyObject) DecRef() { + C.Py_DecRef(toc(pyObject)) +} + +//ReprEnter : https://docs.python.org/3/c-api/exceptions.html#c.Py_ReprEnter +func (pyObject *PyObject) ReprEnter() int { + return int(C.Py_ReprEnter(toc(pyObject))) +} + +//ReprLeave : https://docs.python.org/3/c-api/exceptions.html#c.Py_ReprLeave +func (pyObject *PyObject) ReprLeave() { + C.Py_ReprLeave(toc(pyObject)) +} + +//HasAttr : https://docs.python.org/3/c-api/object.html#c.PyObject_HasAttr +func (pyObject *PyObject) HasAttr(attr_name *PyObject) bool { + return C.PyObject_HasAttr(toc(pyObject), toc(attr_name)) == 1 +} + +//HasAttrString : https://docs.python.org/3/c-api/object.html#c.PyObject_HasAttrString +func (pyObject *PyObject) HasAttrString(attr_name string) bool { + cattr_name := C.CString(attr_name) + defer C.free(unsafe.Pointer(cattr_name)) + + return C.PyObject_HasAttrString(toc(pyObject), cattr_name) == 1 +} + +//GetAttr : https://docs.python.org/3/c-api/object.html#c.PyObject_GetAttr +func (pyObject *PyObject) GetAttr(attr_name *PyObject) *PyObject { + return togo(C.PyObject_GetAttr(toc(pyObject), toc(attr_name))) +} + +//GetAttrString : https://docs.python.org/3/c-api/object.html#c.PyObject_GetAttrString +func (pyObject *PyObject) GetAttrString(attr_name string) *PyObject { + cattr_name := C.CString(attr_name) + defer C.free(unsafe.Pointer(cattr_name)) + + return togo(C.PyObject_GetAttrString(toc(pyObject), cattr_name)) +} + +//SetAttr : https://docs.python.org/3/c-api/object.html#c.PyObject_SetAttr +func (pyObject *PyObject) SetAttr(attr_name *PyObject, v *PyObject) { + + C.PyObject_SetAttr(toc(pyObject), toc(attr_name), toc(v)) +} + +//SetAttrString : https://docs.python.org/3/c-api/object.html#c.PyObject_SetAttrString +func (pyObject *PyObject) SetAttrString(attr_name string, v *PyObject) int { + cattr_name := C.CString(attr_name) + defer C.free(unsafe.Pointer(cattr_name)) + + return int(C.PyObject_SetAttrString(toc(pyObject), cattr_name, toc(v))) +} + +//DelAttr : https://docs.python.org/3/c-api/object.html#c.PyObject_DelAttr +func (pyObject *PyObject) DelAttr(attr_name *PyObject) { + C._go_PyObject_DelAttr(toc(pyObject), toc(attr_name)) +} + +//DelAttrString : https://docs.python.org/3/c-api/object.html#c.PyObject_DelAttrString +func (pyObject *PyObject) DelAttrString(attr_name string) { + cattr_name := C.CString(attr_name) + defer C.free(unsafe.Pointer(cattr_name)) + + C._go_PyObject_DelAttrString(toc(pyObject), cattr_name) +} + +//RichCompare : https://docs.python.org/3/c-api/object.html#c.PyObject_RichCompare +func (pyObject *PyObject) RichCompare(o *PyObject, opid int) *PyObject { + return togo(C.PyObject_RichCompare(toc(pyObject), toc(o), C.int(opid))) +} + +//RichCompareBool : https://docs.python.org/3/c-api/object.html#c.PyObject_RichCompareBool +func (pyObject *PyObject) RichCompareBool(o *PyObject, opid int) int { + return int(C.PyObject_RichCompareBool(toc(pyObject), toc(o), C.int(opid))) +} + +//Repr : https://docs.python.org/3/c-api/object.html#c.PyObject_Repr +func (pyObject *PyObject) Repr() *PyObject { + return togo(C.PyObject_Repr(toc(pyObject))) +} + +//ASCII : https://docs.python.org/3/c-api/object.html#c.PyObject_ASCII +func (pyObject *PyObject) ASCII() *PyObject { + return togo(C.PyObject_ASCII(toc(pyObject))) +} + +//Str : https://docs.python.org/3/c-api/object.html#c.PyObject_Str +func (pyObject *PyObject) Str() *PyObject { + return togo(C.PyObject_Str(toc(pyObject))) +} + +//Bytes : https://docs.python.org/3/c-api/object.html#c.PyObject_Bytes +func (pyObject *PyObject) Bytes() *PyObject { + return togo(C.PyObject_Bytes(toc(pyObject))) +} + +//IsSubclass : https://docs.python.org/3/c-api/object.html#c.PyObject_IsSubclass +func (pyObject *PyObject) IsSubclass(cls *PyObject) int { + return int(C.PyObject_IsSubclass(toc(pyObject), toc(cls))) +} + +//IsInstance : https://docs.python.org/3/c-api/object.html#c.PyObject_IsInstance +func (pyObject *PyObject) IsInstance(cls *PyObject) int { + return int(C.PyObject_IsInstance(toc(pyObject), toc(cls))) +} + +// PyCallable_Check : https://docs.python.org/3/c-api/object.html#c.PyCallable_Check +func PyCallable_Check(o *PyObject) bool { + return C.PyCallable_Check(toc(o)) == 1 +} + +//Call : https://docs.python.org/3/c-api/object.html#c.PyObject_Call +func (pyObject *PyObject) Call(args *PyObject, kwargs *PyObject) *PyObject { + return togo(C.PyObject_Call(toc(pyObject), toc(args), toc(kwargs))) +} + +//CallObject : https://docs.python.org/3/c-api/object.html#c.PyObject_CallObject +func (pyObject *PyObject) CallObject(args *PyObject) *PyObject { + return togo(C.PyObject_CallObject(toc(pyObject), toc(args))) +} + +//CallFunctionObjArgs : https://docs.python.org/3/c-api/object.html#c.PyObject_CallFunctionObjArgs +func (pyObject *PyObject) CallFunctionObjArgs(args ...*PyObject) *PyObject { + + if len(args) > MaxVariadicLength { + panic("CallFunctionObjArgs: too many arrguments") + } + if len(args) == 0 { + return togo(C._go_PyObject_CallFunctionObjArgs(toc(pyObject), 0, (**C.PyObject)(nil))) + } + + cargs := make([]*C.PyObject, len(args), len(args)) + for i, arg := range args { + cargs[i] = toc(arg) + } + return togo(C._go_PyObject_CallFunctionObjArgs(toc(pyObject), C.int(len(args)), (**C.PyObject)(unsafe.Pointer(&cargs[0])))) +} + +//CallMethodObjArgs : https://docs.python.org/3/c-api/object.html#c.PyObject_CallMethodObjArgs +func (pyObject *PyObject) CallMethodObjArgs(name *PyObject, args ...*PyObject) *PyObject { + if len(args) > MaxVariadicLength { + panic("CallMethodObjArgs: too many arguments") + } + if len(args) == 0 { + return togo(C._go_PyObject_CallMethodObjArgs(toc(pyObject), toc(name), 0, (**C.PyObject)(nil))) + } + + cargs := make([]*C.PyObject, len(args), len(args)) + for i, arg := range args { + cargs[i] = toc(arg) + } + return togo(C._go_PyObject_CallMethodObjArgs(toc(pyObject), toc(name), C.int(len(args)), (**C.PyObject)(unsafe.Pointer(&cargs[0])))) +} + +//CallMethodArgs : same as CallMethodObjArgs but with name as go string +func (pyObject *PyObject) CallMethodArgs(name string, args ...*PyObject) *PyObject { + pyName := PyUnicode_FromString(name) + defer pyName.DecRef() + + return pyObject.CallMethodObjArgs(pyName, args...) +} + +//Hash : https://docs.python.org/3/c-api/object.html#c.PyObject_Hash +func (pyObject *PyObject) Hash() int { + return int(C.PyObject_Hash(toc(pyObject))) +} + +//HashNotImplemented : https://docs.python.org/3/c-api/object.html#c.PyObject_HashNotImplemented +func (pyObject *PyObject) HashNotImplemented() int { + return int(C.PyObject_HashNotImplemented(toc(pyObject))) +} + +//IsTrue : https://docs.python.org/3/c-api/object.html#c.PyObject_IsTrue +func (pyObject *PyObject) IsTrue() int { + return int(C.PyObject_IsTrue(toc(pyObject))) +} + +//Not : https://docs.python.org/3/c-api/object.html#c.PyObject_Not +func (pyObject *PyObject) Not() int { + return int(C.PyObject_Not(toc(pyObject))) +} + +//Type : https://docs.python.org/3/c-api/object.html#c.PyObject_Type +func (pyObject *PyObject) Type() *PyObject { + return togo(C.PyObject_Type(toc(pyObject))) +} + +//Length : https://docs.python.org/3/c-api/object.html#c.PyObject_Length +func (pyObject *PyObject) Length() int { + return int(C.PyObject_Length(toc(pyObject))) +} + +//LengthHint : https://docs.python.org/3/c-api/object.html#c.PyObject_LengthHint +func (pyObject *PyObject) LengthHint(pyDefault int) int { + return int(C.PyObject_LengthHint(toc(pyObject), C.Py_ssize_t(pyDefault))) +} + +//GetItem : https://docs.python.org/3/c-api/object.html#c.PyObject_GetItem +func (pyObject *PyObject) GetItem(key *PyObject) *PyObject { + return togo(C.PyObject_GetItem(toc(pyObject), toc(key))) +} + +//SetItem : https://docs.python.org/3/c-api/object.html#c.PyObject_SetItem +func (pyObject *PyObject) SetItem(key, v *PyObject) int { + return int(C.PyObject_SetItem(toc(pyObject), toc(key), toc(v))) +} + +//DelItem : https://docs.python.org/3/c-api/object.html#c.PyObject_DelItem +func (pyObject *PyObject) DelItem(key *PyObject) int { + return int(C.PyObject_DelItem(toc(pyObject), toc(key))) +} + +//Dir : https://docs.python.org/3/c-api/object.html#c.PyObject_Dir +func (pyObject *PyObject) Dir() *PyObject { + return togo(C.PyObject_Dir(toc(pyObject))) +} + +//GetIter : https://docs.python.org/3/c-api/object.html#c.PyObject_GetIter +func (pyObject *PyObject) GetIter() *PyObject { + return togo(C.PyObject_GetIter(toc(pyObject))) +} diff --git a/script/variadic.go b/script/variadic.go new file mode 100644 index 0000000..07ad01e --- /dev/null +++ b/script/variadic.go @@ -0,0 +1,64 @@ +package main + +import ( + "flag" + "fmt" + "os" + + python "github.com/DataDog/go-python3" +) + +var ( + output = flag.String("o", "variadic.c", "output file") + caseNumber = flag.Int("n", python.MaxVariadicLength, "number of case in the switch statement") +) + +func main() { + flag.Parse() + + out, err := os.Create(*output) + if err != nil { + fmt.Printf("Error opening file %s: %s", *output, err) + os.Exit(1) + } + defer out.Close() + + _, err = out.WriteString("#include \"Python.h\"\n\n") + if err != nil { + fmt.Printf("Error writing to file %s: %s", *output, err) + os.Exit(1) + } + out.WriteString(renderTemplate(*caseNumber, "PyObject_CallFunctionObjArgs", "callable")) + out.WriteString(renderTemplate(*caseNumber, "PyObject_CallMethodObjArgs", "obj", "name")) + +} + +func renderTemplate(n int, functionName string, pyArgs ...string) string { + template := + `PyObject* _go_%s(%sint argc, PyObject **argv) { + + PyObject *result = NULL; + switch (argc) { +%s } + return result; +} +` + args := "" + for _, arg := range pyArgs { + args += fmt.Sprintf("PyObject *%s, ", arg) + } + switchTemplate := "" + for i := 0; i < n+1; i++ { + switchTemplate += fmt.Sprintf(" case %d:\n", i) + args := "" + for _, arg := range pyArgs { + args += fmt.Sprintf("%s, ", arg) + } + for j := 0; j < i; j++ { + args += fmt.Sprintf("argv[%d], ", j) + } + args += "NULL" + switchTemplate += fmt.Sprintf(" return %s(%s);\n", functionName, args) + } + return fmt.Sprintf(template, functionName, args, switchTemplate) +} diff --git a/tuple.go b/tuple.go new file mode 100644 index 0000000..aecd0a3 --- /dev/null +++ b/tuple.go @@ -0,0 +1,47 @@ +package python3 + +/* +#include "Python.h" +#include "macro.h" +#include "type.h" +*/ +import "C" + +//Tuple : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_Type +var Tuple = togo(C._go_PyTuple_Type) + +//PyTuple_Check : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_Check +func PyTuple_Check(p *PyObject) bool { + return C._go_PyTuple_Check(toc(p)) != 0 +} + +//PyTuple_CheckExact : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_CheckExact +func PyTuple_CheckExact(p *PyObject) bool { + return C._go_PyTuple_CheckExact(toc(p)) != 0 +} + +//PyTuple_New : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_New +func PyTuple_New(len int) *PyObject { + return togo(C.PyTuple_New(C.Py_ssize_t(len))) +} + +//PyTuple_Size : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_Size +func PyTuple_Size(p *PyObject) int { + return int(C.PyTuple_Size(toc(p))) +} + +//PyTuple_GetItem : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_GetItem +func PyTuple_GetItem(p *PyObject, pos int) *PyObject { + return togo(C.PyTuple_GetItem(toc(p), C.Py_ssize_t(pos))) +} + +//PyTuple_GetSlice : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_GetSlice +func PyTuple_GetSlice(p *PyObject, low, high int) *PyObject { + return togo(C.PyTuple_GetSlice(toc(p), C.Py_ssize_t(low), C.Py_ssize_t(high))) +} + +//PyTuple_SetItem : https://docs.python.org/3/c-api/tuple.html#c.PyTuple_SetItem +func PyTuple_SetItem(p *PyObject, pos int, o *PyObject) { + C.PyTuple_SetItem(toc(p), C.Py_ssize_t(pos), toc(o)) +} + diff --git a/type.c b/type.c new file mode 100644 index 0000000..a864dc9 --- /dev/null +++ b/type.c @@ -0,0 +1,17 @@ +#include "type.h" + +PyObject *_go_PyType_Type = (PyObject *)&PyType_Type; +PyObject *_go_PyLong_Type = (PyObject *)&PyLong_Type; +PyObject *_go_PyBool_Type = (PyObject *)&PyBool_Type; +PyObject *_go_PyFloat_Type = (PyObject *)&PyFloat_Type; +PyObject *_go_PyComplex_Type = (PyObject *)&PyComplex_Type; + +PyObject *_go_PyBytes_Type = (PyObject *)&PyBytes_Type; +PyObject *_go_PyByteArray_Type = (PyObject *)&PyByteArray_Type; +PyObject *_go_PyUnicode_Type = (PyObject *)&PyUnicode_Type; +PyObject *_go_PyTuple_Type = (PyObject *)&PyTuple_Type; +PyObject *_go_PyList_Type = (PyObject *)&PyList_Type; + +PyObject *_go_PyDict_Type = (PyObject *)&PyDict_Type; + +PyObject *_go_PyModule_Type = (PyObject *)&PyModule_Type; diff --git a/type.h b/type.h new file mode 100644 index 0000000..19eb75e --- /dev/null +++ b/type.h @@ -0,0 +1,22 @@ +#ifndef TYPE_H +#define TYPE_H + +#include "Python.h" + +extern PyObject *_go_PyType_Type; +extern PyObject *_go_PyLong_Type; +extern PyObject *_go_PyBool_Type; +extern PyObject *_go_PyFloat_Type; +extern PyObject *_go_PyComplex_Type; + +extern PyObject *_go_PyBytes_Type; +extern PyObject *_go_PyByteArray_Type; +extern PyObject *_go_PyUnicode_Type; +extern PyObject *_go_PyTuple_Type; +extern PyObject *_go_PyList_Type; + +extern PyObject *_go_PyDict_Type; + +extern PyObject *_go_PyModule_Type; + +#endif diff --git a/unicode.go b/unicode.go new file mode 100644 index 0000000..951b45a --- /dev/null +++ b/unicode.go @@ -0,0 +1,85 @@ +package python3 + +/* +#include "Python.h" +#include "macro.h" +#include "type.h" +*/ +import "C" +import ( + "unsafe" +) + +//Unicode : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_Type +var Unicode = togo(C._go_PyUnicode_Type) + +//PyUnicode_Check : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_Check +func PyUnicode_Check(o *PyObject) bool { + return C._go_PyUnicode_Check(toc(o)) != 0 +} + +//PyUnicode_CheckExact : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_CheckExact +func PyUnicode_CheckExact(o *PyObject) bool { + return C._go_PyUnicode_CheckExact(toc(o)) != 0 +} + +//PyUnicode_New : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_New +func PyUnicode_New(size, maxchar rune) *PyObject { + return togo(C.PyUnicode_New(C.Py_ssize_t(size), C.Py_UCS4(maxchar))) +} + +//PyUnicode_FromString : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_FromString +func PyUnicode_FromString(u string) *PyObject { + cu := C.CString(u) + defer C.free(unsafe.Pointer(cu)) + + return togo(C.PyUnicode_FromString(cu)) +} + +//PyUnicode_FromEncodedObject : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_FromEncodedObject +func PyUnicode_FromEncodedObject(obj *PyObject, encoding, errors string) *PyObject { + cencoding := C.CString(encoding) + defer C.free(unsafe.Pointer(cencoding)) + + cerrors := C.CString(errors) + defer C.free(unsafe.Pointer(cerrors)) + + return togo(C.PyUnicode_FromEncodedObject(toc(obj), cencoding, cerrors)) +} + +//PyUnicode_GetLength : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_GetLength +func PyUnicode_GetLength(unicode *PyObject) int { + return int(C.PyUnicode_GetLength(toc(unicode))) +} + +//PyUnicode_CopyCharacters : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_CopyCharacters +func PyUnicode_CopyCharacters(to, from *PyObject, to_start, from_start, how_many int) int { + return int(C.PyUnicode_CopyCharacters(toc(to), C.Py_ssize_t(to_start), toc(from), C.Py_ssize_t(from_start), C.Py_ssize_t(how_many))) + +} + +//PyUnicode_Fill : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_Fill +func PyUnicode_Fill(unicode *PyObject, start, length int, fill_char rune) int { + return int(C.PyUnicode_Fill(toc(unicode), C.Py_ssize_t(start), C.Py_ssize_t(length), C.Py_UCS4(fill_char))) +} + +//PyUnicode_WriteChar : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_WriteChar +func PyUnicode_WriteChar(unicode *PyObject, index int, character rune) { + C.PyUnicode_WriteChar(toc(unicode), C.Py_ssize_t(index), C.Py_UCS4(character)) +} + +//PyUnicode_ReadChar : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_ReadChar +func PyUnicode_ReadChar(unicode *PyObject, index int) rune { + return rune(C.PyUnicode_ReadChar(toc(unicode), C.Py_ssize_t(index))) +} + +//PyUnicode_Substring : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_Substring +func PyUnicode_Substring(unicode *PyObject, start, end int) *PyObject { + return togo(C.PyUnicode_Substring(toc(unicode), C.Py_ssize_t(start), C.Py_ssize_t(end))) +} + +//PyUnicode_AsUTF8 : https://docs.python.org/3/c-api/unicode.html#c.PyUnicode_AsUTF8 +func PyUnicode_AsUTF8(unicode *PyObject) string { + cutf8 := C.PyUnicode_AsUTF8(toc(unicode)) + return C.GoString(cutf8) +} diff --git a/variadic.c b/variadic.c new file mode 100644 index 0000000..0cfab2f --- /dev/null +++ b/variadic.c @@ -0,0 +1,100 @@ +#include "Python.h" + +PyObject* _go_PyObject_CallFunctionObjArgs(PyObject *callable, int argc, PyObject **argv) { + + PyObject *result = NULL; + switch (argc) { + case 0: + return PyObject_CallFunctionObjArgs(callable, NULL); + case 1: + return PyObject_CallFunctionObjArgs(callable, argv[0], NULL); + case 2: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], NULL); + case 3: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], NULL); + case 4: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], NULL); + case 5: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], NULL); + case 6: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL); + case 7: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL); + case 8: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], NULL); + case 9: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], NULL); + case 10: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], NULL); + case 11: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], NULL); + case 12: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], NULL); + case 13: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], NULL); + case 14: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], NULL); + case 15: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], NULL); + case 16: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], NULL); + case 17: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], NULL); + case 18: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], NULL); + case 19: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18], NULL); + case 20: + return PyObject_CallFunctionObjArgs(callable, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18], argv[19], NULL); + } + return result; +} +PyObject* _go_PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, int argc, PyObject **argv) { + + PyObject *result = NULL; + switch (argc) { + case 0: + return PyObject_CallMethodObjArgs(obj, name, NULL); + case 1: + return PyObject_CallMethodObjArgs(obj, name, argv[0], NULL); + case 2: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], NULL); + case 3: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], NULL); + case 4: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], NULL); + case 5: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], NULL); + case 6: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], NULL); + case 7: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL); + case 8: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], NULL); + case 9: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], NULL); + case 10: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], NULL); + case 11: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], NULL); + case 12: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], NULL); + case 13: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], NULL); + case 14: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], NULL); + case 15: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], NULL); + case 16: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], NULL); + case 17: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], NULL); + case 18: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], NULL); + case 19: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18], NULL); + case 20: + return PyObject_CallMethodObjArgs(obj, name, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18], argv[19], NULL); + } + return result; +} diff --git a/variadic.h b/variadic.h new file mode 100644 index 0000000..8834e67 --- /dev/null +++ b/variadic.h @@ -0,0 +1,9 @@ +#ifndef VARIADIC_H +#define VARIADIC_H + +#include "Python.h" + +PyObject* _go_PyObject_CallFunctionObjArgs(PyObject *callable, int argc, PyObject **args); +PyObject* _go_PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, int argc, PyObject **args); + +#endif \ No newline at end of file