Commit 5513b31c authored by Barry Warsaw's avatar Barry Warsaw

Code cleanup, and a bunch of XXX comments. Specifically,

UPDATE_STATE_IF_NECESSARY: Un-macroize this.  Renamed to function
unghostify() and changed (slightly) the return semantics.

ghostify(): Don't use the NON_GHOST_COUNT macro.  Add some comments.

Per_setstate(), Per__getstate__(), Per_getattr(), _setattro(): Use
unghostify() instead of UPDATE_STATE_IF_NECESSARY.
parent bbd033c3
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
static char cPersistence_doc_string[] = static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n" "Defines Persistent mixin class for persistent objects.\n"
"\n" "\n"
"$Id: cPersistence.c,v 1.54 2002/04/02 11:11:45 htrd Exp $\n"; "$Id: cPersistence.c,v 1.55 2002/04/02 22:17:24 bwarsaw Exp $\n";
#include "cPersistence.h" #include "cPersistence.h"
/* XXX What is this structure used for? */
struct ccobject_head_struct { struct ccobject_head_struct {
CACHE_HEAD CACHE_HEAD
}; };
...@@ -114,31 +115,42 @@ callmethod1(PyObject *self, PyObject *name, PyObject *arg) ...@@ -114,31 +115,42 @@ callmethod1(PyObject *self, PyObject *name, PyObject *arg)
return self; return self;
} }
#define UPDATE_STATE_IF_NECESSARY(self, ER) \
if(self->state < 0 && self->jar) \ static void ghostify(cPersistentObject*);
{ \
PyObject *r; \ /* Load the state of the object, unghostifying it. Upon success, return 1.
\ * If an error occurred, re-ghostify the object and return 0.
int *count = NON_GHOST_COUNT(self); \ */
if(count) \ static int
{ \ unghostify(cPersistentObject *self)
(*count)++; \ {
self->ring.next = HOME(self); \ if (self->state < 0 && self->jar) {
self->ring.prev = HOME(self)->prev; \ PyObject *r;
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; \ /* XXX Is it ever possibly to not have a cache? */
Py_INCREF(self); \ if (self->cache) {
} \ /* Create a node in the ring for this unghostified object. */
self->state=cPersistent_CHANGED_STATE; \ self->cache->non_ghost_count++;
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \ self->ring.next = &self->cache->ring_home;
{ \ self->ring.prev = (&(self)->cache->ring_home)->prev;
ghostify(self); \ HOME(self)->prev->next = &self->ring;
return ER; \ HOME(self)->prev = &self->ring;
} \ Py_INCREF(self);
self->state=cPersistent_UPTODATE_STATE; \ }
Py_DECREF(r); \ self->state = cPersistent_CHANGED_STATE;
/* Call the object's __setstate__() */
r = callmethod1(self->jar, py_setstate, (PyObject*)self);
if (r == NULL) {
ghostify(self);
return 0;
}
self->state = cPersistent_UPTODATE_STATE;
Py_DECREF(r);
}
return 1;
} }
#define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) accessed(self) #define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) accessed(self)
/****************************************************************************/ /****************************************************************************/
...@@ -161,22 +173,31 @@ accessed(cPersistentObject *self) ...@@ -161,22 +173,31 @@ accessed(cPersistentObject *self)
static void static void
ghostify(cPersistentObject *self) ghostify(cPersistentObject *self)
{ {
int *count; /* are we already a ghost? */
count = NON_GHOST_COUNT(self); if (self->state == cPersistent_GHOST_STATE)
if(count && (self->state>=0)) return;
{ /* XXX is it ever possible to not have a cache? */
(*count)--; if (self->cache == NULL) {
self->ring.next->prev = self->ring.prev;
self->ring.prev->next = self->ring.next;
self->ring.prev = NULL;
self->ring.next = NULL;
self->state = cPersistent_GHOST_STATE;
Py_DECREF(self);
}
else
{
self->state = cPersistent_GHOST_STATE; self->state = cPersistent_GHOST_STATE;
return;
} }
/* if we're ghostifying an object, we better have some non-ghosts */
assert(self->cache->non_ghost_count > 0);
self->cache->non_ghost_count--;
self->ring.next->prev = self->ring.prev;
self->ring.prev->next = self->ring.next;
self->ring.prev = NULL;
self->ring.next = NULL;
self->state = cPersistent_GHOST_STATE;
/* We remove the reference to the just ghosted object that the ring
* holds. Note that the dictionary of oids->objects has an uncounted
* reference, so if the ring's reference was the only one, this frees
* the ghost object. Note further that the object's dealloc knows to
* inform the dictionary that it is going away.
*/
Py_DECREF(self);
} }
static void static void
...@@ -293,53 +314,59 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args) ...@@ -293,53 +314,59 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
static int static int
Per_setstate(cPersistentObject *self) Per_setstate(cPersistentObject *self)
{ {
UPDATE_STATE_IF_NECESSARY(self, -1); if (!unghostify(self))
self->state=cPersistent_STICKY_STATE; return -1;
return 0; self->state = cPersistent_STICKY_STATE;
return 0;
} }
static PyObject * static PyObject *
Per__getstate__(cPersistentObject *self, PyObject *args) Per__getstate__(cPersistentObject *self, PyObject *args)
{ {
PyObject *__dict__, *d=0; PyObject *__dict__, *d=0;
if (!checknoargs(args)) return NULL; if (!checknoargs(args))
return NULL;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
if(idebug_log < 0) call_debug("get",self); if (idebug_log < 0)
call_debug("get",self);
#endif #endif
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
if(HasInstDict(self) && (__dict__=INSTANCE_DICT(self))) if (HasInstDict(self) && (__dict__=INSTANCE_DICT(self))) {
{ PyObject *k, *v;
PyObject *k, *v; int pos;
int pos; char *ck;
char *ck;
for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) {
{ if(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
if(PyString_Check(k) && (ck=PyString_AS_STRING(k)) && (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
(*ck=='_' && ck[1]=='v' && ck[2]=='_'))
{ {
UNLESS(d=PyDict_New()) goto err; if ((d=PyDict_New()) == NULL)
for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) goto err;
UNLESS(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
(*ck=='_' && ck[1]=='v' && ck[2]=='_')) for (pos=0; PyDict_Next(__dict__, &pos, &k, &v); )
if(PyDict_SetItem(d,k,v) < 0) goto err; UNLESS(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
return d; (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
{
if (PyDict_SetItem(d,k,v) < 0)
goto err;
}
return d;
} }
} }
} }
else else
__dict__=Py_None; __dict__ = Py_None;
Py_INCREF(__dict__);
return __dict__;
err: Py_INCREF(__dict__);
Py_XDECREF(d); return __dict__;
return NULL; err:
Py_XDECREF(d);
return NULL;
} }
static PyObject * static PyObject *
...@@ -466,7 +493,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name, ...@@ -466,7 +493,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
case 'm': case 'm':
if(strcmp(n,"time")==0) if(strcmp(n,"time")==0)
{ {
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
accessed(self); accessed(self);
...@@ -498,7 +526,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name, ...@@ -498,7 +526,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
(strcmp(name,"dict__")==0 || strcmp(name,"class__")==0 (strcmp(name,"dict__")==0 || strcmp(name,"class__")==0
|| strcmp(name, "of__")==0))) || strcmp(name, "of__")==0)))
{ {
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
accessed(self); accessed(self);
} }
...@@ -614,7 +643,8 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -614,7 +643,8 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
} }
else else
{ {
UPDATE_STATE_IF_NECESSARY(self, -1); if (!unghostify(self))
return -1;
accessed(self); accessed(self);
......
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
static char cPersistence_doc_string[] = static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n" "Defines Persistent mixin class for persistent objects.\n"
"\n" "\n"
"$Id: cPersistence.c,v 1.54 2002/04/02 11:11:45 htrd Exp $\n"; "$Id: cPersistence.c,v 1.55 2002/04/02 22:17:24 bwarsaw Exp $\n";
#include "cPersistence.h" #include "cPersistence.h"
/* XXX What is this structure used for? */
struct ccobject_head_struct { struct ccobject_head_struct {
CACHE_HEAD CACHE_HEAD
}; };
...@@ -114,31 +115,42 @@ callmethod1(PyObject *self, PyObject *name, PyObject *arg) ...@@ -114,31 +115,42 @@ callmethod1(PyObject *self, PyObject *name, PyObject *arg)
return self; return self;
} }
#define UPDATE_STATE_IF_NECESSARY(self, ER) \
if(self->state < 0 && self->jar) \ static void ghostify(cPersistentObject*);
{ \
PyObject *r; \ /* Load the state of the object, unghostifying it. Upon success, return 1.
\ * If an error occurred, re-ghostify the object and return 0.
int *count = NON_GHOST_COUNT(self); \ */
if(count) \ static int
{ \ unghostify(cPersistentObject *self)
(*count)++; \ {
self->ring.next = HOME(self); \ if (self->state < 0 && self->jar) {
self->ring.prev = HOME(self)->prev; \ PyObject *r;
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; \ /* XXX Is it ever possibly to not have a cache? */
Py_INCREF(self); \ if (self->cache) {
} \ /* Create a node in the ring for this unghostified object. */
self->state=cPersistent_CHANGED_STATE; \ self->cache->non_ghost_count++;
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \ self->ring.next = &self->cache->ring_home;
{ \ self->ring.prev = (&(self)->cache->ring_home)->prev;
ghostify(self); \ HOME(self)->prev->next = &self->ring;
return ER; \ HOME(self)->prev = &self->ring;
} \ Py_INCREF(self);
self->state=cPersistent_UPTODATE_STATE; \ }
Py_DECREF(r); \ self->state = cPersistent_CHANGED_STATE;
/* Call the object's __setstate__() */
r = callmethod1(self->jar, py_setstate, (PyObject*)self);
if (r == NULL) {
ghostify(self);
return 0;
}
self->state = cPersistent_UPTODATE_STATE;
Py_DECREF(r);
}
return 1;
} }
#define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) accessed(self) #define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) accessed(self)
/****************************************************************************/ /****************************************************************************/
...@@ -161,22 +173,31 @@ accessed(cPersistentObject *self) ...@@ -161,22 +173,31 @@ accessed(cPersistentObject *self)
static void static void
ghostify(cPersistentObject *self) ghostify(cPersistentObject *self)
{ {
int *count; /* are we already a ghost? */
count = NON_GHOST_COUNT(self); if (self->state == cPersistent_GHOST_STATE)
if(count && (self->state>=0)) return;
{ /* XXX is it ever possible to not have a cache? */
(*count)--; if (self->cache == NULL) {
self->ring.next->prev = self->ring.prev;
self->ring.prev->next = self->ring.next;
self->ring.prev = NULL;
self->ring.next = NULL;
self->state = cPersistent_GHOST_STATE;
Py_DECREF(self);
}
else
{
self->state = cPersistent_GHOST_STATE; self->state = cPersistent_GHOST_STATE;
return;
} }
/* if we're ghostifying an object, we better have some non-ghosts */
assert(self->cache->non_ghost_count > 0);
self->cache->non_ghost_count--;
self->ring.next->prev = self->ring.prev;
self->ring.prev->next = self->ring.next;
self->ring.prev = NULL;
self->ring.next = NULL;
self->state = cPersistent_GHOST_STATE;
/* We remove the reference to the just ghosted object that the ring
* holds. Note that the dictionary of oids->objects has an uncounted
* reference, so if the ring's reference was the only one, this frees
* the ghost object. Note further that the object's dealloc knows to
* inform the dictionary that it is going away.
*/
Py_DECREF(self);
} }
static void static void
...@@ -293,53 +314,59 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args) ...@@ -293,53 +314,59 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
static int static int
Per_setstate(cPersistentObject *self) Per_setstate(cPersistentObject *self)
{ {
UPDATE_STATE_IF_NECESSARY(self, -1); if (!unghostify(self))
self->state=cPersistent_STICKY_STATE; return -1;
return 0; self->state = cPersistent_STICKY_STATE;
return 0;
} }
static PyObject * static PyObject *
Per__getstate__(cPersistentObject *self, PyObject *args) Per__getstate__(cPersistentObject *self, PyObject *args)
{ {
PyObject *__dict__, *d=0; PyObject *__dict__, *d=0;
if (!checknoargs(args)) return NULL; if (!checknoargs(args))
return NULL;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
if(idebug_log < 0) call_debug("get",self); if (idebug_log < 0)
call_debug("get",self);
#endif #endif
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
if(HasInstDict(self) && (__dict__=INSTANCE_DICT(self))) if (HasInstDict(self) && (__dict__=INSTANCE_DICT(self))) {
{ PyObject *k, *v;
PyObject *k, *v; int pos;
int pos; char *ck;
char *ck;
for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) {
{ if(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
if(PyString_Check(k) && (ck=PyString_AS_STRING(k)) && (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
(*ck=='_' && ck[1]=='v' && ck[2]=='_'))
{ {
UNLESS(d=PyDict_New()) goto err; if ((d=PyDict_New()) == NULL)
for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) goto err;
UNLESS(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
(*ck=='_' && ck[1]=='v' && ck[2]=='_')) for (pos=0; PyDict_Next(__dict__, &pos, &k, &v); )
if(PyDict_SetItem(d,k,v) < 0) goto err; UNLESS(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
return d; (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
{
if (PyDict_SetItem(d,k,v) < 0)
goto err;
}
return d;
} }
} }
} }
else else
__dict__=Py_None; __dict__ = Py_None;
Py_INCREF(__dict__);
return __dict__;
err: Py_INCREF(__dict__);
Py_XDECREF(d); return __dict__;
return NULL; err:
Py_XDECREF(d);
return NULL;
} }
static PyObject * static PyObject *
...@@ -466,7 +493,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name, ...@@ -466,7 +493,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
case 'm': case 'm':
if(strcmp(n,"time")==0) if(strcmp(n,"time")==0)
{ {
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
accessed(self); accessed(self);
...@@ -498,7 +526,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name, ...@@ -498,7 +526,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
(strcmp(name,"dict__")==0 || strcmp(name,"class__")==0 (strcmp(name,"dict__")==0 || strcmp(name,"class__")==0
|| strcmp(name, "of__")==0))) || strcmp(name, "of__")==0)))
{ {
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
accessed(self); accessed(self);
} }
...@@ -614,7 +643,8 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -614,7 +643,8 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
} }
else else
{ {
UPDATE_STATE_IF_NECESSARY(self, -1); if (!unghostify(self))
return -1;
accessed(self); accessed(self);
......
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
static char cPersistence_doc_string[] = static char cPersistence_doc_string[] =
"Defines Persistent mixin class for persistent objects.\n" "Defines Persistent mixin class for persistent objects.\n"
"\n" "\n"
"$Id: cPersistence.c,v 1.54 2002/04/02 11:11:45 htrd Exp $\n"; "$Id: cPersistence.c,v 1.55 2002/04/02 22:17:24 bwarsaw Exp $\n";
#include "cPersistence.h" #include "cPersistence.h"
/* XXX What is this structure used for? */
struct ccobject_head_struct { struct ccobject_head_struct {
CACHE_HEAD CACHE_HEAD
}; };
...@@ -114,31 +115,42 @@ callmethod1(PyObject *self, PyObject *name, PyObject *arg) ...@@ -114,31 +115,42 @@ callmethod1(PyObject *self, PyObject *name, PyObject *arg)
return self; return self;
} }
#define UPDATE_STATE_IF_NECESSARY(self, ER) \
if(self->state < 0 && self->jar) \ static void ghostify(cPersistentObject*);
{ \
PyObject *r; \ /* Load the state of the object, unghostifying it. Upon success, return 1.
\ * If an error occurred, re-ghostify the object and return 0.
int *count = NON_GHOST_COUNT(self); \ */
if(count) \ static int
{ \ unghostify(cPersistentObject *self)
(*count)++; \ {
self->ring.next = HOME(self); \ if (self->state < 0 && self->jar) {
self->ring.prev = HOME(self)->prev; \ PyObject *r;
HOME(self)->prev->next = &self->ring; \
HOME(self)->prev = &self->ring; \ /* XXX Is it ever possibly to not have a cache? */
Py_INCREF(self); \ if (self->cache) {
} \ /* Create a node in the ring for this unghostified object. */
self->state=cPersistent_CHANGED_STATE; \ self->cache->non_ghost_count++;
UNLESS(r=callmethod1(self->jar,py_setstate,(PyObject*)self)) \ self->ring.next = &self->cache->ring_home;
{ \ self->ring.prev = (&(self)->cache->ring_home)->prev;
ghostify(self); \ HOME(self)->prev->next = &self->ring;
return ER; \ HOME(self)->prev = &self->ring;
} \ Py_INCREF(self);
self->state=cPersistent_UPTODATE_STATE; \ }
Py_DECREF(r); \ self->state = cPersistent_CHANGED_STATE;
/* Call the object's __setstate__() */
r = callmethod1(self->jar, py_setstate, (PyObject*)self);
if (r == NULL) {
ghostify(self);
return 0;
}
self->state = cPersistent_UPTODATE_STATE;
Py_DECREF(r);
}
return 1;
} }
#define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) accessed(self) #define KEEP_THIS_ONE_AROUND_FOR_A_WHILE(self) accessed(self)
/****************************************************************************/ /****************************************************************************/
...@@ -161,22 +173,31 @@ accessed(cPersistentObject *self) ...@@ -161,22 +173,31 @@ accessed(cPersistentObject *self)
static void static void
ghostify(cPersistentObject *self) ghostify(cPersistentObject *self)
{ {
int *count; /* are we already a ghost? */
count = NON_GHOST_COUNT(self); if (self->state == cPersistent_GHOST_STATE)
if(count && (self->state>=0)) return;
{ /* XXX is it ever possible to not have a cache? */
(*count)--; if (self->cache == NULL) {
self->ring.next->prev = self->ring.prev;
self->ring.prev->next = self->ring.next;
self->ring.prev = NULL;
self->ring.next = NULL;
self->state = cPersistent_GHOST_STATE;
Py_DECREF(self);
}
else
{
self->state = cPersistent_GHOST_STATE; self->state = cPersistent_GHOST_STATE;
return;
} }
/* if we're ghostifying an object, we better have some non-ghosts */
assert(self->cache->non_ghost_count > 0);
self->cache->non_ghost_count--;
self->ring.next->prev = self->ring.prev;
self->ring.prev->next = self->ring.next;
self->ring.prev = NULL;
self->ring.next = NULL;
self->state = cPersistent_GHOST_STATE;
/* We remove the reference to the just ghosted object that the ring
* holds. Note that the dictionary of oids->objects has an uncounted
* reference, so if the ring's reference was the only one, this frees
* the ghost object. Note further that the object's dealloc knows to
* inform the dictionary that it is going away.
*/
Py_DECREF(self);
} }
static void static void
...@@ -293,53 +314,59 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args) ...@@ -293,53 +314,59 @@ Per__p_deactivate(cPersistentObject *self, PyObject *args)
static int static int
Per_setstate(cPersistentObject *self) Per_setstate(cPersistentObject *self)
{ {
UPDATE_STATE_IF_NECESSARY(self, -1); if (!unghostify(self))
self->state=cPersistent_STICKY_STATE; return -1;
return 0; self->state = cPersistent_STICKY_STATE;
return 0;
} }
static PyObject * static PyObject *
Per__getstate__(cPersistentObject *self, PyObject *args) Per__getstate__(cPersistentObject *self, PyObject *args)
{ {
PyObject *__dict__, *d=0; PyObject *__dict__, *d=0;
if (!checknoargs(args)) return NULL; if (!checknoargs(args))
return NULL;
#ifdef DEBUG_LOG #ifdef DEBUG_LOG
if(idebug_log < 0) call_debug("get",self); if (idebug_log < 0)
call_debug("get",self);
#endif #endif
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
if(HasInstDict(self) && (__dict__=INSTANCE_DICT(self))) if (HasInstDict(self) && (__dict__=INSTANCE_DICT(self))) {
{ PyObject *k, *v;
PyObject *k, *v; int pos;
int pos; char *ck;
char *ck;
for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) {
{ if(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
if(PyString_Check(k) && (ck=PyString_AS_STRING(k)) && (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
(*ck=='_' && ck[1]=='v' && ck[2]=='_'))
{ {
UNLESS(d=PyDict_New()) goto err; if ((d=PyDict_New()) == NULL)
for(pos=0; PyDict_Next(__dict__, &pos, &k, &v); ) goto err;
UNLESS(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
(*ck=='_' && ck[1]=='v' && ck[2]=='_')) for (pos=0; PyDict_Next(__dict__, &pos, &k, &v); )
if(PyDict_SetItem(d,k,v) < 0) goto err; UNLESS(PyString_Check(k) && (ck=PyString_AS_STRING(k)) &&
return d; (*ck=='_' && ck[1]=='v' && ck[2]=='_'))
{
if (PyDict_SetItem(d,k,v) < 0)
goto err;
}
return d;
} }
} }
} }
else else
__dict__=Py_None; __dict__ = Py_None;
Py_INCREF(__dict__);
return __dict__;
err: Py_INCREF(__dict__);
Py_XDECREF(d); return __dict__;
return NULL; err:
Py_XDECREF(d);
return NULL;
} }
static PyObject * static PyObject *
...@@ -466,7 +493,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name, ...@@ -466,7 +493,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
case 'm': case 'm':
if(strcmp(n,"time")==0) if(strcmp(n,"time")==0)
{ {
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
accessed(self); accessed(self);
...@@ -498,7 +526,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name, ...@@ -498,7 +526,8 @@ Per_getattr(cPersistentObject *self, PyObject *oname, char *name,
(strcmp(name,"dict__")==0 || strcmp(name,"class__")==0 (strcmp(name,"dict__")==0 || strcmp(name,"class__")==0
|| strcmp(name, "of__")==0))) || strcmp(name, "of__")==0)))
{ {
UPDATE_STATE_IF_NECESSARY(self, NULL); if (!unghostify(self))
return NULL;
accessed(self); accessed(self);
} }
...@@ -614,7 +643,8 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v, ...@@ -614,7 +643,8 @@ _setattro(cPersistentObject *self, PyObject *oname, PyObject *v,
} }
else else
{ {
UPDATE_STATE_IF_NECESSARY(self, -1); if (!unghostify(self))
return -1;
accessed(self); accessed(self);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment