使用requests
冻结时,导入py2exe
库在Python3项目中失败。
未解冻的项目有效。
问题似乎与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'])
进行实际转换会产生一些“缺失模块”警告:
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
包有一些导入魔法
- 支持包括第三方库(urllib
)和包管理器安装的库。
- 支持Py2和Py3(使用six
的本地副本)
两者似乎都会产生问题。
我可以修改urllib3
问题,修补requests
只在相对路径中搜索该包(即使原始代码执行相同操作,仅由try/catch
括起来捕获任何ImportError
,然后回退到全局导入。)
我不知道如何修复import queue
问题。
毕竟,当我在Py3解释器中运行脚本时, 正常工作。
存在类似(可能相同)的问题,但它不包含太多信息:py2exe "requests" module missing
答案 0 :(得分:2)
看起来urllib3尝试导入失败的queue
模块。当失败时,请求无法导入`urllib3。
要强制py2exe包含queue
模块,请在调用时使用--includes queue
。