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
|
found_obj = None
|
||||||
for child in self._children.itervalues():
|
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:
|
if found_obj != None and child != found_obj:
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
'parent.any matched more than one: %s %s' % \
|
'parent.any matched more than one: %s %s' % \
|
||||||
|
|
|
@ -82,12 +82,19 @@ class BaseProxy(object):
|
||||||
result, done = self.find(obj)
|
result, done = self.find(obj)
|
||||||
|
|
||||||
if self._search_up:
|
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:
|
while not done:
|
||||||
obj = obj._parent
|
obj = obj._parent
|
||||||
if not obj:
|
if not obj:
|
||||||
break
|
break
|
||||||
result, done = self.find(obj)
|
result, done = self.find(obj)
|
||||||
|
|
||||||
|
self._visited = False
|
||||||
|
base._visited = False
|
||||||
|
|
||||||
if not done:
|
if not done:
|
||||||
raise AttributeError, \
|
raise AttributeError, \
|
||||||
"Can't resolve proxy '%s' of type '%s' from '%s'" % \
|
"Can't resolve proxy '%s' of type '%s' from '%s'" % \
|
||||||
|
@ -151,10 +158,17 @@ class AttrProxy(BaseProxy):
|
||||||
def find(self, obj):
|
def find(self, obj):
|
||||||
try:
|
try:
|
||||||
val = getattr(obj, self._attr)
|
val = getattr(obj, self._attr)
|
||||||
# for any additional unproxying to be done, pass the
|
visited = False
|
||||||
# current, rather than the original object so that proxy
|
if hasattr(val, '_visited'):
|
||||||
# has the right context
|
visited = getattr(val, '_visited')
|
||||||
obj = val
|
|
||||||
|
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:
|
except:
|
||||||
return None, False
|
return None, False
|
||||||
while isproxy(val):
|
while isproxy(val):
|
||||||
|
|
Loading…
Reference in a new issue