Проблемы совместимости python2 python3
Два uServices обмениваются данными через очередь сообщений (RabbitMQ). Данные кодируются с использованием пакета сообщений.
У меня есть следующие сценарии:
- python3 -> python3: работает нормально
- python2 -> python3: проблемы с кодировкой
Кодирование выполняется с помощью:
umsgpack.packb(data)
Декодирование с помощью:
umsgpack.unpackb(body)
При кодировании и декодировании в python3 я получаю:
data={'sender': 'producer-big-red-tiger', 'json': '{"msg": "hi"}', 'servicename': 'echo', 'command': 'run'}
При кодировании в python2 и декодировании в python3 я получаю:
data={b'command': b'run', b'json': b'{"msg": ""}', b'servicename': b'echo', b'sender': b'bla-blah'}
Почему данные не "полностью" декодируются? Что я должен сделать на отправителе / получателе для достижения совместимости между python2 и python3?
1 ответ
Посмотрите на раздел "Примечания" README из msgpack-python;
На данный момент msgpack может различать строковый и двоичный типы. Но это не так, как в Python 2. В Python 2 добавлена строка Юникода. Но msgpack переименовал raw в str и добавил тип bin. Это потому, что сохраняйте совместимость с данными, созданными старыми библиотеками. raw был использован для текста больше, чем двоичный.
В настоящее время, хотя msgpack-python поддерживает новый тип bin, настройка по умолчанию не использует его и декодирует raw как байты вместо unicode (str в Python 3).
Вы можете изменить это, используя опцию use_bin_type=True в Packer и опцию encoding="utf-8" в Unpacker.
>>> import msgpack
>>> packed = msgpack.packb([b'spam', u'egg'], use_bin_type=True)
>>> msgpack.unpackb(packed, encoding='utf-8')
['spam', u'egg']