dnspython 2.8.0__tar.gz → 2.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. {dnspython-2.8.0 → dnspython-2.9.0}/PKG-INFO +37 -39
  2. {dnspython-2.8.0 → dnspython-2.9.0}/README.md +5 -5
  3. {dnspython-2.8.0 → dnspython-2.9.0}/dns/__init__.py +3 -1
  4. {dnspython-2.8.0 → dnspython-2.9.0}/dns/_asyncio_backend.py +30 -41
  5. {dnspython-2.8.0 → dnspython-2.9.0}/dns/_ddr.py +32 -18
  6. {dnspython-2.8.0 → dnspython-2.9.0}/dns/_features.py +8 -9
  7. dnspython-2.9.0/dns/_file_util.py +21 -0
  8. {dnspython-2.8.0 → dnspython-2.9.0}/dns/_immutable_ctx.py +1 -1
  9. {dnspython-2.8.0 → dnspython-2.9.0}/dns/_no_ssl.py +3 -3
  10. dnspython-2.9.0/dns/_render_util.py +21 -0
  11. dnspython-2.9.0/dns/_text_util.py +45 -0
  12. dnspython-2.9.0/dns/_tls_util.py +21 -0
  13. {dnspython-2.8.0 → dnspython-2.9.0}/dns/_trio_backend.py +10 -10
  14. {dnspython-2.8.0 → dnspython-2.9.0}/dns/asyncbackend.py +5 -7
  15. {dnspython-2.8.0 → dnspython-2.9.0}/dns/asyncquery.py +122 -107
  16. {dnspython-2.8.0 → dnspython-2.9.0}/dns/asyncresolver.py +76 -41
  17. {dnspython-2.8.0 → dnspython-2.9.0}/dns/btree.py +23 -21
  18. {dnspython-2.8.0 → dnspython-2.9.0}/dns/btreezone.py +210 -25
  19. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssec.py +249 -308
  20. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssecalgs/__init__.py +23 -25
  21. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssecalgs/base.py +2 -2
  22. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssecalgs/cryptography.py +2 -2
  23. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssecalgs/dsa.py +6 -4
  24. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssecalgs/ecdsa.py +6 -4
  25. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssecalgs/eddsa.py +1 -3
  26. dnspython-2.9.0/dns/dnssecalgs/mldsa.py +58 -0
  27. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssecalgs/rsa.py +7 -1
  28. {dnspython-2.8.0 → dnspython-2.9.0}/dns/dnssectypes.py +1 -0
  29. {dnspython-2.8.0 → dnspython-2.9.0}/dns/e164.py +25 -25
  30. {dnspython-2.8.0 → dnspython-2.9.0}/dns/edns.py +223 -52
  31. {dnspython-2.8.0 → dnspython-2.9.0}/dns/enum.py +15 -15
  32. {dnspython-2.8.0 → dnspython-2.9.0}/dns/exception.py +1 -4
  33. {dnspython-2.8.0 → dnspython-2.9.0}/dns/flags.py +37 -7
  34. {dnspython-2.8.0 → dnspython-2.9.0}/dns/grange.py +6 -7
  35. {dnspython-2.8.0 → dnspython-2.9.0}/dns/immutable.py +1 -1
  36. {dnspython-2.8.0 → dnspython-2.9.0}/dns/inet.py +31 -38
  37. {dnspython-2.8.0 → dnspython-2.9.0}/dns/ipv4.py +9 -9
  38. {dnspython-2.8.0 → dnspython-2.9.0}/dns/ipv6.py +17 -18
  39. {dnspython-2.8.0 → dnspython-2.9.0}/dns/message.py +369 -440
  40. {dnspython-2.8.0 → dnspython-2.9.0}/dns/name.py +295 -228
  41. {dnspython-2.8.0 → dnspython-2.9.0}/dns/namedict.py +4 -4
  42. {dnspython-2.8.0 → dnspython-2.9.0}/dns/nameserver.py +12 -11
  43. {dnspython-2.8.0 → dnspython-2.9.0}/dns/node.py +79 -54
  44. {dnspython-2.8.0 → dnspython-2.9.0}/dns/opcode.py +18 -22
  45. {dnspython-2.8.0 → dnspython-2.9.0}/dns/query.py +470 -508
  46. {dnspython-2.8.0 → dnspython-2.9.0}/dns/quic/__init__.py +7 -7
  47. {dnspython-2.8.0 → dnspython-2.9.0}/dns/quic/_asyncio.py +5 -8
  48. {dnspython-2.8.0 → dnspython-2.9.0}/dns/quic/_common.py +6 -6
  49. {dnspython-2.8.0 → dnspython-2.9.0}/dns/quic/_sync.py +5 -8
  50. {dnspython-2.8.0 → dnspython-2.9.0}/dns/quic/_trio.py +4 -7
  51. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rcode.py +21 -27
  52. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdata.py +223 -94
  53. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdataclass.py +7 -9
  54. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdataset.py +235 -95
  55. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdatatype.py +27 -25
  56. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/AFSDB.py +3 -2
  57. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/AMTRELAY.py +11 -10
  58. dnspython-2.9.0/dns/rdtypes/ANY/BRID.py +13 -0
  59. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/CAA.py +8 -8
  60. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/CERT.py +9 -9
  61. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/CSYNC.py +4 -4
  62. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/DSYNC.py +8 -7
  63. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/GPOS.py +7 -7
  64. dnspython-2.9.0/dns/rdtypes/ANY/HHIT.py +13 -0
  65. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/HINFO.py +5 -5
  66. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/HIP.py +13 -9
  67. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/ISDN.py +6 -6
  68. dnspython-2.9.0/dns/rdtypes/ANY/KEY.py +116 -0
  69. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/L32.py +3 -3
  70. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/L64.py +5 -4
  71. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/LOC.py +25 -18
  72. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/LP.py +6 -6
  73. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/NID.py +2 -2
  74. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/NSEC.py +2 -3
  75. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/NSEC3.py +6 -14
  76. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/NSEC3PARAM.py +3 -2
  77. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/OPENPGPKEY.py +4 -2
  78. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/OPT.py +9 -8
  79. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/RP.py +4 -4
  80. dnspython-2.9.0/dns/rdtypes/ANY/RRSIG.py +33 -0
  81. dnspython-2.9.0/dns/rdtypes/ANY/SIG.py +33 -0
  82. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/SOA.py +12 -12
  83. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/SSHFP.py +2 -6
  84. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/TKEY.py +6 -4
  85. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/TSIG.py +21 -20
  86. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/URI.py +5 -7
  87. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/X25.py +2 -2
  88. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/ZONEMD.py +7 -6
  89. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/CH/A.py +2 -2
  90. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/A.py +1 -1
  91. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/AAAA.py +1 -1
  92. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/APL.py +19 -6
  93. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/DHCID.py +2 -2
  94. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/IPSECKEY.py +3 -3
  95. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/NAPTR.py +7 -7
  96. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/NSAP.py +2 -1
  97. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/PX.py +3 -3
  98. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/SRV.py +4 -4
  99. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/WKS.py +4 -3
  100. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/__init__.py +1 -0
  101. dnspython-2.9.0/dns/rdtypes/base64base.py +53 -0
  102. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/dnskeybase.py +44 -10
  103. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/dsbase.py +14 -9
  104. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/euibase.py +15 -5
  105. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/mxbase.py +16 -8
  106. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/nsbase.py +16 -7
  107. dnspython-2.8.0/dns/rdtypes/ANY/RRSIG.py → dnspython-2.9.0/dns/rdtypes/rrsigbase.py +40 -24
  108. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/svcbbase.py +124 -36
  109. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/tlsabase.py +18 -13
  110. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/txtbase.py +24 -17
  111. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/util.py +25 -10
  112. {dnspython-2.8.0 → dnspython-2.9.0}/dns/renderer.py +30 -27
  113. {dnspython-2.8.0 → dnspython-2.9.0}/dns/resolver.py +233 -253
  114. {dnspython-2.8.0 → dnspython-2.9.0}/dns/reversename.py +24 -27
  115. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rrset.py +63 -44
  116. {dnspython-2.8.0 → dnspython-2.9.0}/dns/serial.py +3 -0
  117. {dnspython-2.8.0 → dnspython-2.9.0}/dns/set.py +5 -5
  118. dnspython-2.9.0/dns/style.py +28 -0
  119. {dnspython-2.8.0 → dnspython-2.9.0}/dns/tokenizer.py +165 -54
  120. {dnspython-2.8.0 → dnspython-2.9.0}/dns/transaction.py +125 -68
  121. {dnspython-2.8.0 → dnspython-2.9.0}/dns/tsig.py +3 -2
  122. {dnspython-2.8.0 → dnspython-2.9.0}/dns/tsigkeyring.py +42 -6
  123. {dnspython-2.8.0 → dnspython-2.9.0}/dns/ttl.py +7 -7
  124. {dnspython-2.8.0 → dnspython-2.9.0}/dns/update.py +13 -13
  125. {dnspython-2.8.0 → dnspython-2.9.0}/dns/version.py +1 -1
  126. {dnspython-2.8.0 → dnspython-2.9.0}/dns/versioned.py +36 -23
  127. {dnspython-2.8.0 → dnspython-2.9.0}/dns/win32util.py +3 -5
  128. dnspython-2.9.0/dns/wire.py +13 -0
  129. dnspython-2.8.0/dns/wire.py → dnspython-2.9.0/dns/wirebase.py +11 -16
  130. {dnspython-2.8.0 → dnspython-2.9.0}/dns/xfr.py +59 -22
  131. {dnspython-2.8.0 → dnspython-2.9.0}/dns/zone.py +519 -448
  132. {dnspython-2.8.0 → dnspython-2.9.0}/dns/zonefile.py +124 -85
  133. dnspython-2.8.0/examples/ddns.py → dnspython-2.9.0/examples/ddns_client.py +3 -4
  134. dnspython-2.9.0/examples/ddns_server.py +124 -0
  135. {dnspython-2.8.0 → dnspython-2.9.0}/examples/doh-json.py +2 -2
  136. {dnspython-2.8.0 → dnspython-2.9.0}/examples/doh.py +2 -2
  137. {dnspython-2.8.0 → dnspython-2.9.0}/examples/receive_notify.py +1 -1
  138. {dnspython-2.8.0 → dnspython-2.9.0}/examples/reverse.py +1 -1
  139. {dnspython-2.8.0 → dnspython-2.9.0}/examples/send_notify.py +1 -0
  140. dnspython-2.9.0/examples/server.py +712 -0
  141. dnspython-2.9.0/pyproject.toml +124 -0
  142. dnspython-2.8.0/pyproject.toml → dnspython-2.9.0/pyproject.toml.orig +51 -62
  143. {dnspython-2.8.0 → dnspython-2.9.0}/tests/doq.py +6 -6
  144. {dnspython-2.8.0 → dnspython-2.9.0}/tests/example +46 -2
  145. {dnspython-2.8.0 → dnspython-2.9.0}/tests/example1.good +4 -2
  146. {dnspython-2.8.0 → dnspython-2.9.0}/tests/example2.good +4 -2
  147. {dnspython-2.8.0 → dnspython-2.9.0}/tests/example3.good +4 -2
  148. {dnspython-2.8.0 → dnspython-2.9.0}/tests/example4.good +4 -2
  149. {dnspython-2.8.0 → dnspython-2.9.0}/tests/nanonameserver.py +2 -2
  150. dnspython-2.9.0/tests/resolv.conf +7 -0
  151. {dnspython-2.8.0 → dnspython-2.9.0}/tests/svcb_test_vectors.generic +2 -2
  152. {dnspython-2.8.0 → dnspython-2.9.0}/tests/svcb_test_vectors.text +2 -2
  153. dnspython-2.9.0/tests/test_ascii_digits.py +155 -0
  154. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_async.py +35 -10
  155. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_bugs.py +37 -0
  156. dnspython-2.9.0/tests/test_ddr.py +95 -0
  157. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_dnssec.py +214 -12
  158. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_dnssecalgs.py +48 -1
  159. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_doh.py +7 -7
  160. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_edns.py +117 -0
  161. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_flags.py +18 -1
  162. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_generate.py +33 -1
  163. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_message.py +64 -72
  164. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_name.py +69 -73
  165. dnspython-2.9.0/tests/test_nsec3.py +100 -0
  166. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_query.py +41 -17
  167. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rdata.py +102 -1
  168. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rdataset.py +3 -1
  169. dnspython-2.9.0/tests/test_rdtypeanykey.py +44 -0
  170. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_resolution.py +77 -77
  171. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_resolver.py +64 -15
  172. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_resolver_override.py +1 -1
  173. dnspython-2.9.0/tests/test_reversename.py +54 -0
  174. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rrset.py +12 -2
  175. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rrset_reader.py +20 -0
  176. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_serial.py +11 -0
  177. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_svcb.py +229 -8
  178. dnspython-2.9.0/tests/test_tls_util.py +46 -0
  179. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_tokenizer.py +41 -0
  180. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_tsig.py +92 -4
  181. dnspython-2.9.0/tests/test_tsigkeyring.py +127 -0
  182. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_ttl.py +9 -0
  183. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_wire.py +15 -0
  184. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_xfr.py +252 -7
  185. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_zone.py +487 -7
  186. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_zonedigest.py +68 -17
  187. dnspython-2.9.0/tests/tsigkeys/1.key +1 -0
  188. dnspython-2.9.0/tests/tsigkeys/2.key +1 -0
  189. dnspython-2.9.0/tests/tsigkeys/3.key +3 -0
  190. dnspython-2.9.0/tests/tsigkeys/4.key +4 -0
  191. dnspython-2.9.0/tests/tsigkeys/5.key +1 -0
  192. dnspython-2.9.0/tests/ttl_include.text +6 -0
  193. dnspython-2.9.0/util/make-test-project +20 -0
  194. dnspython-2.9.0/util/update-version +52 -0
  195. dnspython-2.9.0/util/uv-dev-setup +3 -0
  196. dnspython-2.8.0/.gitignore +0 -20
  197. dnspython-2.8.0/LICENSE +0 -35
  198. dnspython-2.8.0/dns/_tls_util.py +0 -19
  199. dnspython-2.8.0/tests/test_ddr.py +0 -43
  200. dnspython-2.8.0/tests/test_nsec3.py +0 -55
  201. dnspython-2.8.0/tests/test_tsigkeyring.py +0 -58
  202. {dnspython-2.8.0 → dnspython-2.9.0}/dns/_asyncbackend.py +0 -0
  203. {dnspython-2.8.0 → dnspython-2.9.0}/dns/entropy.py +0 -0
  204. {dnspython-2.8.0 → dnspython-2.9.0}/dns/py.typed +0 -0
  205. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/AVC.py +0 -0
  206. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/CDNSKEY.py +0 -0
  207. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/CDS.py +0 -0
  208. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/CNAME.py +0 -0
  209. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/DLV.py +0 -0
  210. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/DNAME.py +0 -0
  211. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/DNSKEY.py +0 -0
  212. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/DS.py +0 -0
  213. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/EUI48.py +0 -0
  214. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/EUI64.py +0 -0
  215. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/MX.py +0 -0
  216. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/NINFO.py +0 -0
  217. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/NS.py +0 -0
  218. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/PTR.py +0 -0
  219. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/RESINFO.py +0 -0
  220. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/RT.py +0 -0
  221. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/SMIMEA.py +0 -0
  222. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/SPF.py +0 -0
  223. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/TLSA.py +0 -0
  224. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/TXT.py +0 -0
  225. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/WALLET.py +0 -0
  226. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/ANY/__init__.py +0 -0
  227. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/CH/__init__.py +0 -0
  228. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/HTTPS.py +0 -0
  229. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/KX.py +0 -0
  230. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/NSAP_PTR.py +0 -0
  231. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/SVCB.py +0 -0
  232. {dnspython-2.8.0 → dnspython-2.9.0}/dns/rdtypes/IN/__init__.py +0 -0
  233. {dnspython-2.8.0 → dnspython-2.9.0}/dns/zonetypes.py +0 -0
  234. {dnspython-2.8.0 → dnspython-2.9.0}/examples/async_dns.py +0 -0
  235. {dnspython-2.8.0 → dnspython-2.9.0}/examples/ddr.py +0 -0
  236. {dnspython-2.8.0 → dnspython-2.9.0}/examples/doq.py +0 -0
  237. {dnspython-2.8.0 → dnspython-2.9.0}/examples/dot.py +0 -0
  238. {dnspython-2.8.0 → dnspython-2.9.0}/examples/e164.py +0 -0
  239. {dnspython-2.8.0 → dnspython-2.9.0}/examples/ecs.py +0 -0
  240. {dnspython-2.8.0 → dnspython-2.9.0}/examples/edns.py +0 -0
  241. {dnspython-2.8.0 → dnspython-2.9.0}/examples/edns_resolver.py +0 -0
  242. {dnspython-2.8.0 → dnspython-2.9.0}/examples/mx-typed.py +0 -0
  243. {dnspython-2.8.0 → dnspython-2.9.0}/examples/mx.py +0 -0
  244. {dnspython-2.8.0 → dnspython-2.9.0}/examples/name.py +0 -0
  245. {dnspython-2.8.0 → dnspython-2.9.0}/examples/query_specific.py +0 -0
  246. {dnspython-2.8.0 → dnspython-2.9.0}/examples/reverse_name.py +0 -0
  247. {dnspython-2.8.0 → dnspython-2.9.0}/examples/tsig.py +0 -0
  248. {dnspython-2.8.0 → dnspython-2.9.0}/examples/wire_read_tcp.py +0 -0
  249. {dnspython-2.8.0 → dnspython-2.9.0}/examples/xfr.py +0 -0
  250. {dnspython-2.8.0 → dnspython-2.9.0}/examples/zonediff.py +0 -0
  251. {dnspython-2.8.0 → dnspython-2.9.0}/tests/__init__.py +0 -0
  252. {dnspython-2.8.0 → dnspython-2.9.0}/tests/doh.py +0 -0
  253. {dnspython-2.8.0 → dnspython-2.9.0}/tests/keys.py +0 -0
  254. {dnspython-2.8.0 → dnspython-2.9.0}/tests/md_module.py +0 -0
  255. {dnspython-2.8.0 → dnspython-2.9.0}/tests/mx-2-0.pickle +0 -0
  256. {dnspython-2.8.0 → dnspython-2.9.0}/tests/query +0 -0
  257. {dnspython-2.8.0 → dnspython-2.9.0}/tests/stxt_module.py +0 -0
  258. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_address.py +0 -0
  259. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_btree.py +0 -0
  260. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_btreezone.py +0 -0
  261. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_constants.py +0 -0
  262. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_doq.py +0 -0
  263. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_entropy.py +0 -0
  264. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_exceptions.py +0 -0
  265. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_features.py +0 -0
  266. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_grange.py +0 -0
  267. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_immutable.py +0 -0
  268. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_namedict.py +0 -0
  269. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_nsec3_hash.py +0 -0
  270. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_ntoaaton.py +0 -0
  271. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_processing_order.py +0 -0
  272. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rdtypeandclass.py +0 -0
  273. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rdtypeanydnskey.py +0 -0
  274. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rdtypeanyeui.py +0 -0
  275. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rdtypeanyloc.py +0 -0
  276. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_rdtypeanytkey.py +0 -0
  277. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_renderer.py +0 -0
  278. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_set.py +0 -0
  279. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_transaction.py +0 -0
  280. {dnspython-2.8.0 → dnspython-2.9.0}/tests/test_update.py +0 -0
  281. {dnspython-2.8.0 → dnspython-2.9.0}/tests/tls/ca.crt +0 -0
  282. {dnspython-2.8.0 → dnspython-2.9.0}/tests/tls/private.pem +0 -0
  283. {dnspython-2.8.0 → dnspython-2.9.0}/tests/tls/public.crt +0 -0
  284. {dnspython-2.8.0 → dnspython-2.9.0}/tests/ttxt_module.py +0 -0
  285. {dnspython-2.8.0 → dnspython-2.9.0}/tests/utest.py +0 -0
  286. {dnspython-2.8.0 → dnspython-2.9.0}/tests/util.py +0 -0
  287. {dnspython-2.8.0 → dnspython-2.9.0}/util/constants-tool +0 -0
  288. {dnspython-2.8.0 → dnspython-2.9.0}/util/generate-features +0 -0
  289. {dnspython-2.8.0 → dnspython-2.9.0}/util/generate-mx-pickle.py +0 -0
  290. {dnspython-2.8.0 → dnspython-2.9.0}/util/generate-rdatatype-doc.py +0 -0
