Level 1 Direct lookups
Build a small DNS resolver on top of a record store.
records is a dict-like object mapping a name to a list of records, each a tuple (rtype, value, ttl), for example:
records = {
"example.com": [("A", "93.184.216.34", 300), ("MX", "10 mail.example.com", 60)],
"mail.example.com": [("A", "10.0.0.5", 300)],
}
Keys are already normalized (lowercase, no trailing dot). Read the store only with records.get(name), which returns the list or None. Tests use custom stores that count or delay these calls.
Implement Resolver(records, clock=time.monotonic) (the clock matters from level 4) with:
resolve(name, rtype="A") -> list[str]: the values of all records of typertypeatname, in stored order.- Normalize the queried name first: compare case-insensitively (lowercase it) and drop one trailing dot, so
"Example.COM."means"example.com". - Raise
NotFoundErrorif the name has no records, or none of typertype.
The starter defines the exception classes; keep them. NotFoundError, CycleError and UpstreamError all subclass DNSError.
r = Resolver(records)
r.resolve("EXAMPLE.com.") # ["93.184.216.34"]
r.resolve("example.com", "MX") # ["10 mail.example.com"]
r.resolve("example.com", "AAAA") # raises NotFoundError