PackTuple returns a new *Tuple which contains the arguments. This tuple is ready to use. Return value: New Reference.
(items ...*Base)
| 41 | // |
| 42 | // Return value: New Reference. |
| 43 | func PackTuple(items ...*Base) *Tuple { |
| 44 | ret := C.PyTuple_New(C.Py_ssize_t(len(items))) |
| 45 | |
| 46 | // Since the ob_item array has a size of 1, Go won't let us index more than |
| 47 | // a single entry, and if we try and use our own local type definition with |
| 48 | // a flexible array member then cgo converts it to [0]byte which is even |
| 49 | // less useful. So, we resort to pointer manipulation - which is |
| 50 | // unfortunate, as it's messy in Go. |
| 51 | |
| 52 | // base is a pointer to the first item in the array of PyObject pointers. |
| 53 | // step is the size of a PyObject * (i.e. the number of bytes we need to add |
| 54 | // to get to the next item). |
| 55 | base := unsafe.Pointer(&(*C.PyTupleObject)(unsafe.Pointer(ret)).ob_item[0]) |
| 56 | step := uintptr(C.tupleItemSize()) |
| 57 | |
| 58 | for _, item := range items { |
| 59 | item.Incref() |
| 60 | *(**C.PyObject)(base) = item.c() |
| 61 | |
| 62 | // Move base to point to the next item, by incrementing by step bytes |
| 63 | base = unsafe.Pointer(uintptr(base) + step) |
| 64 | } |
| 65 | return newTuple(ret) |
| 66 | } |
| 67 | |
| 68 | func (t *Tuple) CheckExact() bool { |
| 69 | ret := C.tupleCheckE(t.c()) |
searching dependent graphs…