Skip to content

Commit 2c6e240

Browse files
committed
add more object tests
1 parent bd250b6 commit 2c6e240

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed

object.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,10 @@ func (obj Object) AttrFunc(name string) Func {
117117

118118
func (obj Object) SetAttr(name string, value any) {
119119
cname := AllocCStr(name)
120-
C.PyObject_SetAttrString(obj.obj, cname, From(value).obj)
120+
if C.PyObject_SetAttrString(obj.obj, cname, From(value).obj) != 0 {
121+
C.PyErr_Print()
122+
panic(fmt.Errorf("failed to set attribute %s", name))
123+
}
121124
C.free(unsafe.Pointer(cname))
122125
}
123126

object_test.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gp
22

33
import (
4+
"bytes"
45
"reflect"
56
"testing"
67
)
@@ -377,6 +378,56 @@ def make_tuple():
377378
t.Error("Object.Obj() should return nil for nil object")
378379
}
379380
}()
381+
382+
func() {
383+
// Test AttrBytes
384+
builtins := ImportModule("types")
385+
objType := builtins.AttrFunc("SimpleNamespace")
386+
obj := objType.Call()
387+
388+
// Create a simple object with bytes attribute
389+
obj.SetAttr("bytes_val", From([]byte("hello")))
390+
391+
if !bytes.Equal(obj.AttrBytes("bytes_val").Bytes(), []byte("hello")) {
392+
t.Error("AttrBytes failed")
393+
}
394+
}()
395+
396+
func() {
397+
// Test Object.Call with kwargs
398+
pyCode := `
399+
def test_func(a, b=10, c="default"):
400+
return (a, b, c)
401+
`
402+
locals := MakeDict(nil)
403+
globals := MakeDict(nil)
404+
globals.Set(MakeStr("__builtins__"), builtins.Object)
405+
406+
code, err := CompileString(pyCode, "<string>", FileInput)
407+
if err != nil {
408+
t.Errorf("CompileString() error = %v", err)
409+
}
410+
EvalCode(code, globals, locals)
411+
412+
testFunc := locals.Get(MakeStr("test_func"))
413+
414+
// Call with positional and keyword arguments
415+
result := testFunc.Call("__call__", 1, KwArgs{
416+
"b": 20,
417+
"c": "custom",
418+
})
419+
420+
tuple := result.AsTuple()
421+
if tuple.Get(0).AsLong().Int64() != 1 {
422+
t.Error("Wrong value for first argument")
423+
}
424+
if tuple.Get(1).AsLong().Int64() != 20 {
425+
t.Error("Wrong value for keyword argument b")
426+
}
427+
if tuple.Get(2).AsStr().String() != "custom" {
428+
t.Error("Wrong value for keyword argument c")
429+
}
430+
}()
380431
}
381432

382433
func TestToValue(t *testing.T) {
@@ -517,3 +568,48 @@ func TestToValue(t *testing.T) {
517568
}
518569
}()
519570
}
571+
572+
func TestFromSpecialCases(t *testing.T) {
573+
setupTest(t)
574+
575+
func() {
576+
// Test From with uint values
577+
tests := []struct {
578+
input uint
579+
expected uint64
580+
}{
581+
{0, 0},
582+
{42, 42},
583+
{^uint(0), ^uint64(0)}, // maximum uint value
584+
}
585+
586+
for _, tt := range tests {
587+
obj := From(tt.input)
588+
if !obj.IsLong() {
589+
t.Errorf("From(uint) did not create Long object")
590+
}
591+
if got := obj.AsLong().Uint64(); got != tt.expected {
592+
t.Errorf("From(%d) = %d, want %d", tt.input, got, tt.expected)
593+
}
594+
}
595+
}()
596+
597+
func() {
598+
// Test From with Object.Obj()
599+
original := From(42)
600+
obj := From(original.Obj())
601+
602+
if !obj.IsLong() {
603+
t.Error("From(Object.Obj()) did not create Long object")
604+
}
605+
if got := obj.AsLong().Int64(); got != 42 {
606+
t.Errorf("From(Object.Obj()) = %d, want 42", got)
607+
}
608+
609+
// Test that the new object is independent
610+
original = From(100)
611+
if got := obj.AsLong().Int64(); got != 42 {
612+
t.Errorf("Object was not independent, got %d after modifying original", got)
613+
}
614+
}()
615+
}

0 commit comments

Comments
 (0)