Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 6 additions & 15 deletions adap_go.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
package gp

/*
#include <Python.h>
*/
import "C"
import (
"unsafe"
)

type Char = C.char
type WChar = C.wchar_t
type Int = C.int
type Pointer = unsafe.Pointer

//go:inline
func AllocCStr(s string) *C.char {
func AllocCStr(s string) *Char {
return C.CString(s)
}

func AllocCStrDontFree(s string) *C.char {
func AllocCStrDontFree(s string) *Char {
return C.CString(s)
}

func GoString(s *C.char) string {
return C.GoString((*C.char)(s))
func GoString(s *Char) string {
return C.GoString((*Char)(s))
}

func GoStringN(s *C.char, n int) string {
return C.GoStringN((*C.char)(s), C.int(n))
func GoStringN(s *Char, n int) string {
return C.GoStringN(s, C.int(n))
}
4 changes: 2 additions & 2 deletions bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func BytesFromStr(s string) Bytes {

func MakeBytes(bytes []byte) Bytes {
ptr := C.CBytes(bytes)
o := C.PyBytes_FromStringAndSize((*C.char)(ptr), C.Py_ssize_t(len(bytes)))
o := C.PyBytes_FromStringAndSize((*Char)(ptr), C.Py_ssize_t(len(bytes)))
C.free(unsafe.Pointer(ptr))
return newBytes(o)
}
Expand All @@ -34,5 +34,5 @@ func (b Bytes) Bytes() []byte {
}

func (b Bytes) Decode(encoding string) Str {
return Cast[Str](b.Call("decode", MakeStr(encoding)))
return cast[Str](b.Call("decode", MakeStr(encoding)))
}
76 changes: 38 additions & 38 deletions convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"unsafe"
)

func From(v any) Object {
switch v := v.(type) {
func From(from any) Object {
switch v := from.(type) {
case Objecter:
return newObject(v.Obj())
case int8:
Expand Down Expand Up @@ -81,114 +81,114 @@ func From(v any) Object {
}
}

func ToValue(obj Object, v reflect.Value) bool {
if !v.IsValid() || !v.CanSet() {
panic(fmt.Errorf("value is not valid or cannot be set: %v\n", v))
func ToValue(from Object, to reflect.Value) bool {
if !to.IsValid() || !to.CanSet() {
panic(fmt.Errorf("value is not valid or cannot be set: %v\n", to))
}

switch v.Kind() {
switch to.Kind() {
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
if obj.IsLong() {
v.SetInt(Cast[Long](obj).Int64())
if from.IsLong() {
to.SetInt(cast[Long](from).Int64())
} else {
return false
}
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
if obj.IsLong() {
v.SetUint(Cast[Long](obj).Uint64())
if from.IsLong() {
to.SetUint(cast[Long](from).Uint64())
} else {
return false
}
case reflect.Float32, reflect.Float64:
if obj.IsFloat() || obj.IsLong() {
v.SetFloat(Cast[Float](obj).Float64())
if from.IsFloat() || from.IsLong() {
to.SetFloat(cast[Float](from).Float64())
} else {
return false
}
case reflect.Complex64, reflect.Complex128:
if obj.IsComplex() {
v.SetComplex(Cast[Complex](obj).Complex128())
if from.IsComplex() {
to.SetComplex(cast[Complex](from).Complex128())
} else {
return false
}
case reflect.String:
if obj.IsStr() {
v.SetString(Cast[Str](obj).String())
if from.IsStr() {
to.SetString(cast[Str](from).String())
} else {
return false
}
case reflect.Bool:
if obj.IsBool() {
v.SetBool(Cast[Bool](obj).Bool())
if from.IsBool() {
to.SetBool(cast[Bool](from).Bool())
} else {
return false
}
case reflect.Slice:
if v.Type().Elem().Kind() == reflect.Uint8 { // []byte
if obj.IsBytes() {
v.SetBytes(Cast[Bytes](obj).Bytes())
if to.Type().Elem().Kind() == reflect.Uint8 { // []byte
if from.IsBytes() {
to.SetBytes(cast[Bytes](from).Bytes())
} else {
return false
}
} else {
if obj.IsList() {
list := Cast[List](obj)
if from.IsList() {
list := cast[List](from)
l := list.Len()
slice := reflect.MakeSlice(v.Type(), l, l)
slice := reflect.MakeSlice(to.Type(), l, l)
for i := 0; i < l; i++ {
item := list.GetItem(i)
ToValue(item, slice.Index(i))
}
v.Set(slice)
to.Set(slice)
} else {
return false
}
}
case reflect.Map:
if obj.IsDict() {
t := v.Type()
v.Set(reflect.MakeMap(t))
dict := Cast[Dict](obj)
if from.IsDict() {
t := to.Type()
to.Set(reflect.MakeMap(t))
dict := cast[Dict](from)
for key, value := range dict.Items() {
vk := reflect.New(t.Key()).Elem()
vv := reflect.New(t.Elem()).Elem()
if !ToValue(key, vk) || !ToValue(value, vv) {
return false
}
v.SetMapIndex(vk, vv)
to.SetMapIndex(vk, vv)
}
return true
} else {
return false
}
case reflect.Struct:
if obj.IsDict() {
dict := Cast[Dict](obj)
t := v.Type()
if from.IsDict() {
dict := cast[Dict](from)
t := to.Type()
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
key := goNameToPythonName(field.Name)
if !dict.HasKey(MakeStr(key)) {
continue
}
value := dict.Get(MakeStr(key))
if !ToValue(value, v.Field(i)) {
if !ToValue(value, to.Field(i)) {
SetTypeError(fmt.Errorf("failed to convert value to %v", field.Name))
return false
}
}
} else {
maps := getGlobalData()
tyMeta := maps.typeMetas[obj.Type().Obj()]
tyMeta := maps.typeMetas[from.Type().Obj()]
if tyMeta == nil {
return false
}
wrapper := (*wrapperType)(unsafe.Pointer(obj.Obj()))
v.Set(reflect.ValueOf(wrapper.goObj).Elem())
wrapper := (*wrapperType)(unsafe.Pointer(from.Obj()))
to.Set(reflect.ValueOf(wrapper.goObj).Elem())
return true
}
default:
panic(fmt.Errorf("unsupported type conversion from Python object to %v", v.Type()))
panic(fmt.Errorf("unsupported type conversion from Python object to %v", to.Type()))
}
return true
}
Expand Down
4 changes: 2 additions & 2 deletions float.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ func (f Float) Float32() float32 {
}

func (f Float) IsInteger() Bool {
fn := Cast[Func](f.Attr("is_integer"))
return Cast[Bool](fn.callNoArgs())
fn := cast[Func](f.Attr("is_integer"))
return cast[Bool](fn.callNoArgs())
}
Loading