如何修复Google App Engine dev_appserver.py watcher_ignore_re参数JSON不可序列化错误
首先我要说明,我已经试过了同类问题下的所有公开答案,都没有解决问题,且该问题已经存在较长时间。
问题详情
我需要运行dev_appserver.py,同时将特定文件添加到文件监听器的忽略列表中;skip_files参数不符合需求,因为该参数会让服务器完全不读取对应文件。
不带--watcher_ignore_re参数运行dev_appserver.py时,除文件监听功能外所有功能正常运行;但带上该参数就会报如下错误:
INFO 2021-11-02 13:54:50,100 devappserver2.py:309] Skipping SDK update check. Traceback (most recent call last): File "/home/USERNAME/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 109, in <module> _run_file(__file__, globals()) File "/home/USERNAME/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 103, in _run_file _execfile(_PATHS.script_file(script_name), globals_) File "/home/USERNAME/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 83, in _execfile execfile(fn, scope) File "/home/USERNAME/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 635, in <module> main() File "/home/USERNAME/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 623, in main dev_server.start(options) File "/home/USERNAME/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 356, in start java_major_version=self.java_major_version File "/home/USERNAME/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/metrics.py", line 185, in Start self._cmd_args = json.dumps(vars(cmd_args)) if cmd_args else None File "/usr/lib/python2.7/json/__init__.py", line 244, in dumps return _default_encoder.encode(obj) File "/usr/lib/python2.7/json/encoder.py", line 207, in encode chunks = self.iterencode(o, _one_shot=True) File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode return _iterencode(o, 0) File "/usr/lib/python2.7/json/encoder.py", line 184, in default raise TypeError(repr(o) + " is not JSON serializable") TypeError: <_sre.SRE_Pattern object at 0x7f720c625240> is not JSON serializable
我尝试过切换不同版本,均未成功:
- GCloud 361.0.0/362.0.0/357.0.0/240.0.0/220.0.0/200.0.0
- Python 2.7.18/3.9.7
我也试过为watcher参数设置不同的字符串值:
""''".css""*.css"".*\css"'.css''*.css''.*\css'- 其他同类写法
因此我确认问题大概率不是出在参数字符串的写法上,切换不同版本也未解决问题。
我的同事在MacOS系统上使用我上述列出的不同版本都没有遇到这个问题,我目前使用Arch Linux,但在自己的Mac设备上也遇到了完全相同的问题。
我还已经在~/.zshrc文件中添加了export CLOUDSDK_PYTHON=python2.7配置。
解决方案
这个报错是GAE SDK内置的使用情况上报模块的已知bug:上报逻辑会尝试把所有命令行参数序列化为JSON,但--watcher_ignore_re参数会被预先解析为正则表达式对象,Python标准JSON库不支持直接序列化正则对象,因此触发报错。
可按优先级选择以下方案解决:
- 无修改快速绕过(推荐)
启动命令追加--disable_usage_reporting参数关闭使用情况上报即可,完全不影响dev_appserver的核心功能和文件监听逻辑。示例命令:
dev_appserver.py --watcher_ignore_re=".*\.css$" --disable_usage_reporting 你的应用目录
- 保留上报功能的源码修复
如果需要保留使用情况上报功能,可以直接修改SDK源码修复bug:
找到报错路径下的google/appengine/tools/devappserver2/metrics.py文件,定位到self._cmd_args = json.dumps(vars(cmd_args)) if cmd_args else None这一行,替换为以下代码:
import re args_dict = vars(cmd_args) for k, v in args_dict.items(): if isinstance(v, re._pattern_type if hasattr(re, '_pattern_type') else re.Pattern): args_dict[k] = v.pattern self._cmd_args = json.dumps(args_dict) if cmd_args else None
修改后重启服务即可正常运行。
3. 补充说明
正则匹配规则需要符合Python re模块语法,比如要忽略所有.css后缀的文件,推荐写为.*\.css$,避免误匹配路径中包含css字样的其他文件。
内容的提问来源于stack exchange,提问作者Sebastien De Varennes