@@ -1,57 +1,55 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dnspython
3
- Version: 2.8.0
3
+ Version: 2.9.0
4
4
  Summary: DNS toolkit
5
- Project-URL: homepage, https://www.dnspython.org
6
- Project-URL: repository, https://github.com/rthalley/dnspython.git
7
- Project-URL: documentation, https://dnspython.readthedocs.io/en/stable/
8
- Project-URL: issues, https://github.com/rthalley/dnspython/issues
5
+ Author: Bob Halley
9
6
  Author-email: Bob Halley <halley@dnspython.org>
10
- License: ISC
11
- License-File: LICENSE
7
+ License-Expression: ISC
12
8
  Classifier: Development Status :: 5 - Production/Stable
13
9
  Classifier: Intended Audience :: Developers
14
10
  Classifier: Intended Audience :: System Administrators
15
- Classifier: License :: OSI Approved :: ISC License (ISCL)
16
- Classifier: Operating System :: Microsoft :: Windows
17
11
  Classifier: Operating System :: POSIX
12
+ Classifier: Operating System :: Microsoft :: Windows
18
13
  Classifier: Programming Language :: Python
14
+ Classifier: Topic :: Internet :: Name Service (DNS)
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
16
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.10
21
17
  Classifier: Programming Language :: Python :: 3.11
