使用 py2exe 时导入 `requests` 的问题
problems with importing `requests` when using py2exe
TL;DR
当冻结 py2exe
时,在 Python3 项目中导入 requests
库失败。
解冻项目有效。
该问题似乎与 requests
模块中的相对导入有关。
详细说明
我使用 Python3 创建了一个小项目,并想将其转换为 w32 的可执行文件。
该项目依赖于 PySide
和 requests
(2.13.0;实际上这是使用的 pyapi-gitlab
包的次要依赖项)。
所有依赖项都已通过 pip3
安装。
Python 版本是 3.4.4(因为 PySide 不支持任何更高版本的 Py3)。
我正在使用 py2exe 0.9.2.2
.
一切(例如导入和使用 PySide
)都很好,但 import requests
内部深处失败了。
这里有一个稍微简单的例子来说明这个问题:
import logging
logging.basicConfig()
log = logging.getLogger()
import sys
print("Python: %s" % (sys.version,))
try:
import requests
except ImportError:
log.fatal("failed to import 'requests'", exc_info=True)
当我从 cmdline 中 运行 时,我得到:
E:\p2e> python p2e.py
Python: 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (Intel)]
E:\p2e>
不错。
以下最小 setup.py
应该将其转换为 exe:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from distutils.core import setup
import py2exe
setup(console=['p2e.py'])
进行实际转换会给出一些 "missing modules" 警告:
E:\p2e> python setup.py py2exe
running py2exe
24 missing Modules
------------------
? Cookie imported from requests.compat
? OpenSSL imported from requests.packages.urllib3.contrib.pyopenssl
? Queue imported from requests.packages.urllib3.connectionpool
? _abcoll imported from requests.packages.urllib3.packages.ordered_dict
? backports imported from requests.packages.urllib3.packages.ssl_match_hostname
? certifi imported from requests.certs
? chardet imported from requests.packages
? cookielib imported from requests.compat
? cryptography imported from requests.packages.urllib3.contrib.pyopenssl
? idna imported from requests.models, requests.packages.urllib3.contrib.pyopenssl
? netbios imported from uuid
? readline imported from cmd, code, pdb
? simplejson imported from requests.compat
? six imported from requests.packages.urllib3.contrib.pyopenssl
? socks imported from requests.packages.urllib3.contrib.socks
? urllib.getproxies imported from requests.compat
? urllib.proxy_bypass imported from requests.compat
? urllib.quote imported from requests.compat
? urllib.quote_plus imported from requests.compat
? urllib.unquote imported from requests.compat
? urllib.unquote_plus imported from requests.compat
? urllib.urlencode imported from requests.compat
? urllib3 imported from requests.packages
? win32wnet imported from uuid
Building 'dist\p2e.exe'.
Building shared code archive 'dist\library.zip'.
Copy c:\windows\system32\python34.dll to dist
Copy C:\Python34\DLLs\_ssl.pyd to dist\_ssl.pyd
Copy C:\Python34\DLLs\_lzma.pyd to dist\_lzma.pyd
Copy C:\Python34\DLLs\select.pyd to dist\select.pyd
Copy C:\Python34\DLLs\_hashlib.pyd to dist\_hashlib.pyd
Copy C:\Python34\DLLs\_ctypes.pyd to dist\_ctypes.pyd
Copy C:\Python34\DLLs\_bz2.pyd to dist\_bz2.pyd
Copy C:\Python34\DLLs\_socket.pyd to dist\_socket.pyd
Copy C:\Python34\DLLs\pyexpat.pyd to dist\pyexpat.pyd
Copy C:\Python34\DLLs\unicodedata.pyd to dist\unicodedata.pyd
E:\p2e>
我经常忽略这些警告,运行 生成的 exe:
E:\p2e> dist\p2e.exe
CRITICAL:root:failed to import 'requests'
Traceback (most recent call last):
File "c:\Python34\lib\site-packages\requests\packages\__init__.py", line 27, in <module>
from . import urllib3
File "c:\Python34\lib\site-packages\requests\packages\urllib3\__init__.py", line 8, in <module>
from .connectionpool import (
File "c:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 28, in <module>
from .packages.six.moves import queue
File "c:\Python34\lib\site-packages\requests\packages\urllib3\packages\six.py", line 92, in __get__
result = self._resolve()
File "c:\Python34\lib\site-packages\requests\packages\urllib3\packages\six.py", line 115, in _resolve
return _import_module(self.mod)
File "c:\Python34\lib\site-packages\requests\packages\urllib3\packages\six.py", line 82, in _import_module
__import__(name)
ImportError: No module named 'queue'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "p2e.py", line 9, in <module>
File "c:\Python34\lib\site-packages\requests\__init__.py", line 63, in <module>
from . import utils
File "c:\Python34\lib\site-packages\requests\utils.py", line 24, in <module>
from ._internal_utils import to_native_string
File "c:\Python34\lib\site-packages\requests\_internal_utils.py", line 11, in <module>
from .compat import is_py2, builtin_str, str
File "c:\Python34\lib\site-packages\requests\compat.py", line 11, in <module>
from .packages import chardet
File "c:\Python34\lib\site-packages\requests\packages\__init__.py", line 29, in <module>
import urllib3
ImportError: No module named 'urllib3'
Python: 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (Intel)]
E:\p2e>
我百思不得其解
似乎 requests
包对
- 支持包含的第 3 方库 (urllib
) 和包管理器安装的库。
- 同时支持 Py2 和 Py3(使用 six
的本地副本)
两者似乎都会产生问题。
我可以修改 urllib3
问题,通过修补 requests
以仅在相对路径中搜索该包(即使原始代码也是如此,只是用 try/catch
捕获任何 ImportError
然后退回到全局导入。)
我不知道如何解决 import queue
问题。
毕竟,当我 运行 Py3 解释器中的脚本时,它 是 正常工作。
注意
有一个类似(可能相同)的问题,但它没有包含那么多信息:py2exe "requests" module missing
看起来 urllib3 试图导入失败的 queue
模块。如果失败,请求将无法导入 `urllib3.
要强制 py2exe 包含 queue
模块,请在调用它时使用 --includes queue
。
TL;DR
当冻结 py2exe
时,在 Python3 项目中导入 requests
库失败。
解冻项目有效。
该问题似乎与 requests
模块中的相对导入有关。
详细说明
我使用 Python3 创建了一个小项目,并想将其转换为 w32 的可执行文件。
该项目依赖于 PySide
和 requests
(2.13.0;实际上这是使用的 pyapi-gitlab
包的次要依赖项)。
所有依赖项都已通过 pip3
安装。
Python 版本是 3.4.4(因为 PySide 不支持任何更高版本的 Py3)。
我正在使用 py2exe 0.9.2.2
.
一切(例如导入和使用 PySide
)都很好,但 import requests
内部深处失败了。
这里有一个稍微简单的例子来说明这个问题:
import logging
logging.basicConfig()
log = logging.getLogger()
import sys
print("Python: %s" % (sys.version,))
try:
import requests
except ImportError:
log.fatal("failed to import 'requests'", exc_info=True)
当我从 cmdline 中 运行 时,我得到:
E:\p2e> python p2e.py
Python: 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (Intel)]
E:\p2e>
不错。
以下最小 setup.py
应该将其转换为 exe:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from distutils.core import setup
import py2exe
setup(console=['p2e.py'])
进行实际转换会给出一些 "missing modules" 警告:
E:\p2e> python setup.py py2exe
running py2exe
24 missing Modules
------------------
? Cookie imported from requests.compat
? OpenSSL imported from requests.packages.urllib3.contrib.pyopenssl
? Queue imported from requests.packages.urllib3.connectionpool
? _abcoll imported from requests.packages.urllib3.packages.ordered_dict
? backports imported from requests.packages.urllib3.packages.ssl_match_hostname
? certifi imported from requests.certs
? chardet imported from requests.packages
? cookielib imported from requests.compat
? cryptography imported from requests.packages.urllib3.contrib.pyopenssl
? idna imported from requests.models, requests.packages.urllib3.contrib.pyopenssl
? netbios imported from uuid
? readline imported from cmd, code, pdb
? simplejson imported from requests.compat
? six imported from requests.packages.urllib3.contrib.pyopenssl
? socks imported from requests.packages.urllib3.contrib.socks
? urllib.getproxies imported from requests.compat
? urllib.proxy_bypass imported from requests.compat
? urllib.quote imported from requests.compat
? urllib.quote_plus imported from requests.compat
? urllib.unquote imported from requests.compat
? urllib.unquote_plus imported from requests.compat
? urllib.urlencode imported from requests.compat
? urllib3 imported from requests.packages
? win32wnet imported from uuid
Building 'dist\p2e.exe'.
Building shared code archive 'dist\library.zip'.
Copy c:\windows\system32\python34.dll to dist
Copy C:\Python34\DLLs\_ssl.pyd to dist\_ssl.pyd
Copy C:\Python34\DLLs\_lzma.pyd to dist\_lzma.pyd
Copy C:\Python34\DLLs\select.pyd to dist\select.pyd
Copy C:\Python34\DLLs\_hashlib.pyd to dist\_hashlib.pyd
Copy C:\Python34\DLLs\_ctypes.pyd to dist\_ctypes.pyd
Copy C:\Python34\DLLs\_bz2.pyd to dist\_bz2.pyd
Copy C:\Python34\DLLs\_socket.pyd to dist\_socket.pyd
Copy C:\Python34\DLLs\pyexpat.pyd to dist\pyexpat.pyd
Copy C:\Python34\DLLs\unicodedata.pyd to dist\unicodedata.pyd
E:\p2e>
我经常忽略这些警告,运行 生成的 exe:
E:\p2e> dist\p2e.exe
CRITICAL:root:failed to import 'requests'
Traceback (most recent call last):
File "c:\Python34\lib\site-packages\requests\packages\__init__.py", line 27, in <module>
from . import urllib3
File "c:\Python34\lib\site-packages\requests\packages\urllib3\__init__.py", line 8, in <module>
from .connectionpool import (
File "c:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 28, in <module>
from .packages.six.moves import queue
File "c:\Python34\lib\site-packages\requests\packages\urllib3\packages\six.py", line 92, in __get__
result = self._resolve()
File "c:\Python34\lib\site-packages\requests\packages\urllib3\packages\six.py", line 115, in _resolve
return _import_module(self.mod)
File "c:\Python34\lib\site-packages\requests\packages\urllib3\packages\six.py", line 82, in _import_module
__import__(name)
ImportError: No module named 'queue'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "p2e.py", line 9, in <module>
File "c:\Python34\lib\site-packages\requests\__init__.py", line 63, in <module>
from . import utils
File "c:\Python34\lib\site-packages\requests\utils.py", line 24, in <module>
from ._internal_utils import to_native_string
File "c:\Python34\lib\site-packages\requests\_internal_utils.py", line 11, in <module>
from .compat import is_py2, builtin_str, str
File "c:\Python34\lib\site-packages\requests\compat.py", line 11, in <module>
from .packages import chardet
File "c:\Python34\lib\site-packages\requests\packages\__init__.py", line 29, in <module>
import urllib3
ImportError: No module named 'urllib3'
Python: 3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 19:28:18) [MSC v.1600 32 bit (Intel)]
E:\p2e>
我百思不得其解
似乎 requests
包对
- 支持包含的第 3 方库 (urllib
) 和包管理器安装的库。
- 同时支持 Py2 和 Py3(使用 six
的本地副本)
两者似乎都会产生问题。
我可以修改 urllib3
问题,通过修补 requests
以仅在相对路径中搜索该包(即使原始代码也是如此,只是用 try/catch
捕获任何 ImportError
然后退回到全局导入。)
我不知道如何解决 import queue
问题。
毕竟,当我 运行 Py3 解释器中的脚本时,它 是 正常工作。
注意
有一个类似(可能相同)的问题,但它没有包含那么多信息:py2exe "requests" module missing
看起来 urllib3 试图导入失败的 queue
模块。如果失败,请求将无法导入 `urllib3.
要强制 py2exe 包含 queue
模块,请在调用它时使用 --includes queue
。