<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Pip on kites262</title><link>https://kites.cc/tags/pip/</link><description>Recent content in Pip on kites262</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><copyright>kites262</copyright><lastBuildDate>Sat, 30 Nov 2024 14:06:36 +0800</lastBuildDate><atom:link href="https://kites.cc/tags/pip/index.xml" rel="self" type="application/rss+xml"/><item><title>pip 安装依赖时的 SSL 错误</title><link>https://kites.cc/p/python-pip-ssl-proxy-error/</link><pubDate>Sat, 30 Nov 2024 14:06:36 +0800</pubDate><guid>https://kites.cc/p/python-pip-ssl-proxy-error/</guid><description>&lt;p&gt;使用 pip 安装 Python 包时，有时会遇到 SSL 错误，导致依赖无法下载。控制台输出类似：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;WARNING: Retrying &lt;span class="o"&gt;(&lt;/span&gt;Retry&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;total&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4, &lt;span class="nv"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;None, &lt;span class="nv"&gt;read&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;None, &lt;span class="nv"&gt;redirect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;None, &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;None&lt;span class="o"&gt;))&lt;/span&gt; after connection broken by &lt;span class="s1"&gt;&amp;#39;SSLError(SSLZeroReturnError(6, &amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;TLS/SSL connection has been closed &lt;span class="o"&gt;(&lt;/span&gt;EOF&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;_ssl.c:1149&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;))&amp;#39;&lt;/span&gt;: /simple/...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;日志冗长，原因却往往并不复杂。&lt;/p&gt;
&lt;h2 id="问题定位"&gt;问题定位
&lt;/h2&gt;&lt;p&gt;较常见的情况是：系统已配置代理，但该代理主要支持 HTTP；pip 仍将系统代理当作可用于 HTTPS 的通道。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Clash for Windows 等软件，通常会修改 Windows 注册表&lt;br&gt;
&lt;code&gt;计算机\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings&lt;/code&gt;&lt;br&gt;
中的 &lt;code&gt;ProxyServer&lt;/code&gt; 与 &lt;code&gt;ProxyEnable&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在 Python 3.7 / 3.8 中，pip 依赖的 &lt;code&gt;urllib&lt;/code&gt; 会默认读取系统代理，却较少校验代理是否真正支持 HTTPS。连接中途被关闭后，便表现为上述 &lt;code&gt;SSLZeroReturnError&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="处理方式"&gt;处理方式
&lt;/h2&gt;&lt;p&gt;可考虑以下途径：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完整配置代理软件的 HTTPS 代理&lt;/li&gt;
&lt;li&gt;使用 TUN 模式在更底层接管流量&lt;/li&gt;
&lt;li&gt;在 pip 配置文件中写明代理地址&lt;/li&gt;
&lt;li&gt;调整 Python 内置库中的代理协议选择逻辑，使自动检测时仅使用 HTTP&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;前两项与具体代理软件相关，此处不展开。后两项与软件种类关系较小，记录如下。&lt;/p&gt;
&lt;h3 id="1-编写-pip-配置"&gt;1. 编写 pip 配置
&lt;/h3&gt;&lt;p&gt;在用户目录创建配置文件并指定代理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows：&lt;code&gt;%APPDATA%\pip\pip.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Linux：&lt;code&gt;~/.config/pip/pip.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;端口请按本机代理设置修改：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[global]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;proxy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://127.0.0.1:7897&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;保存后重新打开终端，再执行 &lt;code&gt;pip install&lt;/code&gt;，一般即可恢复正常。&lt;/p&gt;
&lt;p&gt;该方式只影响 pip，影响面较小。代价是代理地址固定：更换端口需改配置，系统代理的自动检测也基本失效。&lt;/p&gt;
&lt;h3 id="2-修正内置库行为"&gt;2. 修正内置库行为
&lt;/h3&gt;&lt;p&gt;若不愿在配置中写死代理，可使用我放在 PyPI 上的小工具 &lt;a class="link" href="https://pypi.org/project/pytool-proxy-fix/" target="_blank" rel="noopener"
&gt;&lt;code&gt;pytool-proxy-fix&lt;/code&gt;&lt;/a&gt;（&lt;a class="link" href="https://github.com/kites262/pytool-proxy-fix" target="_blank" rel="noopener"
&gt;GitHub&lt;/a&gt;）。包体积约 8KB，作用单一：使 &lt;code&gt;urllib&lt;/code&gt; 在自动应用系统代理时仅使用 HTTP，避免误走 HTTPS。&lt;/p&gt;
&lt;p&gt;本机测试中，发文时仍会触发该问题的 Python 3.7 / 3.8 均可修复。&lt;/p&gt;
&lt;p&gt;请先确认当前环境确为「系统代理开启且 pip 报 SSL 错误」，并在&lt;strong&gt;关闭代理&lt;/strong&gt;后安装：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install pytool-proxy-fix
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pytool-proxy-fix
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;执行后会修改相应的协议选择逻辑。之后可重新开启代理，并继续使用自动检测。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;若只求尽快恢复安装，使用 &lt;code&gt;pip.ini&lt;/code&gt; / &lt;code&gt;pip.conf&lt;/code&gt; 即可。若希望保留系统代理的自动检测，可优先考虑 &lt;code&gt;pytool-proxy-fix&lt;/code&gt;。该工具以 MIT 协议开源，允许使用与修改；转载或二次开发时请注明原作者。&lt;/p&gt;</description></item></channel></rss>