22
18
  Classifier: Programming Language :: Python :: 3.12
23
19
  Classifier: Programming Language :: Python :: 3.13
24
- Classifier: Topic :: Internet :: Name Service (DNS)
25
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
- Requires-Python: >=3.10
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Requires-Dist: black>=26.5 ; extra == 'dev'
22
+ Requires-Dist: coverage>=7.15 ; extra == 'dev'
23
+ Requires-Dist: hypercorn>=0.18.0 ; extra == 'dev'
24
+ Requires-Dist: pyright>=1.1.411 ; extra == 'dev'
25
+ Requires-Dist: pytest>=9.1 ; extra == 'dev'
26
+ Requires-Dist: pytest-cov>=7.1 ; extra == 'dev'
27
+ Requires-Dist: quart-trio>=0.12.0 ; extra == 'dev'
28
+ Requires-Dist: ruff>=0.16.0 ; extra == 'dev'
29
+ Requires-Dist: sphinx>=9.1.0 ; python_full_version >= '3.12' and extra == 'dev'
30
+ Requires-Dist: sphinx-rtd-theme>=3.1.0 ; python_full_version >= '3.12' and extra == 'dev'
31
+ Requires-Dist: trustme>=1.2.1 ; extra == 'dev'
32
+ Requires-Dist: ty>=0.0.85 ; extra == 'dev'
33
+ Requires-Dist: cryptography>=50 ; extra == 'dnssec'
34
+ Requires-Dist: httpcore2>=2.13 ; extra == 'doh'
35
+ Requires-Dist: httpx2>=2.13 ; extra == 'doh'
36
+ Requires-Dist: h2>=4.4 ; extra == 'doh'
37
+ Requires-Dist: aioquic>=1.3.0 ; extra == 'doq'
38
+ Requires-Dist: idna>=3.20 ; extra == 'idna'
39
+ Requires-Dist: trio>=0.34 ; extra == 'trio'
40
+ Requires-Dist: wmi>=1.5.1 ; sys_platform == 'win32' and extra == 'wmi'
41
+ Requires-Python: >=3.11
42
+ Project-URL: homepage, https://www.dnspython.org
43
+ Project-URL: repository, https://github.com/rthalley/dnspython.git
44
+ Project-URL: documentation, https://dnspython.readthedocs.io/en/stable/
45
+ Project-URL: issues, https://github.com/rthalley/dnspython/issues
27
46
  Provides-Extra: dev
