Skip to content

Commit 14fd99e

Browse files
committed
fix: msgpack bug fix
1 parent 0d958fb commit 14fd99e

7 files changed

Lines changed: 74 additions & 30 deletions

File tree

packages/polywrap-msgpack/polywrap_msgpack/__init__.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,39 @@
88
custom extension types defined by wrap standard
99
"""
1010
from enum import Enum
11-
from typing import Any, Dict, List, Set, cast
11+
from typing import Any, Dict, List, Set, Tuple, cast
1212

1313
import msgpack
14+
from msgpack.ext import ExtType
1415
from msgpack.exceptions import UnpackValueError
1516

17+
from .generic_map import GenericMap
18+
1619

1720
class ExtensionTypes(Enum):
1821
"""Wrap msgpack extension types."""
1922

2023
GENERIC_MAP = 1
2124

2225

23-
def ext_hook(code: int, data: bytes) -> Any:
26+
def encode_ext_hook(obj: Any) -> ExtType:
27+
"""Extension hook for extending the msgpack supported types.
28+
29+
Args:
30+
obj (Any): object to be encoded
31+
32+
Raises:
33+
TypeError: when given object is not supported
34+
35+
Returns:
36+
Tuple[int, bytes]: extension type code and payload
37+
"""
38+
if isinstance(obj, GenericMap):
39+
return ExtType(ExtensionTypes.GENERIC_MAP.value, msgpack_encode(obj._map)) # type: ignore
40+
raise TypeError(f"Object of type {type(obj)} is not supported")
41+
42+
43+
def decode_ext_hook(code: int, data: bytes) -> Any:
2444
"""Extension hook for extending the msgpack supported types.
2545
2646
Args:
@@ -34,7 +54,7 @@ def ext_hook(code: int, data: bytes) -> Any:
3454
Any: decoded object
3555
"""
3656
if code == ExtensionTypes.GENERIC_MAP.value:
37-
return msgpack_decode(data)
57+
return GenericMap(msgpack_decode(data))
3858
raise UnpackValueError("Invalid Extention type")
3959

4060

@@ -50,6 +70,8 @@ def sanitize(value: Any) -> Any:
5070
Returns:
5171
Any: msgpack compatible sanitized value
5272
"""
73+
if isinstance(value, GenericMap):
74+
return cast(Any, value)
5375
if isinstance(value, dict):
5476
dictionary: Dict[Any, Any] = value
5577
for key, val in dictionary.items():
@@ -59,7 +81,7 @@ def sanitize(value: Any) -> Any:
5981
array: List[Any] = value
6082
return [sanitize(a) for a in array]
6183
if isinstance(value, tuple):
62-
array: List[Any] = list(value) # type: ignore partially unknown
84+
array: List[Any] = list(cast(Tuple[Any], value))
6385
return sanitize(array)
6486
if isinstance(value, set):
6587
set_val: Set[Any] = value
@@ -87,7 +109,7 @@ def msgpack_encode(value: Any) -> bytes:
87109
bytes: encoded msgpack value
88110
"""
89111
sanitized = sanitize(value)
90-
return msgpack.packb(sanitized)
112+
return msgpack.packb(sanitized, default=encode_ext_hook, use_bin_type=True)
91113

92114

93115
def msgpack_decode(val: bytes) -> Any:
@@ -99,4 +121,4 @@ def msgpack_decode(val: bytes) -> Any:
99121
Returns:
100122
Any: python object
101123
"""
102-
return msgpack.unpackb(val, ext_hook=ext_hook)
124+
return msgpack.unpackb(val, ext_hook=decode_ext_hook)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import Dict, MutableMapping, TypeVar
2+
3+
K = TypeVar("K")
4+
V = TypeVar("V")
5+
6+
7+
class GenericMap(MutableMapping[K, V]):
8+
_map: Dict[K, V]
9+
10+
def __init__(self, map: Dict[K, V]):
11+
self._map = dict(map)
12+
13+
def __getitem__(self, key: K) -> V:
14+
return self._map[key]
15+
16+
def __setitem__(self, key: K, value: V) -> None:
17+
self._map[key] = value
18+
19+
def __delitem__(self, key: K) -> None:
20+
del self._map[key]
21+
22+
def __iter__(self):
23+
return iter(self._map)
24+
25+
def __len__(self) -> int:
26+
return len(self._map)
27+
28+
def __repr__(self) -> str:
29+
return f"GenericMap({repr(self._map)})"

