object.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package python
  2. // See:
  3. // https://docs.python.org/3/c-api/object.html
  4. import (
  5. "unsafe"
  6. )
  7. /*
  8. #define PY_SSIZE_T_CLEAN
  9. #include <Python.h>
  10. */
  11. import "C"
  12. // fmt.Stringer interface
  13. func (self *Reference) String() string {
  14. if str := C.PyObject_Str(self.Object); str != nil {
  15. if data := C.PyUnicode_AsUTF8String(str); data != nil {
  16. defer C.Py_DecRef(data)
  17. if string_ := C.PyBytes_AsString(data); string_ != nil {
  18. return C.GoString(string_)
  19. } else {
  20. return ""
  21. }
  22. } else {
  23. return ""
  24. }
  25. } else {
  26. return ""
  27. }
  28. }
  29. func (self *Reference) Acquire() {
  30. C.Py_IncRef(self.Object)
  31. }
  32. func (self *Reference) Release() {
  33. C.Py_DecRef(self.Object)
  34. }
  35. func (self *Reference) Str() (*Reference, error) {
  36. if str := C.PyObject_Str(self.Object); str != nil {
  37. return NewReference(str), nil
  38. } else {
  39. return nil, GetError()
  40. }
  41. }
  42. func (self *Reference) HasAttr(name string) bool {
  43. name_ := C.CString(name)
  44. defer C.free(unsafe.Pointer(name_))
  45. res := C.PyObject_HasAttrString(self.Object, name_)
  46. return res == 1
  47. }
  48. func (self *Reference) GetAttr(name string) (*Reference, error) {
  49. name_ := C.CString(name)
  50. defer C.free(unsafe.Pointer(name_))
  51. if attr := C.PyObject_GetAttrString(self.Object, name_); attr != nil {
  52. return NewReference(attr), nil
  53. } else {
  54. return nil, GetError()
  55. }
  56. }
  57. func (self *Reference) GetAttrDict() map[string]*Reference {
  58. obj := C.PyObject_GenericGetDict(self.Object, nil)
  59. defer C.Py_DecRef(obj)
  60. dict := make(map[string]*Reference)
  61. keys := C.PyDict_Keys(obj)
  62. //if HasException() {
  63. // fmt.Printf("%v\n", GetError())
  64. // return dict
  65. //}
  66. defer C.Py_DecRef(keys)
  67. iterator := C.PyObject_GetIter(keys)
  68. defer C.Py_DecRef(iterator)
  69. for {
  70. key := C.PyIter_Next(iterator);
  71. if key == nil { break }
  72. value := C.PyDict_GetItem(obj, key)
  73. if value == nil { continue }
  74. keyRef := NewReference(key)
  75. dict[keyRef.String()] = NewReference(value)
  76. keyRef.Release()
  77. }
  78. return dict
  79. }
  80. func (self *Reference) SetAttr(name string, reference *Reference) error {
  81. name_ := C.CString(name)
  82. defer C.free(unsafe.Pointer(name_))
  83. if C.PyObject_SetAttrString(self.Object, name_, reference.Object) == 0 {
  84. return nil
  85. } else {
  86. return GetError()
  87. }
  88. }
  89. func (self *Reference) SetAttrI(name string, primite interface{}) error {
  90. value, err := NewPrimitiveReference(primite)
  91. if err != nil { return err }
  92. return self.SetAttr(name, value)
  93. }
  94. func (self *Reference) Call(args ...interface{}) (*Reference, error) {
  95. if args_, err := NewTuple(args...); err == nil {
  96. if kw, err := NewDict(); err == nil {
  97. return self.CallRaw(args_, kw)
  98. } else {
  99. return nil, err
  100. }
  101. } else {
  102. return nil, err
  103. }
  104. }
  105. func (self *Reference) CallRaw(args *Reference, kw *Reference) (*Reference, error) {
  106. if r := C.PyObject_Call(self.Object, args.Object, kw.Object); r != nil {
  107. return NewReference(r), nil
  108. } else {
  109. return nil, GetError()
  110. }
  111. }