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:
parent
85940fd537
commit
0c1913336a
2 changed files with 23 additions and 5 deletions
|
@ -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' % \
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in a new issue