From 01a74b2fa1b7eef7e4c4f575e353662eeb6e3b49 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= <martin@v.loewis.de>
Date: Sun, 19 Oct 2003 18:30:01 +0000
Subject: Make CObjects mutable. Fixes #477441.

---
 Doc/api/concrete.tex | 16 +++++++++++-----
 Include/cobject.h    |  3 +++
 Misc/NEWS            |  2 ++
 Objects/cobject.c    | 14 ++++++++++++++
 4 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/Doc/api/concrete.tex b/Doc/api/concrete.tex
index cc552b4..7e784c7 100644
--- a/Doc/api/concrete.tex
+++ b/Doc/api/concrete.tex
@@ -2479,34 +2479,40 @@ information on using these objects.
 \end{ctypedesc}
 
 \begin{cfuncdesc}{int}{PyCObject_Check}{PyObject *p}
-  Returns true if its argument is a \ctype{PyCObject}.
+  Return true if its argument is a \ctype{PyCObject}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyCObject_FromVoidPtr}{void* cobj,
                                                     void (*destr)(void *)}
-  Creates a \ctype{PyCObject} from the \code{void *}\var{cobj}.  The
+  Create a \ctype{PyCObject} from the \code{void *}\var{cobj}.  The
   \var{destr} function will be called when the object is reclaimed,
   unless it is \NULL.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyCObject_FromVoidPtrAndDesc}{void* cobj,
 	                          void* desc, void (*destr)(void *, void *)}
-  Creates a \ctype{PyCObject} from the \ctype{void *}\var{cobj}.  The
+  Create a \ctype{PyCObject} from the \ctype{void *}\var{cobj}.  The
   \var{destr} function will be called when the object is reclaimed.
   The \var{desc} argument can be used to pass extra callback data for
   the destructor function.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{void*}{PyCObject_AsVoidPtr}{PyObject* self}
-  Returns the object \ctype{void *} that the \ctype{PyCObject}
+  Return the object \ctype{void *} that the \ctype{PyCObject}
   \var{self} was created with.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{void*}{PyCObject_GetDesc}{PyObject* self}
-  Returns the description \ctype{void *} that the \ctype{PyCObject}
+  Return the description \ctype{void *} that the \ctype{PyCObject}
   \var{self} was created with.
 \end{cfuncdesc}
 
+\begin{cfuncdesc}{int}{PyCObject_SetVoidPtr}{PyObject* self, void* cobj}
+  Set the void pointer inside \var{self} to \var{cobj}. 
+  The \ctype{PyCObject} must not have an associated destructor.
+  Return true on success, false on failure.
+\end{cfuncdesc}
+
 
 \subsection{Cell Objects \label{cell-objects}}
 
diff --git a/Include/cobject.h b/Include/cobject.h
index ccf8b32..ad23ac8 100644
--- a/Include/cobject.h
+++ b/Include/cobject.h
@@ -45,6 +45,9 @@ PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *);
 /* Import a pointer to a C object from a module using a PyCObject. */
 PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name);
 
+/* Modify a C object. Fails (==0) if object has a destructor. */
+PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Misc/NEWS b/Misc/NEWS
index 967f93a..87a82e9 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 2.4 alpha 1?
 Core and builtins
 -----------------
 
+- CObjects are now mutable (on the C level) through PyCObject_SetVoidPtr.
+
 - list.sort() now supports three keyword arguments:  cmp, key, and reverse.
   The key argument can be a function of one argument that extracts a
   comparison key from the original record:  mylist.sort(key=str.lower).
diff --git a/Objects/cobject.c b/Objects/cobject.c
index eed906a..5a6be43 100644
--- a/Objects/cobject.c
+++ b/Objects/cobject.c
@@ -99,6 +99,20 @@ PyCObject_Import(char *module_name, char *name)
     return r;
 }
 
+int
+PyCObject_SetVoidPtr(PyObject *_self, void *cobj)
+{
+    PyCObject* self = (PyCObject*)_self;
+    if (self == NULL || !PyCObject_Check(self) ||
+	self->destructor != NULL) {
+	PyErr_SetString(PyExc_TypeError, 
+			"Invalid call to PyCObject_SetVoidPtr");
+	return 0;
+    }
+    self->cobject = cobj;
+    return 1;
+}
+
 static void
 PyCObject_dealloc(PyCObject *self)
 {
-- 
cgit v0.12

