如何说服Kombu使用simplejson而不是json模块



有没有一个好的方法可以说服Celery+Kombu使用simplejson而不是标准库的json模块?

我在:

tact@tact_pub_api:/app$ python3.10 -m pip list -v | egrep -i 'celery|kombu'
celery                  5.2.3       /usr/local/lib/python3.10/site-packages pip
kombu                   5.2.4       /usr/local/lib/python3.10/site-packages pip
tact@tact_pub_api:/app$ python2.7 -m pip list -v | egrep -i 'celery|kombu'
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
celery                        3.1.26.post2 /usr/local/lib/python2.7/dist-packages pip
kombu                         3.0.37       /usr/local/lib/python2.7/dist-packages pip

我得到了一个回溯:

Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/kombu/serialization.py", line 39, in _reraise_errors
yield
File "/usr/local/lib/python3.10/site-packages/kombu/serialization.py", line 210, in dumps
payload = encoder(data)
File "/usr/local/lib/python3.10/site-packages/kombu/utils/json.py", line 68, in dumps
return _dumps(s, cls=cls or _default_encoder,
File "/usr/local/lib/python3.10/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/local/lib/python3.10/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/lib/python3.10/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/local/lib/python3.10/site-packages/kombu/utils/json.py", line 58, in default
return super().default(o)
File "/usr/local/lib/python3.10/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type bytes is not JSON serializable

我听到的是,这是由于最近版本的Kombu使用了python标准库的json模块,而不是pypi的simplejson模块(https://docs.celeryq.dev/projects/kombu/en/stable/changelog.html#rc1)。显然,标准库的";json";模块不能(反(序列化字节,但pypi的";simplejson";可以Celery+Kombu的旧版本默认使用simplejson。

例如:

>>> import json
>>> s = b'abc'
>>> json.dumps(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.10/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/usr/local/lib/python3.10/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/local/lib/python3.10/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/local/lib/python3.10/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type bytes is not JSON serializable

我的团队/项目可能希望也可能不希望最终转向json模块的序列化,但就目前而言,为了互操作性,使用simplejson似乎最有意义。

(这是一个更大的CPython 2.7->CPython 3.10端口的一部分;我只想先在3.10上工作,然后担心更新依赖关系以使其现代化。现在,客户端和服务器使用不同版本的芹菜和康普。(

谢谢!

也许您可以在导入代码后,从代码中对kombu进行monkeypatch,使用simplejson而不是json。从上面的回溯来看:

File "/usr/local/lib/python3.10/site-packages/kombu/serialization.py", line 210, in dumps
payload = encoder(data)

如果encoder是全局名称,则将kombu.encoder重新绑定到使用simplejson的函数。如果不是,但dumps是,则重新绑定kombu.dumps

或者,这对

File "/usr/local/lib/python3.10/site-packages/kombu/utils/json.py", line 68, in dumps
return _dumps(s, cls=cls or _default_encoder,

建议您可以将kombu.utils.json.cls设置为None以外的值来更改行为。查看kombu文档或阅读模块代码。

最新更新