Advanced types

This commit is contained in:
2026-07-28 05:43:29 +02:00
parent 5f2ff55d35
commit e884b7982f
4 changed files with 73 additions and 19 deletions
+57
View File
@@ -0,0 +1,57 @@
import struct
def pwp_number(fmt):
size = struct.calcsize(fmt)
def decorator(cls):
def __init__(self, value):
self.value = value
def to_com(self):
return struct.pack(fmt, self.value)
@classmethod
def from_com(cls, data, offset=0):
value = struct.unpack_from(fmt, data, offset)[0]
return cls(value), offset + size
cls.__init__ = __init__
cls.to_com = to_com
cls.from_com = from_com
return cls
return decorator
# Unsigned integers
@pwp_number("<B")
class u8: pass
@pwp_number("<H")
class u16: pass
@pwp_number("<I")
class u32: pass
@pwp_number("<Q")
class u64: pass
# Signed integers
@pwp_number("<b")
class i8: pass
@pwp_number("<h")
class i16: pass
@pwp_number("<i")
class i32: pass
@pwp_number("<q")
class i64: pass
# Floating point
@pwp_number("<f")
class f32: pass
@pwp_number("<d")
class f64: pass
+3 -2
View File
@@ -1,4 +1,5 @@
from pwp import pwp, pwp_enum
from adv_types import *
import units
@pwp_enum
@@ -18,8 +19,8 @@ class LogKind:
class Signal:
symbol: str
kind: units.Direction
confidence: float
size: float
confidence: f32
size: f64
price: units.USD
take_profit: units.USD
stop_loss: units.USD
+11 -16
View File
@@ -1,13 +1,11 @@
import struct
import typing
from typing import get_type_hints, get_origin, get_args
from adv_types import *
class PWPError(Exception):
pass
class uint8:
pass
def encode_value(value, typ) -> bytes:
origin = get_origin(typ)
@@ -23,7 +21,7 @@ def encode_value(value, typ) -> bytes:
return b"\x01" + encode_value(value, real_type)
# list[T]
if origin is list:
elif origin is list:
item_type = get_args(typ)[0]
out = len(value).to_bytes(4, "little")
@@ -62,10 +60,7 @@ def encode_value(value, typ) -> bytes:
if typ is bool:
return b"\x01" if value else b"\x00"
if typ is uint8:
return struct.pack("<B", value)
if hasattr(value, "to_com"):
if hasattr(typ, "to_com"):
return value.to_com()
raise PWPError(f"Unsupported type: {typ}")
@@ -147,12 +142,9 @@ def decode_value(data: bytes, offset: int, typ):
if typ is bool:
return data[offset] != 0, offset + 1
if typ is uint8:
return data[offset], offset + 1
# nested PWP class
if hasattr(typ, "from_com"):
return typ.from_com(data[offset:]), len(data)
return typ.from_com(data, offset)
raise PWPError(f"Unsupported type: {typ}")
@@ -189,20 +181,23 @@ def pwp(cls):
def pwp_enum(cls):
variants = {}
for index, (name, value) in enumerate(cls.__dict__.items()):
index = 0
for idx, (name, value) in enumerate(cls.__dict__.items()):
if isinstance(value, type) and value.__module__ == cls.__module__:
value.__annotations__ = {
"_id": uint8,
"_id": u8,
**getattr(value, "__annotations__", {})
}
value._id = index
value._id = u8(index)
value = pwp(value)
variants[index] = value
variants[idx] = value
setattr(cls, name, value)
index += 1
@classmethod
def from_com(enum_cls, data):
enum_id = data[0]
+2 -1
View File
@@ -1,4 +1,5 @@
from pwp import pwp, pwp_enum
from adv_types import *
@pwp
class Symbol:
@@ -6,7 +7,7 @@ class Symbol:
@pwp
class USD:
unit: float
unit: f64
@pwp_enum
class Direction: