###--------------------------------------------------------------------------
### A bulk DNS resolver.
+class ResolverFailure (Exception):
+ def __init__(me, host, msg):
+ me.host = host
+ me.msg = msg
+ def __str__(me):
+ return "failed to resolve `%s': %s" % (me.host, me.msg)
+
class BulkResolver (object):
"""
Resolve a number of DNS names in parallel.
"""
addr = me._namemap[host]
if addr is None:
- raise KeyError(host)
+ raise ResolverFailure(host, '(unknown failure)')
return addr
def _resolved(me, host, addr):
## Special handling for the `name' key.
if key == 'name':
value = me._itemmap.get('name', me.name)
+ elif key == '@inherits':
+ try: return me._itemmap['@inherits']
+ except KeyError: raise MissingKeyException(me.name, key)
else:
value, _ = me._get(key)
if value is None:
"""
## Initialize for a depth-first walk of the inheritance graph.
- d = {}
- visited = {}
+ seen = { 'name': True }
+ visiting = { me.name: True }
stack = [me]
## Visit nodes, collecting their keys. Don't believe the values:
## resolving inheritance is too hard to do like this.
while stack:
sec = stack.pop()
- if sec.name in visited: continue
- visited[sec.name] = True
- stack += sec._parents()
+ for p in sec._parents():
+ if p.name not in visiting:
+ stack.append(p); visiting[p.name] = True
- for key in sec._itemmap.iterkeys():
- if key != '@inherit': d[key] = None
+ for key in sec._itemmap.iterkeys(): seen[key] = None
## And we're done.
- return d.iterkeys()
+ return seen.iterkeys()
class MyConfigParser (object):
"""