<p>没有答案,只有几个数据点。DNS解析似乎来自<code>HTTPConnection.connect()</code>中的<code>httplib.py</code>(python 2.5.4 stdlib上的第670行)</p>
<p>代码流大致如下:</p>
<pre><code>for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
self.sock = socket.socket(af, socktype, proto)
try:
self.sock.connect(sa)
except socket.error, msg:
continue
break
</code></pre>
<p>对发生的事情有几点看法:</p>
<ul>
<li><p><code>socket.getaddrinfo()</code>的第三个参数限制套接字系列,即IPv4与IPv6。通过零返回所有族。零被硬编码到stdlib中。</p></li>
<li><p>将主机名传递到<code>getaddrinfo()</code>将导致名称解析——在启用了IPv6的OS X框中,a和AAAA记录都会输出,两个答案都会返回,并且都会返回。</p></li>
<li><p>connect循环的其余部分尝试每个返回的地址,直到一个成功为止</p></li>
</ul>
<p>例如:</p>
<pre><code>>>> socket.getaddrinfo("python.org", 80, 0, socket.SOCK_STREAM)
[
(30, 1, 6, '', ('2001:888:2000:d::a2', 80, 0, 0)),
( 2, 1, 6, '', ('82.94.164.162', 80))
]
>>> help(socket.getaddrinfo)
getaddrinfo(...)
getaddrinfo(host, port [, family, socktype, proto, flags])
-> list of (family, socktype, proto, canonname, sockaddr)
</code></pre>
<p>一些猜测:</p>
<ul>
<li><p>由于<code>getaddrinfo()</code>中的套接字系列硬编码为零,您将无法通过urllib中支持的一些API接口重写A与AAAA记录。除非mechanize出于其他原因执行自己的名称解析,否则mechanize也不能。从连接循环的构造来看,这是通过设计实现的。</p></li>
<li><p>python的socket模块是POSIX socket api的一个瘦包装器;我<em>期望</em>它们正在解析系统上配置的每个可用系列。仔细检查Gentoo的IPv6配置。</p></li>
</ul>