Skip to content
Snippets Groups Projects
Commit 5b2cbd58 authored by Tulir Asokan's avatar Tulir Asokan :cat2:
Browse files

Fix reading thrift maps on Python 3.7 and below

CPython 3.7 and below had a bug where dict comprehension values are
evaluated before the keys, which meant the bridge parsed the binary
data in the wrong order.

Fixes #127
Might fix #130
parent a4f3e31c
No related branches found
No related tags found
No related merge requests found
......@@ -201,6 +201,13 @@ class ThriftReader(io.BytesIO):
else:
self.read_val(type)
def _read_kv(self, key_type: RecursiveType, value_type: RecursiveType, field_path: str,
index: int) -> Tuple[Any, Any]:
key = self.read_val_recursive(key_type, field_path=f"{field_path}[{index}::key]")
value_path = repr(key) if isinstance(key, (str, bytes, int)) else f"{index}::value"
value = self.read_val_recursive(value_type, field_path=f"{field_path}[{value_path}]")
return key, value
def read_val_recursive(self, rtype: RecursiveType, field_path: str = "root") -> Any:
"""
Read any type of value from the buffer.
......@@ -227,11 +234,8 @@ class ThriftReader(io.BytesIO):
elif value_type != rtype.value_type.type:
raise ValueError(f"Unexpected value type at {field_path}: "
f"expected {rtype.value_type.type.name}, got {value_type.name}")
return {
self.read_val_recursive(rtype.key_type, field_path=f"{field_path}[{i}.key]"):
self.read_val_recursive(rtype.value_type, field_path=f"{field_path}[{i}.val]")
for i in range(length)
}
return dict(self._read_kv(rtype.key_type, rtype.value_type, field_path, index)
for index in range(length))
elif rtype.type in (TType.LIST, TType.SET):
item_type, length = self.read_list_header()
if item_type != rtype.item_type.type:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment