[ZODB-Dev] Odd output from checkbtrees.py
Paul Winkler
pw_lists at slinkp.com
Wed Aug 27 19:33:41 EDT 2003
On Wed, Aug 27, 2003 at 11:39:18AM -0400, Shane Hathaway wrote:
> DCWorkflow doesn't use BTrees. My guess is that checkbtrees is actually
> traversing a single object many times, making it a bug in checkbtrees.
Correct. And in fact, there were 2 issues to deal with:
1) obj.__dict__.items() sometimes picks things up
through acquisition, as demonstrated by the problem with DCWorkflow
transitions (and states, BTW).
2) it's possible for an object to contain a reference to itself,
e.g. a LocalFS instance has a root attribute that (sometimes?
always?) points to itself. So checkbtrees.py was infinitely
descending into spam.root.root.root.root...
Both of these were trivial to fix.
Attached is a patch against checkbtrees.py from the ZODB3 main branch.
I have check-in privileges and would be happy to check this in,
but there's no unit tests for checkbtrees.py and I'd like
some comments on whether i've broken anything.
"It works for me" - that is, it runs (on a 2 GB Data.fs), prints a whole
lot of output, and doesn't give any errors.
--
Paul Winkler
http://www.slinkp.com
Look! Up in the sky! It's WOODEN GLOVE POLE-LICKER!
(random hero from isometric.spaceninja.com)
-------------- next part --------------
*** checkbtrees.py.CVS_ORIG Wed Aug 27 18:26:00 2003
--- checkbtrees.py Wed Aug 27 17:14:12 2003
***************
*** 17,37 ****
L.append((obj, path))
def get_subobjects(obj):
getattr(obj, '_', None) # unghostify
sub = []
try:
attrs = obj.__dict__.items()
except AttributeError:
attrs = ()
! for pair in attrs:
! sub.append(pair)
!
# what if it is a mapping?
try:
items = obj.items()
except AttributeError:
items = ()
for k, v in items:
if not isinstance(k, IntType):
sub.append(("<key>", k))
if not isinstance(v, IntType):
--- 17,50 ----
L.append((obj, path))
def get_subobjects(obj):
+ ''' Get all subobjects, but carefully - don't
+ go into an infinite loop!'''
+
getattr(obj, '_', None) # unghostify
sub = []
+ # don't accidentally wander into obj's siblings
+ try:
+ obj = obj.aq_base
+ except AttributeError:
+ pass
+
try:
attrs = obj.__dict__.items()
except AttributeError:
attrs = ()
! # don't loop if object contains reference to itself
! sub.extend([pair for pair in attrs if not (pair[1] is obj)])
!
# what if it is a mapping?
try:
items = obj.items()
except AttributeError:
items = ()
for k, v in items:
+ # don't loop if object contains reference to itself
+ if v is obj:
+ continue
+ # ok, v is not a self reference.
if not isinstance(k, IntType):
sub.append(("<key>", k))
if not isinstance(v, IntType):
More information about the ZODB-Dev
mailing list