Skip to content

Commit cb6f540

Browse files
author
g.ph
committed
update
1 parent 859a0c5 commit cb6f540

30 files changed

+779
-165
lines changed

PyBool.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package py3
2+
3+
import (
4+
"github.com/aadog/py3-go/cpy3"
5+
"unsafe"
6+
)
7+
8+
type PyBool struct {
9+
PyObject
10+
}
11+
12+
// PyBoolFromInst
13+
// 新建一个对象来自已经存在的对象实例指针。
14+
//
15+
// Create a new object from an existing object instance pointer.
16+
func PyBoolFromInst(inst uintptr) *PyBool {
17+
dl := new(PyBool)
18+
dl.instance = inst
19+
dl.ptr = unsafe.Pointer(dl.instance)
20+
return dl
21+
}
22+
func PyBoolFromObj(obj *PyObject) *PyBool {
23+
dl := new(PyBool)
24+
dl.PyObject = *obj
25+
return dl
26+
}
27+
28+
func NewPyBoolFromLong(l int64) *PyObject {
29+
return PyObjectFromInst(cpy3.PyBool_FromLong(l))
30+
}
31+
func NewPyBool(b bool) *PyObject {
32+
l := 0
33+
if b == true {
34+
l = 1
35+
}
36+
return NewPyBoolFromLong(int64(l))
37+
}

PyBytes.go

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package py3
2+
3+
import (
4+
"github.com/aadog/py3-go/cpy3"
5+
"unsafe"
6+
)
7+
8+
type PyBytes struct {
9+
PyObject
10+
}
11+
12+
func PyBytes_FromString(s string) *PyBytes {
13+
return PyBytesFromInst(cpy3.PyBytes_FromString(s))
14+
}
15+
16+
// PyBytesFromInst
17+
// 新建一个对象来自已经存在的对象实例指针。
18+
//
19+
// Create a new object from an existing object instance pointer.
20+
func PyBytesFromInst(inst uintptr) *PyBytes {
21+
dl := new(PyBytes)
22+
dl.instance = inst
23+
dl.ptr = unsafe.Pointer(dl.instance)
24+
return dl
25+
}

PyClass.go

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package py3
2+
3+
import (
4+
"fmt"
5+
"github.com/aadog/py3-go/cpy3"
6+
"syscall"
7+
"unsafe"
8+
)
9+
10+
type PyClass struct {
11+
PyObject
12+
}
13+
14+
func (p *PyClass) GetName() string {
15+
return p.GetAttrString("__className__").AsUTF8()
16+
}
17+
18+
// PyClassFromInst
19+
// 新建一个对象来自已经存在的对象实例指针。
20+
//
21+
// Create a new object from an existing object instance pointer.
22+
func PyClassFromInst(inst uintptr) *PyClass {
23+
dl := new(PyClass)
24+
dl.instance = inst
25+
dl.ptr = unsafe.Pointer(dl.instance)
26+
return dl
27+
}
28+
func PyClassFromObj(obj *PyObject) *PyClass {
29+
dl := new(PyClass)
30+
dl.PyObject = *obj
31+
return dl
32+
}
33+
34+
func CreateClass(name string, dict map[string]any) *PyClass {
35+
if dict == nil {
36+
dict = map[string]any{}
37+
}
38+
pClassName := GoToPyObject(name)
39+
defer pClassName.DecRef()
40+
pClassBases := NewPyTuple(0)
41+
defer pClassBases.DecRef()
42+
pClassDic := GoToPyObject(dict)
43+
defer pClassDic.DecRef()
44+
pClass := PyObjectFromInst(cpy3.PyObject_CallFunctionObjArgs(cpy3.PyType_Type(), pClassName.Instance(), pClassBases.Instance(), pClassDic.Instance(), 0))
45+
pClass.SetAttrString("__className__", NewPyUnicode(name).AsObj())
46+
47+
fnName := "Call"
48+
methodCallDef := &cpy3.PyMethodDef{
49+
Ml_name: cpy3.GoStrToCStr(fnName),
50+
Ml_meth: syscall.NewCallback(func() uintptr {
51+
fmt.Println("call")
52+
53+
return Py_RETURN_NONE().instance
54+
}),
55+
Ml_flags: 0,
56+
Ml_doc: cpy3.GoStrToCStr("module call forward"),
57+
}
58+
PyMethodMap.Store("x", methodCallDef)
59+
60+
fn := PyObjectFromInst(cpy3.PyCFunction_New(uintptr(unsafe.Pointer(methodCallDef)), cpy3.PyTuple_New(0)))
61+
defer fn.DecRef()
62+
method := PyObjectFromInst(cpy3.PyInstanceMethod(fn.instance))
63+
defer method.DecRef()
64+
pClass.SetAttrString(fnName, method)
65+
return PyClassFromObj(pClass)
66+
}