packages/polywrap-msgpack/tests/test_msgpack.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import Any, Dict, List, Set, Tuple
33

44
from polywrap_msgpack import msgpack_decode, msgpack_encode, sanitize
5+
from polywrap_msgpack.generic_map import GenericMap
56
from tests.conftest import DataClassObject, DataClassObjectWithSlots, Example
67

78
# ENCODING AND DECODING
@@ -147,16 +148,10 @@ def test_sanitize_set_returns_list_with_all_items_of_the_set(
147148
set1: Set[Any], set2: Set[Any]
148149
):
149150
sanitized = sanitize(set1)
150-
# r: List[bool] = []
151151
assert list(set1) == sanitized
152-
# [r.append(True) if item in sanitized else r.append(False) for item in set1]
153-
# assert False not in r
154152

155153
sanitized = sanitize(set2)
156154
assert list(set2) == sanitized
157-
# r = []
158-
# [r.append(True) if item in sanitized else r.append(False) for item in set2]
159-
# assert False not in r
160155

161156

162157
def test_sanitize_set_returns_list_of_same_length(set1: Set[Any]):
@@ -261,3 +256,9 @@ def test_sanitize_dict_of_dataclass_objects_with_slots_returns_list_of_dicts(
261256
"firstKey": dataclass_object_with_slots1_sanitized,
262257
"secondKey": dataclass_object_with_slots2_sanitized,
263258
}
259+
260+
261+
def test_encode_generic_map():
262+
generic_map = GenericMap({"firstKey": "firstValue", "secondKey": "secondValue"})
263+
assert sanitize(generic_map) == generic_map
264+
assert msgpack_decode(msgpack_encode(generic_map)) == generic_map

packages/polywrap-msgpack/typings/msgpack/__init__.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ def pack(o: Any, stream: IOBase, **kwargs: Dict[Any, Any]) -> IOBase: # -> None
2424
"""
2525
...
2626

27-
def packb(o: Any, **kwargs: Dict[Any, Any]) -> bytes: # -> None:
27+
def packb(o: Any, default: Optional[Callable[[Any], ExtType]], use_bin_type: bool, **kwargs: Dict[Any, Any]) -> bytes: # -> None:
2828
"""
2929
Pack object `o` and return packed bytes
3030
3131
See :class:`Packer` for options.
3232
"""
3333
...
3434

35-
def unpack(stream: IOBase, **kwargs: Dict[Any, Any]) -> Any:
35+
def unpack(stream: IOBase,**kwargs: Dict[Any, Any]) -> Any:
3636
"""
3737
Unpack an object from `stream`.
3838

packages/polywrap-plugin/polywrap_plugin/wrapper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ async def invoke(
3535

3636
args: Union[Dict[str, Any], bytes] = options.args or {}
3737
decoded_args: Dict[str, Any] = (
38-
msgpack_decode(args) if isinstance(args, bytes) else args
38+
msgpack_decode(args) if isinstance(args, (bytes, bytearray)) else args
3939
)
4040

4141
result = cast(

packages/polywrap-uri-resolvers/polywrap_uri_resolvers/abc/uri_resolver_aggregator.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,9 @@ async def try_resolve_uri_with_resolvers(
4646

4747
for resolver in resolvers:
4848
result = await resolver.try_resolve_uri(uri, client, sub_context)
49-
50-
if result.is_ok():
51-
return result
52-
53-
if not result.is_ok():
54-
step = IUriResolutionStep(
55-
source_uri=uri,
56-
result=result,
57-
sub_history=sub_context.get_history(),
58-
description=self.get_step_description(),
59-
)
60-
resolution_context.track_step(step)
61-
49+
if result.is_ok() and not (
50+
isinstance(result.unwrap(), Uri) and result.unwrap() == uri
51+
):
6252
return result
6353

6454
result = Ok(uri)

packages/polywrap-wasm/polywrap_wasm/imports.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,10 @@ def wrap_subinvoke(
200200
result = unfuture_result.result()
201201

202202
if result.is_ok():
203-
result = cast(Ok[bytes], result)
204-
state.subinvoke["result"] = result.unwrap()
203+
if isinstance(result.unwrap(), (bytes, bytearray)):
204+
state.subinvoke["result"] = result.unwrap()
205+
return True
206+
state.subinvoke["result"] = msgpack_encode(result.unwrap())
205207
return True
206208
elif result.is_err():
207209
error = cast(Err, result).unwrap_err()

0 commit comments

Comments
 (0)