+ ## If we've been this way before on another pass through then return
+ ## the value we found then. If we're still thinking about it then
+ ## we've found a cycle.
+ try:
+ threadp, value = map[sec]
+ except KeyError:
+ pass
+ else:
+ if threadp:
+ raise InheritanceCycleError(key, path[:])
+
+ ## See whether the answer is ready waiting for us.
+ try:
+ v = CP.RawConfigParser.get(me, sec, key)
+ except CP.NoOptionError:
+ pass
+ else:
+ return v, path[:]
+
+ ## No, apparently, not. Find out our list of parents.
+ try:
+ parents = CP.RawConfigParser.get(me, sec, '@inherit').\
+ replace(',', ' ').split()
+ except CP.NoOptionError:
+ parents = []
+
+ ## Initially we have no idea.
+ value = None
+ winner = None
+
+ ## Go through our parents and ask them what they think.
+ map[sec] = True, None
+ for p in parents:
+
+ ## See whether we get an answer. If not, keep on going.
+ v, pp = me._get(p, key, map, path)
+ if v is None: continue
+
+ ## If we got an answer, check that it matches any previous ones.
+ if value is None:
+ value = v
+ winner = pp
+ elif value != v:
+ raise AmbiguousOptionError(key, winner, value, pp, v)
+
+ ## That's the best we could manage.
+ map[sec] = False, value
+ return value, winner
+
+ finally:
+ ## Remove us from the path again.