fix(signarl): wrong msgpack encode
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from typing import Any, get_origin
|
from enum import Enum
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from pydantic import (
|
from pydantic import (
|
||||||
BaseModel,
|
BaseModel,
|
||||||
|
BeforeValidator,
|
||||||
ConfigDict,
|
ConfigDict,
|
||||||
Field,
|
Field,
|
||||||
TypeAdapter,
|
TypeAdapter,
|
||||||
@@ -17,22 +19,56 @@ def serialize_to_list(value: BaseModel) -> list[Any]:
|
|||||||
data = []
|
data = []
|
||||||
for field, info in value.__class__.model_fields.items():
|
for field, info in value.__class__.model_fields.items():
|
||||||
v = getattr(value, field)
|
v = getattr(value, field)
|
||||||
anno = get_origin(info.annotation)
|
typ = v.__class__
|
||||||
if anno and issubclass(anno, BaseModel):
|
if issubclass(typ, BaseModel):
|
||||||
data.append(serialize_to_list(v))
|
data.append(serialize_to_list(v))
|
||||||
elif anno and issubclass(anno, list):
|
elif issubclass(typ, list):
|
||||||
data.append(
|
data.append(
|
||||||
TypeAdapter(
|
TypeAdapter(
|
||||||
info.annotation, config=ConfigDict(arbitrary_types_allowed=True)
|
info.annotation, config=ConfigDict(arbitrary_types_allowed=True)
|
||||||
).dump_python(v)
|
).dump_python(v)
|
||||||
)
|
)
|
||||||
elif isinstance(v, datetime.datetime):
|
elif issubclass(typ, datetime.datetime):
|
||||||
data.append([v, 0])
|
data.append([v, 0])
|
||||||
|
elif issubclass(typ, Enum):
|
||||||
|
list_ = list(typ)
|
||||||
|
data.append(list_.index(v) if v in list_ else v.value)
|
||||||
else:
|
else:
|
||||||
data.append(v)
|
data.append(v)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _by_index(v: Any, class_: type[Enum]):
|
||||||
|
enum_list = list(class_)
|
||||||
|
if not isinstance(v, int):
|
||||||
|
return v
|
||||||
|
if 0 <= v < len(enum_list):
|
||||||
|
return enum_list[v]
|
||||||
|
raise ValueError(
|
||||||
|
f"Value {v} is out of range for enum "
|
||||||
|
f"{class_.__name__} with {len(enum_list)} items"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def EnumByIndex(enum_class: type[Enum]) -> BeforeValidator:
|
||||||
|
return BeforeValidator(lambda v: _by_index(v, enum_class))
|
||||||
|
|
||||||
|
|
||||||
|
def msgpack_union(v):
|
||||||
|
data = v[1]
|
||||||
|
data.append(v[0])
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def msgpack_union_dump(v: BaseModel) -> list[Any]:
|
||||||
|
_type = getattr(v, "type", None)
|
||||||
|
if _type is None:
|
||||||
|
raise ValueError(
|
||||||
|
f"Model {v.__class__.__name__} does not have a '_type' attribute"
|
||||||
|
)
|
||||||
|
return [_type, serialize_to_list(v)]
|
||||||
|
|
||||||
|
|
||||||
class MessagePackArrayModel(BaseModel):
|
class MessagePackArrayModel(BaseModel):
|
||||||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class MsgpackProtocol:
|
|||||||
result_kind = 2
|
result_kind = 2
|
||||||
if packet.error:
|
if packet.error:
|
||||||
result_kind = 1
|
result_kind = 1
|
||||||
elif packet.result is None:
|
elif packet.result is not None:
|
||||||
result_kind = 3
|
result_kind = 3
|
||||||
payload.extend(
|
payload.extend(
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ class APIMod:
|
|||||||
@property
|
@property
|
||||||
def acronym(self) -> str: ...
|
def acronym(self) -> str: ...
|
||||||
@property
|
@property
|
||||||
def settings(self) -> str: ...
|
def settings(self) -> dict[str, Any]: ...
|
||||||
|
|
||||||
def encode(obj: Any) -> bytes: ...
|
def encode(obj: Any) -> bytes: ...
|
||||||
def decode(data: bytes) -> Any: ...
|
def decode(data: bytes) -> Any: ...
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ pub fn read_object(
|
|||||||
match rmp::decode::read_marker(cursor) {
|
match rmp::decode::read_marker(cursor) {
|
||||||
Ok(marker) => match marker {
|
Ok(marker) => match marker {
|
||||||
rmp::Marker::Null => Ok(py.None()),
|
rmp::Marker::Null => Ok(py.None()),
|
||||||
|
rmp::Marker::True => Ok(true.into_py_any(py)?),
|
||||||
|
rmp::Marker::False => Ok(false.into_py_any(py)?),
|
||||||
rmp::Marker::FixPos(val) => Ok(val.into_pyobject(py)?.into_any().unbind()),
|
rmp::Marker::FixPos(val) => Ok(val.into_pyobject(py)?.into_any().unbind()),
|
||||||
rmp::Marker::FixNeg(val) => Ok(val.into_pyobject(py)?.into_any().unbind()),
|
rmp::Marker::FixNeg(val) => Ok(val.into_pyobject(py)?.into_any().unbind()),
|
||||||
rmp::Marker::U8 => {
|
rmp::Marker::U8 => {
|
||||||
@@ -86,8 +88,6 @@ pub fn read_object(
|
|||||||
cursor.read_exact(&mut data).map_err(to_py_err)?;
|
cursor.read_exact(&mut data).map_err(to_py_err)?;
|
||||||
Ok(data.into_pyobject(py)?.into_any().unbind())
|
Ok(data.into_pyobject(py)?.into_any().unbind())
|
||||||
}
|
}
|
||||||
rmp::Marker::True => Ok(true.into_py_any(py)?),
|
|
||||||
rmp::Marker::False => Ok(false.into_py_any(py)?),
|
|
||||||
rmp::Marker::FixStr(len) => read_string(py, cursor, len as u32),
|
rmp::Marker::FixStr(len) => read_string(py, cursor, len as u32),
|
||||||
rmp::Marker::Str8 => {
|
rmp::Marker::Str8 => {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
|
|||||||
@@ -110,12 +110,12 @@ pub fn write_object(buf: &mut Vec<u8>, obj: &Bound<'_, PyAny>) {
|
|||||||
write_list(buf, list);
|
write_list(buf, list);
|
||||||
} else if let Ok(string) = obj.downcast::<PyString>() {
|
} else if let Ok(string) = obj.downcast::<PyString>() {
|
||||||
write_string(buf, string);
|
write_string(buf, string);
|
||||||
} else if let Ok(integer) = obj.downcast::<PyInt>() {
|
|
||||||
write_integer(buf, integer);
|
|
||||||
} else if let Ok(float) = obj.downcast::<PyFloat>() {
|
|
||||||
write_float(buf, float);
|
|
||||||
} else if let Ok(boolean) = obj.downcast::<PyBool>() {
|
} else if let Ok(boolean) = obj.downcast::<PyBool>() {
|
||||||
write_bool(buf, boolean);
|
write_bool(buf, boolean);
|
||||||
|
} else if let Ok(float) = obj.downcast::<PyFloat>() {
|
||||||
|
write_float(buf, float);
|
||||||
|
} else if let Ok(integer) = obj.downcast::<PyInt>() {
|
||||||
|
write_integer(buf, integer);
|
||||||
} else if let Ok(bytes) = obj.downcast::<PyBytes>() {
|
} else if let Ok(bytes) = obj.downcast::<PyBytes>() {
|
||||||
write_bin(buf, bytes);
|
write_bin(buf, bytes);
|
||||||
} else if let Ok(dict) = obj.downcast::<PyDict>() {
|
} else if let Ok(dict) = obj.downcast::<PyDict>() {
|
||||||
|
|||||||
Reference in New Issue
Block a user