config: Avoid generating a reference to myself for Parent.any

The unproxy code for Parent.any can generate a circular reference
in certain situations with classes hierarchies like those in ClockDomain.py.
This patch solves this by marking ouself as visited to make sure the
search does not resolve to a self-reference.
This commit is contained in:
Geoffrey Blake 2014-05-09 18:58:47 -04:00
parent 85940fd537
commit 0c1913336a
2 changed files with 23 additions and 5 deletions

View file

@ -861,7 +861,11 @@ class SimObject(object):
found_obj = None
for child in self._children.itervalues():
if isinstance(child, ptype):
visited = False
if hasattr(child, '_visited'):
visited = getattr(child, '_visited')
if isinstance(child, ptype) and not visited:
if found_obj != None and child != found_obj:
raise AttributeError, \
'parent.any matched more than one: %s %s' % \

View file

@ -82,12 +82,19 @@ class BaseProxy(object):
result, done = self.find(obj)
if self._search_up:
# Search up the tree but mark ourself
# as visited to avoid a self-reference
self._visited = True
obj._visited = True
while not done:
obj = obj._parent
if not obj:
break
result, done = self.find(obj)
self._visited = False
base._visited = False
if not done:
raise AttributeError, \
"Can't resolve proxy '%s' of type '%s' from '%s'" % \
@ -151,10 +158,17 @@ class AttrProxy(BaseProxy):
def find(self, obj):
try:
val = getattr(obj, self._attr)
# for any additional unproxying to be done, pass the
# current, rather than the original object so that proxy
# has the right context
obj = val
visited = False
if hasattr(val, '_visited'):
visited = getattr(val, '_visited')
if not visited:
# for any additional unproxying to be done, pass the
# current, rather than the original object so that proxy
# has the right context
obj = val
else:
return None, False
except:
return None, False
while isproxy(val):