PyConvert.go

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package py3
2+
3+
import (
4+
"reflect"
5+
)
6+
7+
func GoToPyObject(o interface{}) *PyObject {
8+
to := reflect.TypeOf(o)
9+
valOf := reflect.ValueOf(o)
10+
11+
if o == nil {
12+
return Py_RETURN_NONE().AsObj()
13+
}
14+
//*PyObject return
15+
if to.AssignableTo(reflect.TypeOf(&PyObject{})) {
16+
return o.(*PyObject)
17+
}
18+
if valOf.CanInt() {
19+
return PyLongFromLongLong(valOf.Int()).AsObj()
20+
}
21+
if valOf.CanUint() {
22+
return PyLongFromLongLong(int64(valOf.Uint())).AsObj()
23+
}
24+
if valOf.CanFloat() {
25+
return PyLong_FromDouble(valOf.Float()).AsObj()
26+
}
27+
28+
if to.Kind() == reflect.Bool {
29+
return NewPyBool(valOf.Bool())
30+
}
31+
if to.Kind() == reflect.String {
32+
return NewPyUnicode(valOf.String()).AsObj()
33+
}
34+
35+
if to.Kind() == reflect.Slice {
36+
l := NewPyList(0)
37+
size := valOf.Len()
38+
for i := 0; i < size; i++ {
39+
item := valOf.Index(i).Interface()
40+
o := GoToPyObject(item)
41+
defer o.DecRef()
42+
l.Append(o)
43+
}
44+
return l.AsObj()
45+
}
46+
if to.Kind() == reflect.Map {
47+
d := NewPyDict()
48+
keys := valOf.MapKeys()
49+
for _, key := range keys {
50+
k := GoToPyObject(key.Interface())
51+
defer k.DecRef()
52+
v := GoToPyObject(valOf.MapIndex(key).Interface())
53+
defer v.DecRef()
54+
d.SetItem(k, v)
55+
}
56+
return d.AsObj()
57+
}
58+
return Py_RETURN_NONE().AsObj()
59+
}
60+
61+
func PyObjectToGo(o *PyObject, to reflect.Type) any {
62+
//*PyObject return
63+
if to.AssignableTo(reflect.TypeOf(o)) {
64+
return o
65+
}
66+
if to.Kind() == reflect.Int {
67+
return int(o.AsLongLong())
68+
}
69+
if to.Kind() == reflect.Int8 {
70+
return int8(o.AsLongLong())
71+
}
72+
if to.Kind() == reflect.Int16 {
73+
return int16(o.AsLongLong())
74+
}
75+
if to.Kind() == reflect.Int32 {
76+
return int32(o.AsLongLong())
77+
}
78+
if to.Kind() == reflect.Int64 {
79+
return int64(o.AsLongLong())
80+
}
81+
82+
if to.Kind() == reflect.Uint {
83+
return uint(o.AsLongLong())
84+
}
85+
if to.Kind() == reflect.Uint8 {
86+
return uint8(o.AsLongLong())
87+
}
88+
if to.Kind() == reflect.Uint16 {
89+
return uint16(o.AsLongLong())
90+
}
91+
if to.Kind() == reflect.Uint32 {
92+
return uint32(o.AsLongLong())
93+
}
94+
if to.Kind() == reflect.Uint64 {
95+
return uint64(o.AsLongLong())
96+
}
97+
98+
if to.Kind() == reflect.Uintptr {
99+
return uintptr(o.AsLongLong())
100+
}
101+
102+
if to.Kind() == reflect.Bool {
103+
return o.AsInt() != 0
104+
}
105+
if to.Kind() == reflect.String {
106+
return o.AsUTF8()
107+
}
108+
if to.Kind() == reflect.Float32 {
109+
return float32(o.AsDouble())
110+
}
111+
if to.Kind() == reflect.Float64 {
112+
return float64(o.AsDouble())
113+
}
114+
if to.Kind() == reflect.Slice {
115+
l := reflect.New(to).Elem()
116+
pyL := PyListFromObj(o.AsObj())
117+
for i := int64(0); i < pyL.Size(); i++ {
118+
l = reflect.Append(l, reflect.ValueOf(PyObjectToGo(pyL.GetItem(i), to.Elem())))
119+
}
120+
return l.Interface()
121+
}
122+
if to.Kind() == reflect.Map {
123+
l := reflect.MakeMap(to)
124+
pyD := PyDictFromObj(o.AsObj())
125+
keys := PyListFromObj(pyD.Keys())
126+
defer keys.DecRef()
127+
for i := int64(0); i < keys.Size(); i++ {
128+
k := keys.GetItem(i)
129+
goK := PyObjectToGo(k, to.Key())
130+
l.SetMapIndex(reflect.ValueOf(goK), reflect.ValueOf(PyObjectToGo(pyD.GetItem(k), to.Elem())))
131+
}
132+
return l.Interface()
133+
}
134+
if to.Kind() == reflect.Func {
135+
f := reflect.MakeFunc(to, func(args []reflect.Value) (results []reflect.Value) {
136+
pyArgs := NewPyTuple(int64(len(args)))
137+
for i, arg := range args {
138+
pyArgs.SetItem(int64(i), GoToPyObject(arg.Interface()))
139+
}
140+
rets := o.Call(pyArgs.AsObj(), PyNil)
141+
//如果声明函数不需要返回
142+
if to.NumOut() == 0 {
143+
return nil
144+
}
145+
tp := rets.Type()
146+
defer tp.DecRef()
147+
148+
goRets := make([]reflect.Value, 0)
149+
150+
//如果是单个返回
151+
if tp.Name() != "tuple" {
152+
if to.NumOut() != 1 {
153+
k := make([]reflect.Value, 0)
154+
for i := 0; i < to.NumOut(); i++ {
155+
k = append(k, reflect.ValueOf(reflect.New(to.Out(i)).Elem().Interface()))
156+
}
157+
PyErr_SetString(PyExc_ValueError(), "返回参数不正确")
158+
return k
159+
}
160+
goRets = append(goRets, reflect.ValueOf(PyObjectToGo(rets, to.Out(0))))
161+
} else {
162+
tpRets := PyTupleFromObj(rets.AsObj())
163+
if int64(to.NumOut()) != tpRets.Size() {
164+
k := make([]reflect.Value, 0)
165+
for i := 0; i < to.NumOut(); i++ {
166+
k = append(k, reflect.ValueOf(reflect.New(to.Out(i)).Elem().Interface()))
167+
}
168+
PyErr_SetString(PyExc_Exception(), "返回参数不正确")
169+
return k
170+
}
171+
for i := int64(0); i < tpRets.Size(); i++ {
172+
goRets = append(goRets, reflect.ValueOf(PyObjectToGo(tpRets.GetItem(i), to.Out(0))))
173+
}
174+
}
175+
return goRets
176+
})
177+
return f.Interface()
178+
}
179+
180+
return o
181+
}

