愚人节填坑计【python3.7导入gevent模块报错的解决方案】

2,206 阅读2分钟

问题描述

服务通过Flask + Gunicorn + Gevent,升级Python版本至3.7以后,运行报错,具体报错如下:

/usr/local/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
  return f(*args, **kwds)
/usr/local/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
  return f(*args, **kwds)
/usr/local/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 144 from C header, got 152 from PyObject
  return f(*args, **kwds)

问题分析

Python3.7greenlet版本不兼容,但项目没有直接使用greenlet的地方,由于Gevent底层基于greenlet实现,故大致定位到原因至Gevent包模块

文本解决

更新Gevent,使用非二进制的包重新安装Gevent以及它的依赖 [1],问题解决

pip3 install -U --force-reinstall --no-binary :all: gevent

附上参数说明

-U, --upgrade
Upgrade all specified packages to the newest available version. The handling of dependencies depends on the upgrade-strategy used.
--force-reinstall
Reinstall all packages even if they are already up-to-date.
--no-binary <format_control>
Do not use binary packages. Can be supplied multiple times, and each time adds to the existing value. Accepts either :all: to disable all binary packages, :none: to empty the set, or one or more package names with commas between them. Note that some packages are tricky to compile and may fail to install when this option is used on them.

注:实验环境gevent==20.5.0

问题深入

官方已经修复该BUG,只需要升级Gevent20.9.0即可 [2],具体官方解读如下

Ok, gevent wheels are built with greenlet 0.4.13. Something must have changed in the ABI of greenlet 0.4.14 (which was released last night).

As you discovered, building gevent from source should fix the issue, and I would expect installing greenlet==0.4.13 would as well.
Please do not add unrelated comments to closed issues. Open a new issue if you have, well, a new issue.

gevent 20.9.0 was released at the same time greenlet 0.4.17 was un-yanked. On Python 3.7 and higher, gevent 20.9.0 is required to use (a standard build of) greenlet 0.4.17.

gevent 1.5 doesn't support Python 3.8.

大致意思可以按上面的方式二进制编译安装升级解决问题,或将Gevent升级至20.9.0解决问题,对比校验后我采用了第二种方式

注:升级后环境gevent==20.9.0、greenlet==1.0.0

参考文献

我是三土,感谢各位朋友:点赞、收藏和评论,我们下期再见!