在运行Flask-SocketIO应用时出现AttributeError: module 'dns.rdtypes' has no attribute 'ANY'

起因

16号的时候,我对gglu的客户端代码做了一点修改,准备部署到render上。但是不一会就跟我说在运行我的代码时出现问题,部署失败,render日志那边的报错如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Jan 16 09:29:20 AM  Traceback (most recent call last):
Jan 16 09:29:20 AM File "/app/website/main.py", line 2, in <module>
Jan 16 09:29:20 AM from flask_socketio import SocketIO, emit, join_room, leave_room, disconnect
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/flask_socketio/__init__.py", line 9, in <module>
Jan 16 09:29:20 AM from socketio import socketio_manage # noqa: F401
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/socketio/__init__.py", line 9, in <module>
Jan 16 09:29:20 AM from .zmq_manager import ZmqManager
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/socketio/zmq_manager.py", line 5, in <module>
Jan 16 09:29:20 AM import eventlet.green.zmq as zmq
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/__init__.py", line 17, in <module>
Jan 16 09:29:20 AM from eventlet import convenience
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/convenience.py", line 7, in <module>
Jan 16 09:29:20 AM from eventlet.green import socket
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/green/socket.py", line 21, in <module>
Jan 16 09:29:20 AM from eventlet.support import greendns
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/support/greendns.py", line 66, in <module>
Jan 16 09:29:20 AM setattr(dns, pkg, import_patched('dns.' + pkg))
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/support/greendns.py", line 61, in import_patched
Jan 16 09:29:20 AM return patcher.import_patched(module_name, **modules)
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/patcher.py", line 132, in import_patched
Jan 16 09:29:20 AM return inject(
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/patcher.py", line 109, in inject
Jan 16 09:29:20 AM module = __import__(module_name, {}, {}, module_name.split('.')[:-1])
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/dns/zone.py", line 86, in <module>
Jan 16 09:29:20 AM class Zone(dns.transaction.TransactionManager):
Jan 16 09:29:20 AM File "/app/.heroku/python/lib/python3.10/site-packages/dns/zone.py", line 757, in Zone
Jan 16 09:29:20 AM ) -> dns.rdtypes.ANY.SOA.SOA:
Jan 16 09:29:20 AM AttributeError: module 'dns.rdtypes' has no attribute 'ANY'

可见从代码第二行导入时就开始报错了。我不理解,我甚至没动一点服务端代码,怎么一上来就报错呢,况且昨天(15号)晚上部署的时候都好好的。随后我想到了eventlet的monkey patch(病急乱投医(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Jan 16 12:21:18 PM  Traceback (most recent call last):
Jan 16 12:21:18 PM File "/app/website/main.py", line 1, in <module>
Jan 16 12:21:18 PM import eventlet
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/__init__.py", line 17, in <module>
Jan 16 12:21:18 PM from eventlet import convenience
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/convenience.py", line 7, in <module>
Jan 16 12:21:18 PM from eventlet.green import socket
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/green/socket.py", line 21, in <module>
Jan 16 12:21:18 PM from eventlet.support import greendns
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/support/greendns.py", line 66, in <module>
Jan 16 12:21:18 PM setattr(dns, pkg, import_patched('dns.' + pkg))
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/support/greendns.py", line 61, in import_patched
Jan 16 12:21:18 PM return patcher.import_patched(module_name, **modules)
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/patcher.py", line 132, in import_patched
Jan 16 12:21:18 PM return inject(
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/eventlet/patcher.py", line 109, in inject
Jan 16 12:21:18 PM module = __import__(module_name, {}, {}, module_name.split('.')[:-1])
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/dns/zone.py", line 86, in <module>
Jan 16 12:21:18 PM class Zone(dns.transaction.TransactionManager):
Jan 16 12:21:18 PM File "/app/.heroku/python/lib/python3.10/site-packages/dns/zone.py", line 757, in Zone
Jan 16 12:21:18 PM ) -> dns.rdtypes.ANY.SOA.SOA:
Jan 16 12:21:18 PM AttributeError: module 'dns.rdtypes' has no attribute 'ANY'

还是报相同的错。于是我脑子认真转了一下:从最开始的一行导入eventlet或者SocketIO就报错,而报错的部分是dns模块,dns模块是作为依赖安装的,但是我又没改代码。而且一样的代码,15号晚上能运行,16号早上就不能运行了。

于是我猜,有没有可能是版本问题?

翻了一下15号的日志,发现15号用的dnspython版本为2.2.1,16号的dnspython版本为2.3.0。再去dnspython官网看了看,确实更新了。那么简单来说,问题就在于dnspython更新后,不再兼容2.2.1,而eventlet和SocketIO都是用的2.2.1,所以这导致了问题的发生。

解决方法

很简单,修改requirements.txt,将dnspython的版本指定为2.2.1就ok了

1
dnspython==2.2.1

最终成功部署。


后来发现stackoverflow上也有这个问题的解决方法:https://stackoverflow.com/questions/75137717/eventlet-dns-python-attribute-error-module-dns-rdtypes-has-no-attribute-any?r=SearchResults


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!