PyDict.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func (p *PyDict) GetItemString(key string) *PyObject {
2121
return PyObjectFromInst(cpy3.PyDict_GetItemString(p.instance, key))
2222
}
2323

24-
func (p *PyDict) Keys(key *PyObject) *PyObject {
24+
func (p *PyDict) Keys() *PyObject {
2525
return PyObjectFromInst(cpy3.PyDict_Keys(p.instance))
2626
}
2727
func (p *PyDict) GetItem(key *PyObject) *PyObject {
@@ -31,6 +31,10 @@ func (p *PyDict) GetItem(key *PyObject) *PyObject {
3131
func (p *PyDict) SetItemString(key string, val *PyObject) int {
3232
return cpy3.PyDict_SetItemString(p.instance, key, val.instance)
3333
}
34+
func (p *PyDict) SetItem(key *PyObject, val *PyObject) int {
35+
return cpy3.PyDict_SetItem(p.instance, key.instance, val.instance)
36+
}
37+
3438
func (p *PyDict) Size() int64 {
3539
return cpy3.PyDict_Size(p.instance)
3640
}
@@ -48,6 +52,11 @@ func PyDictFromInst(inst uintptr) *PyDict {
4852
dl.ptr = unsafe.Pointer(dl.instance)
4953
return dl
5054
}
55+
func PyDictFromObj(obj *PyObject) *PyDict {
56+
dl := new(PyDict)
57+
dl.PyObject = *obj
58+
return dl
59+
}
5160

5261
func NewPyDict() *PyDict {
5362
return PyDictFromInst(cpy3.PyDict_New())

PyErr.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package py3
2+
3+
import "github.com/aadog/py3-go/cpy3"
4+
5+
func PyExc_Exception() *PyObject {
6+
return PyObjectFromInst(cpy3.PyExc_Exception())
7+
}
8+
func PyExc_ValueError() *PyObject {
9+
return PyObjectFromInst(cpy3.PyExc_ValueError())
10+
}
11+
12+
func PyErr_SetString(tp *PyObject, message string) {
13+
cpy3.PyErr_SetString(tp.instance, message)
14+
}

PyFunc.go

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package py3
2+
3+
import (
4+
"github.com/aadog/py3-go/cpy3"
5+
"sync"
6+
)
7+
8+
var SystemModuleMap = sync.Map{}
9+
10+
func Initialize() {
11+
cpy3.Py_Initialize()
12+
}
13+
func AddModuleToSystemMap(m *PyModule) {
14+
SystemModuleMap.Store(m.GetName(), m)
15+
}
16+
func IsInitialized() int {
17+
return cpy3.Py_IsInitialized()
18+
}
19+
func Finalize() {
20+
SystemModuleMap.Range(func(key, value any) bool {
21+
SystemModuleMap.Delete(key)
22+
m := value.(*PyModule)
23+
m.DecRef()
24+
return true
25+
})
26+
cpy3.Py_Finalize()
27+
}
28+
func FinalizeEx() int {
29+
SystemModuleMap.Range(func(key, value any) bool {
30+
SystemModuleMap.Delete(key)
31+
m := value.(*PyModule)
32+
m.DecRef()
33+
return true
34+
})
35+
return cpy3.Py_FinalizeEx()
36+
}

0 commit comments

Comments
 (0)