28
- Requires-Dist: black>=25.1.0; extra == 'dev'
29
- Requires-Dist: coverage>=7.0; extra == 'dev'
30
- Requires-Dist: flake8>=7; extra == 'dev'
31
- Requires-Dist: hypercorn>=0.17.0; extra == 'dev'
32
- Requires-Dist: mypy>=1.17; extra == 'dev'
33
- Requires-Dist: pylint>=3; extra == 'dev'
34
- Requires-Dist: pytest-cov>=6.2.0; extra == 'dev'
35
- Requires-Dist: pytest>=8.4; extra == 'dev'
36
- Requires-Dist: quart-trio>=0.12.0; extra == 'dev'
37
- Requires-Dist: sphinx-rtd-theme>=3.0.0; extra == 'dev'
38
- Requires-Dist: sphinx>=8.2.0; extra == 'dev'
39
- Requires-Dist: twine>=6.1.0; extra == 'dev'
40
- Requires-Dist: wheel>=0.45.0; extra == 'dev'
41
47
  Provides-Extra: dnssec
42
- Requires-Dist: cryptography>=45; extra == 'dnssec'
43
48
  Provides-Extra: doh
44
- Requires-Dist: h2>=4.2.0; extra == 'doh'
45
- Requires-Dist: httpcore>=1.0.0; extra == 'doh'
46
- Requires-Dist: httpx>=0.28.0; extra == 'doh'
47
49
  Provides-Extra: doq
