# HG changeset patch
# User ZyX <[email protected]>
# Date 1368992590 -14400
# Branch python-extended-2
# Node ID bacfe074616e538efcea1f6841cc8a6f99ab20a5
# Parent  7186d7015eb10f23ca656702776806e0706e9fd4
Fix GC

- use proper DESTRUCTOR_FINISH: avoids negative refcounts
- use PyObject_GC_* for objects with tp_traverse and tp_clear
- add RangeTraverse and RangeClear
- use Py_XDECREF in some places

diff -r 7186d7015eb1 -r bacfe074616e src/if_py_both.h
--- a/src/if_py_both.h  Mon May 20 00:27:31 2013 +0400
+++ b/src/if_py_both.h  Sun May 19 23:43:10 2013 +0400
@@ -461,7 +461,7 @@
 }
 
     static PyObject *
-VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
+VimEval(PyObject *self UNUSED, PyObject *args)
 {
     char       *expr;
     typval_T   *our_tv;
@@ -602,7 +602,7 @@
 {
     IterObject *self;
 
-    self = PyObject_NEW(IterObject, &IterType);
+    self = PyObject_GC_New(IterObject, &IterType);
     self->cur = start;
     self->next = next;
     self->destruct = destruct;
@@ -615,9 +615,9 @@
     static void
 IterDestructor(IterObject *self)
 {
+    PyObject_GC_UnTrack((void *)(self));
     self->destruct(self->cur);
-
-    DESTRUCTOR_FINISH(self);
+    PyObject_GC_Del((void *)(self));
 }
 
     static int
@@ -1414,7 +1414,7 @@
 {
     OptionsObject      *self;
 
-    self = PyObject_NEW(OptionsObject, &OptionsType);
+    self = PyObject_GC_New(OptionsObject, &OptionsType);
     if (self == NULL)
        return NULL;
 
@@ -1431,9 +1431,9 @@
     static void
 OptionsDestructor(OptionsObject *self)
 {
-    if (self->fromObj)
-       Py_DECREF(self->fromObj);
-    DESTRUCTOR_FINISH(self);
+    PyObject_GC_UnTrack((void *)(self));
+    Py_XDECREF(self->fromObj);
+    PyObject_GC_Del((void *)(self));
 }
 
     static int
@@ -1870,7 +1870,7 @@
     }
     else
     {
-       self = PyObject_NEW(WindowObject, &WindowType);
+       self = PyObject_GC_New(WindowObject, &WindowType);
        if (self == NULL)
            return NULL;
        self->win = win;
@@ -1885,12 +1885,25 @@
     static void
 WindowDestructor(WindowObject *self)
 {
+    PyObject_GC_UnTrack((void *)(self));
     if (self->win && self->win != INVALID_WINDOW_VALUE)
        WIN_PYTHON_REF(self->win) = NULL;
-
-    Py_DECREF(((PyObject *)(self->tabObject)));
-
-    DESTRUCTOR_FINISH(self);
+     Py_XDECREF(((PyObject *)(self->tabObject)));
+    PyObject_GC_Del((void *)(self));
+}
+
+    static int
+WindowTraverse(WindowObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(((PyObject *)(self->tabObject)));
+    return 0;
+}
+
+    static int
+WindowClear(WindowObject *self)
+{
+    Py_CLEAR(self->tabObject);
+    return 0;
 }
 
     static win_T *
@@ -1910,19 +1923,6 @@
     else
        return firstwin;
 }
-    static int
-WindowTraverse(WindowObject *self, visitproc visit, void *arg)
-{
-    Py_VISIT(((PyObject *)(self->tabObject)));
-    return 0;
-}
-
-    static int
-WindowClear(WindowObject *self)
-{
-    Py_CLEAR(self->tabObject);
-    return 0;
-}
 
     static PyObject *
 WindowAttr(WindowObject *self, char *name)
@@ -2918,7 +2918,7 @@
 {
     BufferObject *bufr;
     RangeObject *self;
-    self = PyObject_NEW(RangeObject, &RangeType);
+    self = PyObject_GC_New(RangeObject, &RangeType);
     if (self == NULL)
        return NULL;
 
@@ -2940,8 +2940,23 @@
     static void
 RangeDestructor(RangeObject *self)
 {
+    PyObject_GC_UnTrack((void *)(self));
     Py_XDECREF(self->buf);
-    DESTRUCTOR_FINISH(self);
+    PyObject_GC_Del((void *)(self));
+}
+
+    static int
+RangeTraverse(RangeObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(((PyObject *)(self->buf)));
+    return 0;
+}
+
+    static int
+RangeClear(RangeObject *self)
+{
+    Py_CLEAR(self->buf);
+    return 0;
 }
 
     static PyInt
@@ -3268,14 +3283,16 @@
     static int
 BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
 {
-    Py_VISIT(buffer);
+    if (buffer)
+       Py_VISIT(buffer);
     return 0;
 }
 
     static int
 BufMapIterClear(PyObject **buffer)
 {
-    Py_CLEAR(*buffer);
+    if (*buffer)
+       Py_CLEAR(*buffer);
     return 0;
 }
 
@@ -4145,6 +4162,8 @@
     RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
     RangeType.tp_doc = "vim Range object";
     RangeType.tp_methods = RangeMethods;
+    RangeType.tp_traverse = (traverseproc)RangeTraverse;
+    RangeType.tp_clear = (inquiry)RangeClear;
 #if PY_MAJOR_VERSION >= 3
     RangeType.tp_getattro = (getattrofunc)RangeGetattro;
     RangeType.tp_alloc = call_PyType_GenericAlloc;
diff -r 7186d7015eb1 -r bacfe074616e src/if_python.c
--- a/src/if_python.c   Mon May 20 00:27:31 2013 +0400
+++ b/src/if_python.c   Sun May 19 23:43:10 2013 +0400
@@ -224,6 +224,9 @@
 # define Py_Finalize dll_Py_Finalize
 # define Py_IsInitialized dll_Py_IsInitialized
 # define _PyObject_New dll__PyObject_New
+# define _PyObject_GC_New dll__PyObject_GC_New
+# define PyObject_GC_Del dll_PyObject_GC_Del
+# define PyObject_GC_UnTrack dll_PyObject_GC_UnTrack
 # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02070000
 #  define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented)
 # endif
@@ -331,6 +334,9 @@
 static void(*dll_Py_Finalize)(void);
 static int(*dll_Py_IsInitialized)(void);
 static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
+static PyObject*(*dll__PyObject_GC_New)(PyTypeObject *);
+static void(*dll_PyObject_GC_Del)(void *);
+static void(*dll_PyObject_GC_UnTrack)(void *);
 static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
 static PyObject* (*dll_PyObject_GetIter)(PyObject *);
 static int (*dll_PyObject_IsTrue)(PyObject *);
@@ -474,6 +480,9 @@
     {"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
     {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
     {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
+    {"_PyObject_GC_New", (PYTHON_PROC*)&dll__PyObject_GC_New},
+    {"PyObject_GC_Del", (PYTHON_PROC*)&dll_PyObject_GC_Del},
+    {"PyObject_GC_UnTrack", (PYTHON_PROC*)&dll_PyObject_GC_UnTrack},
     {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
     {"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter},
     {"PyObject_IsTrue", (PYTHON_PROC*)&dll_PyObject_IsTrue},
@@ -632,7 +641,7 @@
 #define DICTKEY_UNREF
 #define DICTKEY_DECL
 
-#define DESTRUCTOR_FINISH(self) Py_DECREF(self);
+#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self);
 
 #define WIN_PYTHON_REF(win) win->w_python_ref
 #define BUF_PYTHON_REF(buf) buf->b_python_ref
diff -r 7186d7015eb1 -r bacfe074616e src/if_python3.c
--- a/src/if_python3.c  Mon May 20 00:27:31 2013 +0400
+++ b/src/if_python3.c  Sun May 19 23:43:10 2013 +0400
@@ -213,6 +213,9 @@
 #  define PyObject_Malloc py3_PyObject_Malloc
 #  define PyObject_Free py3_PyObject_Free
 # endif
+# define _PyObject_GC_New py3__PyObject_GC_New
+# define PyObject_GC_Del py3_PyObject_GC_Del
+# define PyObject_GC_UnTrack py3_PyObject_GC_UnTrack
 # define PyType_GenericAlloc py3_PyType_GenericAlloc
 # define PyType_GenericNew py3_PyType_GenericNew
 # define PyModule_Create2 py3_PyModule_Create2
@@ -334,6 +337,9 @@
     static void (*py3_PyObject_Free)(void*);
     static void* (*py3_PyObject_Malloc)(size_t);
 # endif
+static PyObject*(*py3__PyObject_GC_New)(PyTypeObject *);
+static void(*py3_PyObject_GC_Del)(void *);
+static void(*py3_PyObject_GC_UnTrack)(void *);
 static int (*py3_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
 
 static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
@@ -463,6 +469,9 @@
     {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
     {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
 # endif
+    {"_PyObject_GC_New", (PYTHON_PROC*)&py3__PyObject_GC_New},
+    {"PyObject_GC_Del", (PYTHON_PROC*)&py3_PyObject_GC_Del},
+    {"PyObject_GC_UnTrack", (PYTHON_PROC*)&py3_PyObject_GC_UnTrack},
     {"PyType_IsSubtype", (PYTHON_PROC*)&py3_PyType_IsSubtype},
     {"PyCapsule_New", (PYTHON_PROC*)&py3_PyCapsule_New},
     {"PyCapsule_GetPointer", (PYTHON_PROC*)&py3_PyCapsule_GetPointer},
@@ -638,7 +647,7 @@
     if (bytes != NULL) \
        Py_XDECREF(bytes);
 
-#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self);
+#define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self)
 
 #define WIN_PYTHON_REF(win) win->w_python3_ref
 #define BUF_PYTHON_REF(buf) buf->b_python3_ref

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


diff -cr vim.7186d7015eb1/src/if_py_both.h vim.bacfe074616e/src/if_py_both.h
*** vim.7186d7015eb1/src/if_py_both.h	2013-05-20 00:35:47.153018520 +0400
--- vim.bacfe074616e/src/if_py_both.h	2013-05-20 00:35:47.163018420 +0400
***************
*** 461,467 ****
  }
  
      static PyObject *
! VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
  {
      char	*expr;
      typval_T	*our_tv;
--- 461,467 ----
  }
  
      static PyObject *
! VimEval(PyObject *self UNUSED, PyObject *args)
  {
      char	*expr;
      typval_T	*our_tv;
***************
*** 602,608 ****
  {
      IterObject *self;
  
!     self = PyObject_NEW(IterObject, &IterType);
      self->cur = start;
      self->next = next;
      self->destruct = destruct;
--- 602,608 ----
  {
      IterObject *self;
  
!     self = PyObject_GC_New(IterObject, &IterType);
      self->cur = start;
      self->next = next;
      self->destruct = destruct;
***************
*** 615,623 ****
      static void
  IterDestructor(IterObject *self)
  {
      self->destruct(self->cur);
! 
!     DESTRUCTOR_FINISH(self);
  }
  
      static int
--- 615,623 ----
      static void
  IterDestructor(IterObject *self)
  {
+     PyObject_GC_UnTrack((void *)(self));
      self->destruct(self->cur);
!     PyObject_GC_Del((void *)(self));
  }
  
      static int
***************
*** 1414,1420 ****
  {
      OptionsObject	*self;
  
!     self = PyObject_NEW(OptionsObject, &OptionsType);
      if (self == NULL)
  	return NULL;
  
--- 1414,1420 ----
  {
      OptionsObject	*self;
  
!     self = PyObject_GC_New(OptionsObject, &OptionsType);
      if (self == NULL)
  	return NULL;
  
***************
*** 1431,1439 ****
      static void
  OptionsDestructor(OptionsObject *self)
  {
!     if (self->fromObj)
! 	Py_DECREF(self->fromObj);
!     DESTRUCTOR_FINISH(self);
  }
  
      static int
--- 1431,1439 ----
      static void
  OptionsDestructor(OptionsObject *self)
  {
!     PyObject_GC_UnTrack((void *)(self));
!     Py_XDECREF(self->fromObj);
!     PyObject_GC_Del((void *)(self));
  }
  
      static int
***************
*** 1870,1876 ****
      }
      else
      {
! 	self = PyObject_NEW(WindowObject, &WindowType);
  	if (self == NULL)
  	    return NULL;
  	self->win = win;
--- 1870,1876 ----
      }
      else
      {
! 	self = PyObject_GC_New(WindowObject, &WindowType);
  	if (self == NULL)
  	    return NULL;
  	self->win = win;
***************
*** 1885,1896 ****
      static void
  WindowDestructor(WindowObject *self)
  {
      if (self->win && self->win != INVALID_WINDOW_VALUE)
  	WIN_PYTHON_REF(self->win) = NULL;
  
!     Py_DECREF(((PyObject *)(self->tabObject)));
  
!     DESTRUCTOR_FINISH(self);
  }
  
      static win_T *
--- 1885,1909 ----
      static void
  WindowDestructor(WindowObject *self)
  {
+     PyObject_GC_UnTrack((void *)(self));
      if (self->win && self->win != INVALID_WINDOW_VALUE)
  	WIN_PYTHON_REF(self->win) = NULL;
+      Py_XDECREF(((PyObject *)(self->tabObject)));
+     PyObject_GC_Del((void *)(self));
+ }
  
!     static int
! WindowTraverse(WindowObject *self, visitproc visit, void *arg)
! {
!     Py_VISIT(((PyObject *)(self->tabObject)));
!     return 0;
! }
  
!     static int
! WindowClear(WindowObject *self)
! {
!     Py_CLEAR(self->tabObject);
!     return 0;
  }
  
      static win_T *
***************
*** 1910,1928 ****
      else
  	return firstwin;
  }
-     static int
- WindowTraverse(WindowObject *self, visitproc visit, void *arg)
- {
-     Py_VISIT(((PyObject *)(self->tabObject)));
-     return 0;
- }
- 
-     static int
- WindowClear(WindowObject *self)
- {
-     Py_CLEAR(self->tabObject);
-     return 0;
- }
  
      static PyObject *
  WindowAttr(WindowObject *self, char *name)
--- 1923,1928 ----
***************
*** 2918,2924 ****
  {
      BufferObject *bufr;
      RangeObject *self;
!     self = PyObject_NEW(RangeObject, &RangeType);
      if (self == NULL)
  	return NULL;
  
--- 2918,2924 ----
  {
      BufferObject *bufr;
      RangeObject *self;
!     self = PyObject_GC_New(RangeObject, &RangeType);
      if (self == NULL)
  	return NULL;
  
***************
*** 2940,2947 ****
      static void
  RangeDestructor(RangeObject *self)
  {
      Py_XDECREF(self->buf);
!     DESTRUCTOR_FINISH(self);
  }
  
      static PyInt
--- 2940,2962 ----
      static void
  RangeDestructor(RangeObject *self)
  {
+     PyObject_GC_UnTrack((void *)(self));
      Py_XDECREF(self->buf);
!     PyObject_GC_Del((void *)(self));
! }
! 
!     static int
! RangeTraverse(RangeObject *self, visitproc visit, void *arg)
! {
!     Py_VISIT(((PyObject *)(self->buf)));
!     return 0;
! }
! 
!     static int
! RangeClear(RangeObject *self)
! {
!     Py_CLEAR(self->buf);
!     return 0;
  }
  
      static PyInt
***************
*** 3268,3281 ****
      static int
  BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
  {
!     Py_VISIT(buffer);
      return 0;
  }
  
      static int
  BufMapIterClear(PyObject **buffer)
  {
!     Py_CLEAR(*buffer);
      return 0;
  }
  
--- 3283,3298 ----
      static int
  BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
  {
!     if (buffer)
! 	Py_VISIT(buffer);
      return 0;
  }
  
      static int
  BufMapIterClear(PyObject **buffer)
  {
!     if (*buffer)
! 	Py_CLEAR(*buffer);
      return 0;
  }
  
***************
*** 4145,4150 ****
--- 4162,4169 ----
      RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
      RangeType.tp_doc = "vim Range object";
      RangeType.tp_methods = RangeMethods;
+     RangeType.tp_traverse = (traverseproc)RangeTraverse;
+     RangeType.tp_clear = (inquiry)RangeClear;
  #if PY_MAJOR_VERSION >= 3
      RangeType.tp_getattro = (getattrofunc)RangeGetattro;
      RangeType.tp_alloc = call_PyType_GenericAlloc;
diff -cr vim.7186d7015eb1/src/if_python3.c vim.bacfe074616e/src/if_python3.c
*** vim.7186d7015eb1/src/if_python3.c	2013-05-20 00:35:47.149018560 +0400
--- vim.bacfe074616e/src/if_python3.c	2013-05-20 00:35:47.160018450 +0400
***************
*** 213,218 ****
--- 213,221 ----
  #  define PyObject_Malloc py3_PyObject_Malloc
  #  define PyObject_Free py3_PyObject_Free
  # endif
+ # define _PyObject_GC_New py3__PyObject_GC_New
+ # define PyObject_GC_Del py3_PyObject_GC_Del
+ # define PyObject_GC_UnTrack py3_PyObject_GC_UnTrack
  # define PyType_GenericAlloc py3_PyType_GenericAlloc
  # define PyType_GenericNew py3_PyType_GenericNew
  # define PyModule_Create2 py3_PyModule_Create2
***************
*** 334,339 ****
--- 337,345 ----
      static void (*py3_PyObject_Free)(void*);
      static void* (*py3_PyObject_Malloc)(size_t);
  # endif
+ static PyObject*(*py3__PyObject_GC_New)(PyTypeObject *);
+ static void(*py3_PyObject_GC_Del)(void *);
+ static void(*py3_PyObject_GC_UnTrack)(void *);
  static int (*py3_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
  
  static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
***************
*** 463,468 ****
--- 469,477 ----
      {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
      {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
  # endif
+     {"_PyObject_GC_New", (PYTHON_PROC*)&py3__PyObject_GC_New},
+     {"PyObject_GC_Del", (PYTHON_PROC*)&py3_PyObject_GC_Del},
+     {"PyObject_GC_UnTrack", (PYTHON_PROC*)&py3_PyObject_GC_UnTrack},
      {"PyType_IsSubtype", (PYTHON_PROC*)&py3_PyType_IsSubtype},
      {"PyCapsule_New", (PYTHON_PROC*)&py3_PyCapsule_New},
      {"PyCapsule_GetPointer", (PYTHON_PROC*)&py3_PyCapsule_GetPointer},
***************
*** 638,644 ****
      if (bytes != NULL) \
  	Py_XDECREF(bytes);
  
! #define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self);
  
  #define WIN_PYTHON_REF(win) win->w_python3_ref
  #define BUF_PYTHON_REF(buf) buf->b_python3_ref
--- 647,653 ----
      if (bytes != NULL) \
  	Py_XDECREF(bytes);
  
! #define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self)
  
  #define WIN_PYTHON_REF(win) win->w_python3_ref
  #define BUF_PYTHON_REF(buf) buf->b_python3_ref
diff -cr vim.7186d7015eb1/src/if_python.c vim.bacfe074616e/src/if_python.c
*** vim.7186d7015eb1/src/if_python.c	2013-05-20 00:35:47.156018490 +0400
--- vim.bacfe074616e/src/if_python.c	2013-05-20 00:35:47.166018391 +0400
***************
*** 224,229 ****
--- 224,232 ----
  # define Py_Finalize dll_Py_Finalize
  # define Py_IsInitialized dll_Py_IsInitialized
  # define _PyObject_New dll__PyObject_New
+ # define _PyObject_GC_New dll__PyObject_GC_New
+ # define PyObject_GC_Del dll_PyObject_GC_Del
+ # define PyObject_GC_UnTrack dll_PyObject_GC_UnTrack
  # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02070000
  #  define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented)
  # endif
***************
*** 331,336 ****
--- 334,342 ----
  static void(*dll_Py_Finalize)(void);
  static int(*dll_Py_IsInitialized)(void);
  static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
+ static PyObject*(*dll__PyObject_GC_New)(PyTypeObject *);
+ static void(*dll_PyObject_GC_Del)(void *);
+ static void(*dll_PyObject_GC_UnTrack)(void *);
  static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
  static PyObject* (*dll_PyObject_GetIter)(PyObject *);
  static int (*dll_PyObject_IsTrue)(PyObject *);
***************
*** 474,479 ****
--- 480,488 ----
      {"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
      {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
      {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
+     {"_PyObject_GC_New", (PYTHON_PROC*)&dll__PyObject_GC_New},
+     {"PyObject_GC_Del", (PYTHON_PROC*)&dll_PyObject_GC_Del},
+     {"PyObject_GC_UnTrack", (PYTHON_PROC*)&dll_PyObject_GC_UnTrack},
      {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
      {"PyObject_GetIter", (PYTHON_PROC*)&dll_PyObject_GetIter},
      {"PyObject_IsTrue", (PYTHON_PROC*)&dll_PyObject_IsTrue},
***************
*** 632,638 ****
  #define DICTKEY_UNREF
  #define DICTKEY_DECL
  
! #define DESTRUCTOR_FINISH(self) Py_DECREF(self);
  
  #define WIN_PYTHON_REF(win) win->w_python_ref
  #define BUF_PYTHON_REF(buf) buf->b_python_ref
--- 641,647 ----
  #define DICTKEY_UNREF
  #define DICTKEY_DECL
  
! #define DESTRUCTOR_FINISH(self) Py_TYPE(self)->tp_free((PyObject*)self);
  
  #define WIN_PYTHON_REF(win) win->w_python_ref
  #define BUF_PYTHON_REF(buf) buf->b_python_ref

Raspunde prin e-mail lui