简体   繁体   English

Pyinstaller错误ImportError:没有名为'requests.packages.chardet.sys的模块

[英]Pyinstaller error ImportError: No module named 'requests.packages.chardet.sys

I can't seem to find the root cause of this. 我似乎找不到这个的根本原因。 I don't know if it's pyinstaller, a pip problem, the requests module, or something else as nothing can be eliminated conclusively. 我不知道它是pyinstaller,pip问题,请求模块还是别的东西,因为没有什么可以最终消除。

I wrote a script in python that properly configures a new hardware sonicwall for our enterprise network when we have to deploy a new unit. 我在python中编写了一个脚本,当我们必须部署一个新单元时,它为我们的企业网络正确配置了一个新的硬件sonicwall。 It configures a proper .exp file in memory, logs into the sonicwall device with default credentials, imports the file via a multi-part data form, restarts the sonicwall, then logs in again and changes the shared secret properly. 它在内存中配置正确的.exp文件,使用默认凭据登录到sonicwall设备,通过多部分数据表单导入文件,重新启动sonicwall,然后再次登录并正确更改共享密钥。 For security reasons, I can't post the code here, but I can explain the problem with a much simpler example. 出于安全原因,我不能在这里发布代码,但我可以用一个更简单的例子来解释这个问题。 Previously, the code was using urllib and urllib2 to process http requests, but then I discovered the requests module when I had to re-write the script to include csrfTokens. 以前,代码使用urllib和urllib2来处理http请求,但是当我不得不重新编写脚本以包含csrfTokens时,我发现了请求模块。

Long story short, the script works amazing when called by the python interpreter. 长话短说,这个脚本在python解释器调用时效果很好。 However, when trying to compile it with pyinstaller, I get a series of errors now that I've switched to requests instead of the urllibs. 但是,当尝试使用pyinstaller编译它时,我得到了一系列错误,因为我已切换到请求而不是urllib。

Some more background: 更多背景:

Windows 7 - Python2.7.9
pip 6.0.8 from C:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg (python 2.7)
pip freeze output:
pyinstaller==2.1.1.dev0
pywin32==219
requests==2.5.3

As an example, I'll give you some code that bombs out, a simple request to google. 作为一个例子,我会给你一些炸弹的代码,一个简单的谷歌请求。

#!/usr/bin/python
import requests 
r = requests.get('https://google.com') 
print(r.text)

The above code works for a simple request when I call the file from python, but when I compile it, I get this: 当我从python调用文件时,上面的代码适用于一个简单的请求,但是当我编译它时,我得到这个:

(EDIT Having problems pasting output, here is the pastebin) pastebin (编辑粘贴输出有问题,这里是pastebin) pastebin

It creates a windows executable, but this is the following error when I try to run it: 它创建一个Windows可执行文件,但是当我尝试运行它时出现以下错误:

NOTE I did install the ms c++ 2008 redistributable to help clear up the msvcr90.dll, but I still get the above requests.packages.chardet.sys error. 注意我确实安装了ms c ++ 2008可再发行组件以帮助清除msvcr90.dll,但我仍然得到上述requests.packages.chardet.sys错误。

I've tried everything I can think of, installing chardet, installing chardet2, installing cchardet, forcing earlier versions of pyinstaller and requests incrementally. 我已经尝试了我能想到的一切,安装chardet,安装chardet2,安装cchardet,强制更新pyinstaller的早期版本和请求。 Scrapping pip and manually installing pyinstaler and requests. 废弃pip并手动安装pyinstaler和请求。 I'm at my wits end with things to try, I don't quite get the error on hand here. 我在我的智慧结束时要尝试一些事情,我不太明白这里的错误。 requests.packages.chardet exists on the system. requests.packages.chardet存在于系统中。 I also have C:\\Python27 in my windows PATH as I can call python from any directory. 我在Windows PATH中也有C:\\ Python27,因为我可以从任何目录调用python。

If you need more information, please let me know. 如果您需要更多信息,请告诉我。 I tried to be as thorough with the errors as possible and what I have installed, but I can provide more if needed. 我试图尽可能彻底地解决错误和我已安装的错误,但如果需要我可以提供更多错误。

