The response.authority section is a list of RRsets constructed from the RRs that were in the authority section of the DNS message. So you saw one RRset, and that RRset had 3 Rdatas in it. This is as intended. See RFC 2181 for the definition of RRset. I agree the dnspython documentation in this area could be better!
Let's look at an example that's a reply from one of
dnspython.org's nameservers, first with "dig":
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64458
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;; ANSWER SECTION:
;; AUTHORITY SECTION:
The authority section has 4 NS RRs associated with the owner name
dnspython.org. Dnspython's message code constructs RRsets out of individual RRs as RRsets are the unit that is cached. Now lets look at this with dnspython:
>>> import dns.query
>>> import dns.message
>>> r = dns.query.udp(q, '205.251.196.229')
>>> len(r.authority) # there is one RRset in the authority section
1
>>> r.authority[0] # you can see it's an RRset here
>>> len(r.authority[0]) # that RRset has 4 Rdatas
4
>>> r.authority[0][0] # Here's the first one, so you can see it's an NS rdata object
>>> for rd in r.authority[0]: # We can print all of them
... print(rd)
...