48
- Requires-Dist: aioquic>=1.2.0; extra == 'doq'
49
50
  Provides-Extra: idna
50
- Requires-Dist: idna>=3.10; extra == 'idna'
51
51
  Provides-Extra: trio
52
- Requires-Dist: trio>=0.30; extra == 'trio'
53
52
  Provides-Extra: wmi
54
- Requires-Dist: wmi>=1.5.1; (platform_system == 'Windows') and extra == 'wmi'
55
53
  Description-Content-Type: text/markdown
56
54
 
57
55
  # dnspython
@@ -73,8 +71,8 @@ classes perform queries for data of a given name, type, and class, and return an
73
71
  answer set. The low-level classes allow direct manipulation of DNS zones,
74
72
  messages, names, and records.
75
73
 
76
- To see a few of the ways `dnspython` can be used, look in the `examples/`
77
- directory.
74
+ The module name for `dnspython` is `dns`. To see a few of the ways `dnspython` can be
75
+ used, look in the `examples/` directory.
78
76
 
79
77
  `dnspython` is a utility to work with DNS, `/etc/hosts` is thus not used. For
80
78
  simple forward DNS lookups, it's better to use `socket.getaddrinfo()` or
@@ -85,7 +83,7 @@ testing of DNS software.
85
83
 
86
84
  ## ABOUT THIS RELEASE
87
85
 
88
- This is of `dnspython` 2.8.0.
86
+ This is `dnspython` 2.9.0.
89
87
  Please read
90
88
  [What's New](https://dnspython.readthedocs.io/en/stable/whatsnew.html) for
91
89
  information about the changes in this release.
@@ -142,8 +140,8 @@ Note that you can install any combination of the above, e.g.:
142
140
 
143
141
  ### Notices
144
142
 
145
- Python 2.x support ended with the release of 1.16.0. `dnspython` supports Python 3.10
146
- and later. Future support is aligned with the lifetime of the Python 3 versions.
143
+ Python 2.x support ended with the release of 1.16.0. `dnspython` supports Python 3.11
144
+ and later. Future support is aligned with the lifetime of the Python 3 versions.
147
145
 
148
146
  Documentation has moved to
149
147
  [dnspython.readthedocs.io](https://dnspython.readthedocs.io).
@@ -17,8 +17,8 @@ classes perform queries for data of a given name, type, and class, and return an
17
17
  answer set. The low-level classes allow direct manipulation of DNS zones,
18
18
  messages, names, and records.
19
19
 
20
- To see a few of the ways `dnspython` can be used, look in the `examples/`
21
- directory.
20
+ The module name for `dnspython` is `dns`. To see a few of the ways `dnspython` can be
21
+ used, look in the `examples/` directory.
22
22
 
23
23
  `dnspython` is a utility to work with DNS, `/etc/hosts` is thus not used. For
24
24
  simple forward DNS lookups, it's better to use `socket.getaddrinfo()` or
@@ -29,7 +29,7 @@ testing of DNS software.
29
29
 
30
30
  ## ABOUT THIS RELEASE
31
31
 
32
- This is of `dnspython` 2.8.0.
32
+ This is `dnspython` 2.9.0.
33
33
  Please read
34
34
  [What's New](https://dnspython.readthedocs.io/en/stable/whatsnew.html) for
35
35
  information about the changes in this release.
@@ -86,8 +86,8 @@ Note that you can install any combination of the above, e.g.:
86
86
 
87
87
  ### Notices
88
88
 
89
- Python 2.x support ended with the release of 1.16.0. `dnspython` supports Python 3.10
90
- and later. Future support is aligned with the lifetime of the Python 3 versions.
89
+ Python 2.x support ended with the release of 1.16.0. `dnspython` supports Python 3.11
90
+ and later. Future support is aligned with the lifetime of the Python 3 versions.
91
91
 
92
92
  Documentation has moved to
93
93
  [dnspython.readthedocs.io](https://dnspython.readthedocs.io).
@@ -53,6 +53,7 @@ __all__ = [
53
53
  "rrset",
54
54
  "serial",
55
55
  "set",
56
+ "style",
56
57
  "tokenizer",
57
58
  "transaction",
58
59
  "tsig",
@@ -63,10 +64,11 @@ __all__ = [
63
64
  "version",
64
65
  "versioned",
65
66
  "wire",
67
+ "wirebase",
66
68
  "xfr",
67
69
  "zone",
68
- "zonetypes",
69
70
  "zonefile",
71
+ "zonetypes",
70
72
  ]
71
73
 
72
74
  from dns.version import version as __version__ # noqa
@@ -21,32 +21,25 @@ def _get_running_loop():
21
21
  return asyncio.get_event_loop()
22
22
 
23
23
 
24
- class _DatagramProtocol:
24
+ class _DatagramProtocol(asyncio.DatagramProtocol):
25
25
  def __init__(self):
26
26
  self.transport = None
27
- self.recvfrom = None
27
+ self.recvq = asyncio.Queue()
28
28
 
29
29
  def connection_made(self, transport):
30
30
  self.transport = transport
31
31
 
32
32
  def datagram_received(self, data, addr):
33
- if self.recvfrom and not self.recvfrom.done():
34
- self.recvfrom.set_result((data, addr))
33
+ self.recvq.put_nowait((data, addr))
35
34
 
36
- def error_received(self, exc): # pragma: no cover
37
- if self.recvfrom and not self.recvfrom.done():
38
- self.recvfrom.set_exception(exc)
35
+ def error_received(self, exc):
36
+ self.recvq.put_nowait(exc)
39
37
 
40
38
  def connection_lost(self, exc):
41
- if self.recvfrom and not self.recvfrom.done():
42
- if exc is None:
43
- # EOF we triggered. Is there a better way to do this?
44
- try:
45
- raise EOFError("EOF")
46
- except EOFError as e:
47
- self.recvfrom.set_exception(e)
48
- else:
49
- self.recvfrom.set_exception(exc)
39
+ if exc is None:
40
+ self.recvq.put_nowait(EOFError("EOF"))
41
+ else:
42
+ self.recvq.put_nowait(exc)
50
43
 
51
44
  def close(self):
52
45
  if self.transport is not None:
@@ -57,13 +50,13 @@ async def _maybe_wait_for(awaitable, timeout):
57
50
  if timeout is not None:
58
51
  try:
59
52
  return await asyncio.wait_for(awaitable, timeout)
60
- except asyncio.TimeoutError:
53
+ except TimeoutError:
61
54
  raise dns.exception.Timeout(timeout=timeout)
62
55
  else:
63
56
  return await awaitable
64
57
 
65
58
 
66
- class DatagramSocket(dns._asyncbackend.DatagramSocket):
59
+ class _DatagramSocket(dns._asyncbackend.DatagramSocket):
67
60
  def __init__(self, family, transport, protocol):
68
61
  super().__init__(family, socket.SOCK_DGRAM)
69
62
  self.transport = transport
@@ -76,14 +69,10 @@ class DatagramSocket(dns._asyncbackend.DatagramSocket):
76
69
 
77
70
  async def recvfrom(self, size, timeout):
78
71
  # ignore size as there's no way I know to tell protocol about it
79
- done = _get_running_loop().create_future()
80
- try:
81
- assert self.protocol.recvfrom is None
82
- self.protocol.recvfrom = done
83
- await _maybe_wait_for(done, timeout)
84
- return done.result()
85
- finally:
86
- self.protocol.recvfrom = None
72
+ pkg = await _maybe_wait_for(self.protocol.recvq.get(), timeout)
73
+ if isinstance(pkg, BaseException):
74
+ raise pkg
75
+ return pkg
87
76
 
88
77
  async def close(self):
89
78
  self.protocol.close()
@@ -98,7 +87,7 @@ class DatagramSocket(dns._asyncbackend.DatagramSocket):
98
87
  raise NotImplementedError
99
88
 
100
89
 
101
- class StreamSocket(dns._asyncbackend.StreamSocket):
90
+ class _StreamSocket(dns._asyncbackend.StreamSocket):
102
91
  def __init__(self, af, reader, writer):
103
92
  super().__init__(af, socket.SOCK_STREAM)
104
93
  self.reader = reader
@@ -126,12 +115,12 @@ class StreamSocket(dns._asyncbackend.StreamSocket):
126
115
 
127
116
  if dns._features.have("doh"):
128
117
  import anyio
129
- import httpcore
130
- import httpcore._backends.anyio
131
- import httpx
118
+ import httpcore2
119
+ import httpcore2._backends.anyio
120
+ import httpx2
132
121
 
133
- _CoreAsyncNetworkBackend = httpcore.AsyncNetworkBackend
134
- _CoreAnyIOStream = httpcore._backends.anyio.AnyIOStream # pyright: ignore
122
+ _CoreAsyncNetworkBackend = httpcore2.AsyncNetworkBackend
123
+ _CoreAnyIOStream = httpcore2._backends.anyio.AnyIOStream # pyright: ignore
135
124
 
136
125
  from dns.query import _compute_times, _expiration_for_this_attempt, _remaining
137
126
 
@@ -144,7 +133,7 @@ if dns._features.have("doh"):
144
133
  self._family = family
145
134
  if local_port != 0:
146
135
  raise NotImplementedError(
147
- "the asyncio transport for HTTPX cannot set the local port"
136
+ "the asyncio transport for httpx2 cannot set the local port"
148
137
  )
149
138
 
150
139
  async def connect_tcp(
@@ -178,7 +167,7 @@ if dns._features.have("doh"):
178
167
  return _CoreAnyIOStream(stream)
179
168
  except Exception:
180
169
  pass
181
- raise httpcore.ConnectError
170
+ raise httpcore2.ConnectError
182
171
 
183
172
  async def connect_unix_socket(
184
173
  self, path, timeout=None, socket_options=None
@@ -188,7 +177,7 @@ if dns._features.have("doh"):
188
177
  async def sleep(self, seconds): # pylint: disable=signature-differs
189
178
  await anyio.sleep(seconds)
190
179
 
191
- class _HTTPTransport(httpx.AsyncHTTPTransport):
180
+ class _HTTPTransport(httpx2.AsyncHTTPTransport):
192
181
  def __init__(
193
182
  self,
194
183
  *args,
@@ -204,12 +193,12 @@ if dns._features.have("doh"):
204
193
 
205
194
  resolver = dns.asyncresolver.Resolver()
206
195
  super().__init__(*args, **kwargs)
207
- self._pool._network_backend = _NetworkBackend(
196
+ self._pool._network_backend = _NetworkBackend( # type: ignore
208
197
  resolver, local_port, bootstrap_address, family
209
198
  )
210
199
 
211
200
  else:
212
- _HTTPTransport = dns._asyncbackend.NullTransport # type: ignore
201
+ _HTTPTransport = dns._asyncbackend.NullTransport # pyright: ignore
213
202
 
214
203
 
215
204
  class Backend(dns._asyncbackend.Backend):
@@ -235,18 +224,18 @@ class Backend(dns._asyncbackend.Backend):
235
224
  source = (dns.inet.any_for_af(af), 0)
236
225
  transport, protocol = await loop.create_datagram_endpoint(
237
226
  _DatagramProtocol, # pyright: ignore
238
- source,
227
+ local_addr=source,
239
228
  family=af,
240
229
  proto=proto,
241
230
  remote_addr=destination,
242
231
  )
243
- return DatagramSocket(af, transport, protocol)
232
+ return _DatagramSocket(af, transport, protocol)
244
233
  elif socktype == socket.SOCK_STREAM:
245
234
  if destination is None:
246
235
  # This shouldn't happen, but we check to make code analysis software
247
236
  # happier.
248
237
  raise ValueError("destination required for stream sockets")
249
- (r, w) = await _maybe_wait_for(
238
+ r, w = await _maybe_wait_for(
250
239
  asyncio.open_connection(
251
240
  destination[0],
252
241
  destination[1],
@@ -258,7 +247,7 @@ class Backend(dns._asyncbackend.Backend):
258
247
  ),
259
248
  timeout,
260
249
  )
261
- return StreamSocket(af, r, w)
250
+ return _StreamSocket(af, r, w)
262
251
  raise NotImplementedError(
263
252
  "unsupported socket " + f"type {socktype}"
264
253
  ) # pragma: no cover
@@ -7,6 +7,7 @@ import time
7
7
  from urllib.parse import urlparse
8
8
 
9
9
  import dns.asyncbackend
10
+ import dns.exception
10
11
  import dns.inet
11
12
  import dns.name
12
13
  import dns.nameserver
@@ -32,15 +33,25 @@ class _SVCBInfo:
32
33
 
33
34
  def ddr_check_certificate(self, cert):
34
35
  """Verify that the _SVCBInfo's address is in the cert's subjectAltName (SAN)"""
36
+ # ssl renders IPv6 SAN entries uncompressed and in upper case (e.g.
37
+ # 2001:DB8:0:0:0:0:0:1), so compare addresses in binary form, not as text.
38
+ af = dns.inet.af_for_address(self.bootstrap_address)
39
+ address = dns.inet.inet_pton(af, self.bootstrap_address)
35
40
  for name, value in cert["subjectAltName"]:
36
- if name == "IP Address" and value == self.bootstrap_address:
37
- return True
41
+ if name != "IP Address":
42
+ continue
43
+ try:
44
+ if dns.inet.inet_pton(af, value) == address:
45
+ return True
46
+ except dns.exception.SyntaxError:
47
+ # An address of the other family, or one we cannot parse.
48
+ pass
38
49
  return False
39
50
 
40
51
  def make_tls_context(self):
41
52
  ssl = dns.query.ssl
42
53
  ctx = ssl.create_default_context()
43
- ctx.minimum_version = ssl.TLSVersion.TLSv1_2
54
+ ctx.minimum_version = ssl.TLSVersion.TLSv1_2 # type: ignore
44
55
  return ctx
45
56
 
46
57
  def ddr_tls_check_sync(self, lifetime):
@@ -94,21 +105,24 @@ def _extract_nameservers_from_svcb(answer):
94
105
  # bootstrap address
95
106
  if b"h2" in alpns:
96
107
  param = rr.params.get(dns.rdtypes.svcbbase.ParamKey.DOHPATH)
97
- if param is None or not param.value.endswith(b"{?dns}"):
98
- continue
99
- path = param.value[:-6].decode()
100
- if not path.startswith("/"):
101
- path = "/" + path
102
- if port is None:
103
- port = 443
104
- url = f"https://{host}:{port}{path}"
105
- # check the URL
106
- try:
107
- urlparse(url)
108
- nameservers.append(dns.nameserver.DoHNameserver(url, bootstrap_address))
109
- except Exception:
110
- # continue processing other ALPN types
111
- pass
108
+ # A missing or malformed dohpath only rules out the DoH nameserver;
109
+ # any dot/doq resolver advertised by the same record is still valid.
110
+ if param is not None and param.value.endswith(b"{?dns}"):
111
+ path = param.value[:-6].decode()
112
+ if not path.startswith("/"):
113
+ path = "/" + path
114
+ if port is None:
115
+ port = 443
116
+ url = f"https://{host}:{port}{path}"
117
+ # check the URL
118
+ try:
119
+ urlparse(url)
120
+ nameservers.append(
121
+ dns.nameserver.DoHNameserver(url, bootstrap_address)
122
+ )
123
+ except Exception:
124
+ # continue processing other ALPN types
125
+ pass
112
126
  if b"dot" in alpns:
113
127
  if port is None:
114
128
  port = 853
@@ -3,10 +3,9 @@
3
3
  import importlib.metadata
4
4
  import itertools
5
5
  import string
6
- from typing import Dict, List, Tuple
7
6
 
8
7
 
9
- def _tuple_from_text(version: str) -> Tuple:
8
+ def _tuple_from_text(version: str) -> tuple:
10
9
  text_parts = version.split(".")
11
10
  int_parts = []
12
11
  for text_part in text_parts:
@@ -44,7 +43,7 @@ def _version_check(
44
43
  return True
45
44
 
46
45
 
47
- _cache: Dict[str, bool] = {}
46
+ _cache: dict[str, bool] = {}
48
47
 
49
48
 
50
49
  def have(feature: str) -> bool:
@@ -83,13 +82,13 @@ def force(feature: str, enabled: bool) -> None:
83
82
  _cache[feature] = enabled
84
83
 
85
84
 
86
- _requirements: Dict[str, List[str]] = {
85
+ _requirements: dict[str, list[str]] = {
87
86
  ### BEGIN generated requirements
88
- "dnssec": ["cryptography>=45"],
89
- "doh": ["httpcore>=1.0.0", "httpx>=0.28.0", "h2>=4.2.0"],
90
- "doq": ["aioquic>=1.2.0"],
91
- "idna": ["idna>=3.10"],
92
- "trio": ["trio>=0.30"],
87
+ "dnssec": ["cryptography>=50"],
88
+ "doh": ["httpcore2>=2.13", "httpx2>=2.13", "h2>=4.4"],
89
+ "doq": ["aioquic>=1.3.0"],
90
+ "idna": ["idna>=3.20"],
91
+ "trio": ["trio>=0.34"],
93
92
  "wmi": ["wmi>=1.5.1"],
94
93
  ### END generated requirements
95
94
  }
@@ -0,0 +1,21 @@
1
+ # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
2
+
3
+ import contextlib
4
+ import os
5
+ from typing import IO, Any, cast
6
+
7
+
8
+ def as_filename(f: object) -> str | None:
9
+ if isinstance(f, (str, os.PathLike)):
10
+ return os.fsdecode(f)
11
+ return None
12
+
13
+
14
+ def maybe_open(
15
+ f: str | os.PathLike | IO[Any], mode: str = "r", encoding: str | None = None
16
+ ) -> contextlib.AbstractContextManager[IO[Any]]:
17
+ filename = as_filename(f)
18
+ if filename is not None:
19
+ return open(filename, mode, encoding=encoding)
20
+ # as_filename() is not a type guard, so narrow f by hand
21
+ return contextlib.nullcontext(cast(IO[Any], f))
@@ -41,7 +41,7 @@ def _immutable_init(f):
41
41
  finally:
42
42
  _in__init__.reset(previous)
43
43
 
44
- nf.__signature__ = inspect.signature(f) # pyright: ignore
44
+ nf.__signature__ = inspect.signature(f) # type: ignore
45
45
  return nf
46
46
 
47
47
 
@@ -30,10 +30,10 @@ class SSLContext:
30
30
  self.check_hostname: bool = False
31
31
  self.verify_mode: int = CERT_NONE
32
32
 
33
- def wrap_socket(self, *args, **kwargs) -> "SSLSocket": # type: ignore
33
+ def wrap_socket(self, *args, **kwargs) -> "SSLSocket": # pyright: ignore
34
34
  raise Exception("no ssl support") # pylint: disable=broad-exception-raised
35
35
 
36
- def set_alpn_protocols(self, *args, **kwargs): # type: ignore
36
+ def set_alpn_protocols(self, *args, **kwargs): # pyright: ignore
37
37
  raise Exception("no ssl support") # pylint: disable=broad-exception-raised
38
38
 
39
39
 
@@ -57,5 +57,5 @@ class SSLSocket:
57
57
  return False
58
58
 
59
59
 
60
- def create_default_context(*args, **kwargs) -> SSLContext: # type: ignore
60
+ def create_default_context(*args, **kwargs) -> SSLContext: # pyright: ignore
61
61
  raise Exception("no ssl support") # pylint: disable=broad-exception-raised
@@ -0,0 +1,21 @@
1
+ import contextlib
2
+
3
+ import dns.exception
4
+
5
+
6
+ @contextlib.contextmanager
7
+ def prefixed_length(output, length_length):
8
+ output.write(b"\00" * length_length)
9
+ start = output.tell()
10
+ yield
11
+ end = output.tell()
12
+ length = end - start
13
+ if length > 0:
14
+ try:
15
+ output.seek(start - length_length)
16
+ try:
17
+ output.write(length.to_bytes(length_length, "big"))
18
+ except OverflowError:
19
+ raise dns.exception.FormError
20
+ finally:
21
+ output.seek(end)
@@ -0,0 +1,45 @@
1
+ # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
2
+
3
+ """Internal text-processing helpers."""
4
+
5
+ import functools
6
+ import string
7
+
8
+ _ASCII_DIGITS = frozenset(string.digits)
9
+
10
+ _ALL_ASCII_DIGITS = string.digits + string.ascii_lowercase
11
+
12
+
13
+ def is_ascii_digit(c: str) -> bool:
14
+ """Is *c* one of the ASCII digits "0" through "9"?
15
+
16
+ Unlike ``str.isdigit()`` and ``str.isdecimal()``, this returns ``False``
17
+ for non-ASCII digits such as U+0967 DEVANAGARI DIGIT ONE.
18
+ """
19
+ return c in _ASCII_DIGITS
20
+
21
+
22
+ @functools.cache
23
+ def _ascii_digits_for_base(base: int) -> frozenset[str]:
24
+ if base < 2 or base > 36:
25
+ raise ValueError(f"invalid base {base}")
26
+ digits = _ALL_ASCII_DIGITS[:base]
27
+ return frozenset(digits + digits.upper())
28
+
29
+
30
+ def is_ascii_digits(text: str, base: int = 10) -> bool:
31
+ """Is *text* a non-empty string consisting only of ASCII digits valid in
32
+ *base*?
33
+
34
+ Digits greater than 9 are the ASCII letters, in either case, as with
35
+ ``int()``. Unlike ``int()``, a sign, whitespace, underscores, and base
36
+ prefixes such as ``0x`` are not allowed. Unlike ``str.isdigit()`` and
37
+ ``str.isdecimal()``, non-ASCII digits such as U+0967 DEVANAGARI DIGIT ONE
38
+ are not allowed.
39
+
40
+ Raises ``ValueError`` if *base* is not between 2 and 36 inclusive.
41
+ """
42
+ if base == 10:
43
+ return text.isascii() and text.isdecimal()
44
+ digits = _ascii_digits_for_base(base)
45
+ return len(text) > 0 and all(c in digits for c in text)
@@ -0,0 +1,21 @@
1
+ # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
2
+
3
+ import os
4
+
5
+ import dns._file_util
6
+
7
+
8
+ def convert_verify_to_cafile_and_capath(
9
+ verify: bool | str | os.PathLike,
10
+ ) -> tuple[str | None, str | None]:
11
+ cafile: str | None = None
12
+ capath: str | None = None
13
+ filename = dns._file_util.as_filename(verify)
14
+ if filename is not None:
15
+ if os.path.isfile(filename):
16
+ cafile = filename
17
+ elif os.path.isdir(filename):
18
+ capath = filename
19
+ else:
20
+ raise ValueError("invalid verify string")
21
+ return cafile, capath
@@ -5,7 +5,7 @@
5
5
  import socket
6
6
 
7
7
  import trio
8
- import trio.socket # type: ignore
8
+ import trio.socket # pyright: ignore
9
9
 
10
10
  import dns._asyncbackend
11
11
  import dns._features
@@ -103,12 +103,12 @@ class StreamSocket(dns._asyncbackend.StreamSocket):
103
103
 
104
104
 
105
105
  if dns._features.have("doh"):
106
- import httpcore
107
- import httpcore._backends.trio
108
- import httpx
106
+ import httpcore2
107
+ import httpcore2._backends.trio
108
+ import httpx2
109
109
 
110
- _CoreAsyncNetworkBackend = httpcore.AsyncNetworkBackend
111
- _CoreTrioStream = httpcore._backends.trio.TrioStream
110
+ _CoreAsyncNetworkBackend = httpcore2.AsyncNetworkBackend
111
+ _CoreTrioStream = httpcore2._backends.trio.TrioStream
112
112
 
113
113
  from dns.query import _compute_times, _expiration_for_this_attempt, _remaining
114
114
 
@@ -155,7 +155,7 @@ if dns._features.have("doh"):
155
155
  return _CoreTrioStream(sock.stream)
156
156
  except Exception:
157
157
  continue
158
- raise httpcore.ConnectError
158
+ raise httpcore2.ConnectError
159
159
 
160
160
  async def connect_unix_socket(
161
161
  self, path, timeout=None, socket_options=None
@@ -165,7 +165,7 @@ if dns._features.have("doh"):
165
165
  async def sleep(self, seconds): # pylint: disable=signature-differs
166
166
  await trio.sleep(seconds)
167
167
 
168
- class _HTTPTransport(httpx.AsyncHTTPTransport):
168
+ class _HTTPTransport(httpx2.AsyncHTTPTransport):
169
169
  def __init__(
170
170
  self,
171
171
  *args,
@@ -181,12 +181,12 @@ if dns._features.have("doh"):
181
181
 
182
182
  resolver = dns.asyncresolver.Resolver()
183
183
  super().__init__(*args, **kwargs)
184
- self._pool._network_backend = _NetworkBackend(
184
+ self._pool._network_backend = _NetworkBackend( # type: ignore
185
185
  resolver, local_port, bootstrap_address, family
186
186
  )
187
187
 
188
188
  else:
189
- _HTTPTransport = dns._asyncbackend.NullTransport # type: ignore
189
+ _HTTPTransport = dns._asyncbackend.NullTransport # pyright: ignore
190
190
 
191
191
 
192
192
  class Backend(dns._asyncbackend.Backend):