ALSO This issue ONLY appears to be happening when I try to compile when I import requests. 此外,当我在导入请求时尝试编译时,此问题似乎正在发生。 creating test scripts, beautifulsoup, urllib/2, etc all compile a valid windows exe that runs properly. 创建测试脚本,beautifulsoup,urllib / 2等都编译一个正常运行的有效Windows exe。

I don't have a solution for this yet, but this is caused by latest changes in requests module (versions 2.5.2 & 2.5.3). 我还没有解决方案,但这是由requests模块(版本2.5.2和2.5.3)的最新更改引起的。

For now you can use version 2.5.1 until PyInstaller will have suitable hook for solving this issue. 现在你可以使用版本2.5.1,直到PyInstaller有合适的钩子来解决这个问题。

I cannot really explain the issue, but it looks like there's some kind of collision between PyInstaller import hooks and some latest additions to requests ( VendorAlias ). 我无法解释这个问题,但看起来PyInstaller导入钩子和一些最新的requestsVendorAlias )之间存在某种冲突。

Good news, this has been fixed in the latest version of requests 好消息,这已在最新版本的requests得到修复

pip install requests --upgrade

Easy. 简单。

As m1keil says, the problem is between PyInstaller import hooks and the new load_module features of requests, implemented in the requests.packages.__init__.py source file. 正如m1keil所说,问题出在PyInstaller导入钩子和请求的新load_module功能之间,在requests.packages.__init__.py源文件中实现。

Debugging this file you can see that any import of the requests package is passing through the load_module function. 调试此文件可以看到请求包的任何导入都通过load_module函数传递。 This includes the python standard packages. 这包括python标准包。 This the reason of the error. 这就是错误的原因。

My workaround consists in editing the requests.packages.__init__.py (inside the virtualenv folder) of the version 2.5.3 and adding this piece of code at the very beginning of the load_module function: 我的解决方法在于编辑requests.packages.__init__.py版本2.5.3(在virtualenv中文件夹内),并在load_module函数的最开始加入这一段代码:

    print "Requested name = ", name #Comment this line when it works
    direct_loaded_packages = ('sys', 'errno','logging','warnings'
            ,'socket','os','re','time','hashlib','base64'
            ,'time','collections','datetime','io', 'argparse'
            ,'codecs', 'Queue', 'zlib', 'ssl', 'operator'
            ,'types','platform','struct', 'StringIO','httplib'
            ,'simplejson','cookielib','urllib','urlparse'
            ,'urllib2','Cookie','http','binascii','certifi'
            ,'uuid','json','threading','dummy_thread','email'
            ,'email.utils','operator','mimetypes')    


    new_name = ''
    #Package with three directory deep 
    if '.'.join(name.split('.')[3:]) in direct_loaded_packages:
        new_name = '.'.join(name.split('.')[3:])
    #Package with four directory deep
    elif '.'.join(name.split('.')[4:]) in direct_loaded_packages:
        new_name = '.'.join(name.split('.')[4:])
    #Package with five directory deep
    elif '.'.join(name.split('.')[5:]) in direct_loaded_packages:
        new_name = '.'.join(name.split('.')[5:])

    if new_name != '':
        module = __import__(new_name)
        return module 

By test&error and grepping I have build the list of packages that must be directly loaded without passing by the load_module function. 通过测试和错误以及grepping,我构建了必须直接加载而不通过load_module函数的包列表。

Isn't elegant but it works. 不优雅,但它的工作原理。 I've tested a more elegant solution but I haven't succeeded. 我已经测试了一个更优雅的解决方案,但我还没有成功。

运行我的python可执行文件时出现了一些错误(例如“没有模块命名请求”,“没有名为cv2的模块”,...)我通过升级setuptools解决了这个问题:

pip install setuptools --upgrade

I think the trouble is realted to the Setuptools version, so try to use an older version and test it again. 我认为Setuptools版本存在问题,因此请尝试使用旧版本并再次测试。 In my case it works! 就我而言,它有效!

>> pip uninstall setuptools
>> pip install setuptools==12.0.5

I guess the trouble is related with the interpretation of a positional argument 我猜这个麻烦与位置论证的解释有关

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM