[ZODB-Dev] How do you "wake up" sleepy persistent objects?
Patrick K. O'Brien
pobrien@orbtech.com
Thu, 11 Oct 2001 17:53:07 -0500
Here is my situation. I'm working on a sample app that uses ZODB, but not
Zope. The interface to the application is, at this point, simply the Python
shell. Specifically, the Python shell that I created in wxPython/Scintilla,
called PyCrust (http://sourceforge.net/projects/pycrust/). PyCrust provides
call tips for methods and an auto-completion popup list whenever you type an
object name followed by a dot. I noticed that ghosted objects did not
display all of their attributes in the autocompletion list the first time
you typed a dot, but they would the second time (because we just woke them
up). Since I wanted to see the proper autocompletion list the first time
around, I changed the method that generates the popup list to the following:
def getAllAttributeNames(object):
"""Return list of all attributes, including inherited, for an object.
Recursively walk through a class and all base classes.
"""
attributes = []
# Wake up sleepy objects - a hack for ZODB objects in "ghost" state.
wakeupcall = dir(object)
del wakeupcall
# Get attributes available through the normal convention.
attributes += dir(object)
# For a class instance, get the attributes for the class.
if hasattr(object, '__class__'):
# Break a circular reference. This happens with extension classes.
if object.__class__ is object:
pass
else:
attributes += getAllAttributeNames(object.__class__)
# Also get attributes from any and all parent classes.
if hasattr(object, '__bases__'):
for base in object.__bases__:
attributes += getAllAttributeNames(base)
return attributes
This does what I want. Do you consider this case of waking up ghosts to be
acceptable? Or do you have a suggestion for a better way to handle this
situation?
Thanks for all the help.
P.S. Yes, this method can return a list with duplicated attribute names, but
its caller dedups the list. See below.
def getAttributeNames(object, includeMagic=1, includeSingle=1,
includeDouble=1):
"""Return list of unique attributes, including inherited, for an
object."""
attributes = []
dict = {}
if includeMagic:
try: attributes += object._getAttributeNames()
except: pass
# Get all attribute names, removing duplicates from the attribute list.
for item in getAllAttributeNames(object):
dict[item] = None
attributes += dict.keys()
attributes.sort()
if not includeSingle:
attributes = filter(lambda item: item[0]!='_' or item[1]=='_',
attributes)
if not includeDouble:
attributes = filter(lambda item: item[:2]!='__', attributes)
return attributes
---
Patrick K. O'Brien
Orbtech (http://www.orbtech.com)
"I am, therefore I think."
-----Original Message-----
From: zodb-dev-admin@zope.org [mailto:zodb-dev-admin@zope.org]On Behalf Of
Jim Fulton
Sent: Thursday, October 11, 2001 5:38 PM
To: Chris McDonough
Cc: pobrien@orbtech.com; ZODB
Subject: Re: [ZODB-Dev] How do you "wake up" sleepy persistent objects?
Let me try to summarize.
First, you usually don't need to wake up ghosts. Why would
anyone want to wake up a ghost? I can see doing it
during debugging, but not otherwise.
In general, messing with an objects __dict__ is impolite. :)
You really shouldn't count on getting anything from a __dict__.
The only time to mess with a __dict__ is when you actually want
to defeat the normal persistence machinery. We recently used this
hack^H^H^H^Htechnique in a DTML optimization.
In Python 2.2, __dict__ will be a far less important than
it is now in standard Python. It will be much more bad form to
access a __dict__ than it is in Python now.
I imagine that dir does some attribute access that causes
persistent objects to be activated.
I don't realloy consider the fact that you can't count on __dict__
to be a gitcha in ZODB. It is a little unfortunate that dir doesn't
always do the right thing.
Jim