DNS stub resolver answer. Instances of this class bundle up the result of a successful DNS resolution. For convenience, the answer object implements much of the sequence protocol, forwarding to its ``rrset`` attribute. E.g. ``for a in answer`` is equivalent to ``for a in answe
| 245 | |
| 246 | |
| 247 | class Answer: |
| 248 | """DNS stub resolver answer. |
| 249 | |
| 250 | Instances of this class bundle up the result of a successful DNS |
| 251 | resolution. |
| 252 | |
| 253 | For convenience, the answer object implements much of the sequence |
| 254 | protocol, forwarding to its ``rrset`` attribute. E.g. |
| 255 | ``for a in answer`` is equivalent to ``for a in answer.rrset``. |
| 256 | ``answer[i]`` is equivalent to ``answer.rrset[i]``, and |
| 257 | ``answer[i:j]`` is equivalent to ``answer.rrset[i:j]``. |
| 258 | |
| 259 | Note that CNAMEs or DNAMEs in the response may mean that answer |
| 260 | RRset's name might not be the query name. |
| 261 | """ |
| 262 | |
| 263 | def __init__( |
| 264 | self, |
| 265 | qname: dns.name.Name, |
| 266 | rdtype: dns.rdatatype.RdataType, |
| 267 | rdclass: dns.rdataclass.RdataClass, |
| 268 | response: dns.message.QueryMessage, |
| 269 | nameserver: str | None = None, |
| 270 | port: int | None = None, |
| 271 | ) -> None: |
| 272 | self.qname = qname |
| 273 | self.rdtype = rdtype |
| 274 | self.rdclass = rdclass |
| 275 | self.response = response |
| 276 | self.nameserver = nameserver |
| 277 | self.port = port |
| 278 | self.chaining_result = response.resolve_chaining() |
| 279 | # Copy some attributes out of chaining_result for backwards |
| 280 | # compatibility and convenience. |
| 281 | self.canonical_name = self.chaining_result.canonical_name |
| 282 | self.rrset = self.chaining_result.answer |
| 283 | self.expiration = time.time() + self.chaining_result.minimum_ttl |
| 284 | |
| 285 | def __getattr__(self, attr): # pragma: no cover |
| 286 | if self.rrset is not None: |
| 287 | if attr == "name": |
| 288 | return self.rrset.name |
| 289 | elif attr == "ttl": |
| 290 | return self.rrset.ttl |
| 291 | elif attr == "covers": |
| 292 | return self.rrset.covers |
| 293 | elif attr == "rdclass": |
| 294 | return self.rrset.rdclass |
| 295 | elif attr == "rdtype": |
| 296 | return self.rrset.rdtype |
| 297 | else: |
| 298 | raise AttributeError(attr) |
| 299 | |
| 300 | def __len__(self) -> int: |
| 301 | return self.rrset is not None and len(self.rrset) or 0 |
| 302 | |
| 303 | def __iter__(self) -> Iterator[Any]: |
| 304 | return self.rrset is not None and iter(self.rrset) or iter(tuple()) |
no outgoing calls
no test coverage detected
searching dependent graphs…