M bare/encoder.py => bare/encoder.py +17 -12
@@ 207,7 207,6 @@ class Struct(ABC):
vals[field] = val.value
return cls(**vals)
-
@classmethod
def unpack(cls, data: typing.Union[typing.BinaryIO, bytes]):
"""
@@ 251,6 250,7 @@ class Struct(ABC):
output[name] = field.to_dict(value=val)
return output
+
class _ValidatedList(UserList):
def __init__(self, *args, instance: "Array" = None, **kwargs):
if instance is None:
@@ 284,9 284,7 @@ class Array(Field):
_length = 0 # zero means variable length
_default = None
- def __init__(
- self, type: typing.Type[Field] = None, length=0, values=None
- ):
+ def __init__(self, type: typing.Type[Field] = None, length=0, values=None):
if type is not None:
if inspect.isclass(type):
self._type = type()
@@ 342,14 340,16 @@ class Array(Field):
default = self._type._default
elif isinstance(self._type, Struct):
default = self._type.__class__()
- value.extend([default] * (self._length - len(value))) # pad with default values
+ value.extend(
+ [default] * (self._length - len(value))
+ ) # pad with default values
for item in value:
if isinstance(item, Field):
self._type._pack(fp, item.value)
else:
self._type._pack(fp, item)
- def _unpack(self, fp: typing.BinaryIO) -> 'Array':
+ def _unpack(self, fp: typing.BinaryIO) -> "Array":
if self._length == 0:
length = _read_varint(fp, signed=False)
else:
@@ 478,7 478,9 @@ class Map(Field):
key = self._keytype._unpack(fp)
value = self._valuetype.unpack(fp)
values[key] = value
- return self.__class__(keytype=self._keytype, valuetype=self._valuetype, value=values)
+ return self.__class__(
+ keytype=self._keytype, valuetype=self._valuetype, value=values
+ )
def to_dict(self, value=None):
if value is None:
@@ 528,19 530,20 @@ class Optional(Field):
if value is None:
value = self._value
if value is None:
- fp.write(struct.pack('<B', 0))
+ fp.write(struct.pack("<B", 0))
else:
- fp.write(struct.pack('<B', 1))
+ fp.write(struct.pack("<B", 1))
self._wrapped._pack(fp, value=value)
- def _unpack(self, fp: typing.BinaryIO) -> 'Optional':
+ def _unpack(self, fp: typing.BinaryIO) -> "Optional":
buf = fp.read(1)
- check = struct.unpack('<B', buf)[0]
+ check = struct.unpack("<B", buf)[0]
if check == 0:
return self.__class__(wrapped=self._wrapped, value=None)
value = self._wrapped._unpack(fp)
return self.__class__(wrapped=self._wrapped, value=value)
+
class Union(Field):
_members: typing.Tuple[typing.Union[Field, Struct], ...] = ()
@@ 557,7 560,9 @@ class Union(Field):
if value is not None:
valid, message = self.validate(value)
if not valid:
- raise ValidationError(f"Attempting to set incorrect value to Union type: {type(value)}")
+ raise ValidationError(
+ f"Attempting to set incorrect value to Union type: {type(value)}"
+ )
self._value = value
@property
M bare/test_encoder.py => bare/test_encoder.py +67 -24
@@ 120,9 120,13 @@ class ExampleUnion(Union):
class UnionTest(Struct):
e = ExampleUnion()
b = Union(members=(Str, Int))
- c = Union(members=(OptionalStruct,ArrayTest))
+ c = Union(members=(OptionalStruct, ArrayTest))
+
+
def test_union():
- ex = UnionTest(e=1, b="test", c=ArrayTest(a=[1], n=[Nested(s='s')])) # MUST specify values for union types when creating an object
+ ex = UnionTest(
+ e=1, b="test", c=ArrayTest(a=[1], n=[Nested(s="s")])
+ ) # MUST specify values for union types when creating an object
assert ex.e == 1
ex.e = "1"
assert ex.e == "1"
@@ 133,16 137,19 @@ def test_union():
assert ex.e == ex.e
assert ex.b == ex.b
assert ex.c.a == [1]
- assert ex.c.n[0].s == 's'
+ assert ex.c.n[0].s == "s"
assert ex.c.a == [1]
+
class EnumTest(enum.Enum):
TEST = 0
TEST2 = 1
+
class EnumTestStruct(Struct):
e = Enum(EnumTest)
+
def test_enum():
ex = EnumTestStruct(e=0)
assert ex.e == 0
@@ 153,9 160,11 @@ def test_enum():
class PublicKey(DataFixed):
_length = 128
+
class Time(Str):
pass
+
class Department(enum.Enum):
ACCOUNTING = 0
ADMINISTRATION = 1
@@ 164,16 173,19 @@ class Department(enum.Enum):
JSMITH = 99
+
class Address(Struct):
address = Array(Str, length=4)
city = Str()
state = Str()
country = Str()
+
class Order(Struct):
orderID = I64()
quantity = I32()
+
class Customer(Struct):
name = Str()
email = Str()
@@ 181,6 193,7 @@ class Customer(Struct):
orders = Array(Order)
metadata = Map(Str, Data)
+
class Employee(Struct):
name = Str()
email = Str()
@@ 190,15 203,20 @@ class Employee(Struct):
publicKey = Optional(PublicKey)
metadata = Map(Str, Data)
+
class TerminatedEmployee(Void):
pass
+
class Person(Union):
_members = (Customer, Employee, TerminatedEmployee)
-@pytest.mark.parametrize('file', ['customer.bin', 'employee.bin', 'people.bin', 'terminated.bin'])
+
+@pytest.mark.parametrize(
+ "file", ["customer.bin", "employee.bin", "people.bin", "terminated.bin"]
+)
def test_people(file):
- with open(os.path.join(os.path.dirname(__file__), '_examples', file), 'br') as f:
+ with open(os.path.join(os.path.dirname(__file__), "_examples", file), "br") as f:
people = []
while True:
try:
@@ 213,42 231,62 @@ def test_people(file):
person.pack(buf)
assert buf.getvalue() == f
+
def test_varint():
- expected = b'\x18'
+ expected = b"\x18"
i = Int(value=12)
assert i.pack() == expected
i = Int(value=12345)
- expected = b'\xf2\xc0\x01'
+ expected = b"\xf2\xc0\x01"
assert i.pack() == expected
i = Int(value=-12345678)
- expected = b'\x9b\x85\xe3\x0b'
+ expected = b"\x9b\x85\xe3\x0b"
assert i.pack() == expected
+
def test_uvarint():
- expected = b'\xce\xc2\xf1\x05'
+ expected = b"\xce\xc2\xf1\x05"
i = UInt(value=12345678)
assert i.pack() == expected
+
def test_string():
- expected = b'\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67'
+ expected = b"\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67"
s = Str(value="a test string")
assert s.pack() == expected
s = Str(value="")
- assert s.pack() == b'\x00'
-
-@pytest.mark.parametrize('value', [
- (Str(value='a test string'),b'\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67'),
- (Int(value=12345678), b'\x9c\x85\xe3\x0b\x9c\x85\xe3\x0b\x9c\x85\xe3\x0b\x9c\x85\xe3\x0b')
-])
+ assert s.pack() == b"\x00"
+
+
+@pytest.mark.parametrize(
+ "value",
+ [
+ (
+ Str(value="a test string"),
+ b"\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67",
+ ),
+ (
+ Int(value=12345678),
+ b"\x9c\x85\xe3\x0b\x9c\x85\xe3\x0b\x9c\x85\xe3\x0b\x9c\x85\xe3\x0b",
+ ),
+ ],
+)
def test_fixed_array(value):
a = Array(type=value[0].__class__, length=4, values=[value[0]] * 4)
assert a.pack() == value[1]
-@pytest.mark.parametrize('value',[
- (Str(value='a test string'),b'\x04\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67'),
- (Int(value=123456),b'\x04\x80\x89\x0f\x80\x89\x0f\x80\x89\x0f\x80\x89\x0f')
-])
+
+@pytest.mark.parametrize(
+ "value",
+ [
+ (
+ Str(value="a test string"),
+ b"\x04\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67",
+ ),
+ (Int(value=123456), b"\x04\x80\x89\x0f\x80\x89\x0f\x80\x89\x0f\x80\x89\x0f"),
+ ],
+)
def test_array(value):
a = Array(type=value[0].__class__, values=[value[0]] * 4)
packed = a.pack()
@@ 257,21 295,26 @@ def test_array(value):
unpacked = a.unpack(buf)
assert unpacked.to_dict() == a.to_dict()
+
class B(Struct):
c = Int()
+
class X(Struct):
a = Str()
b = B()
+
+
def test_struct():
- s = X(a='a test string', b=B(c=12345))
- expected = b'\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\xf2\xc0\x01'
+ s = X(a="a test string", b=B(c=12345))
+ expected = b"\x0d\x61\x20\x74\x65\x73\x74\x20\x73\x74\x72\x69\x6e\x67\xf2\xc0\x01"
assert s.pack() == expected
buf = io.BytesIO(expected)
unpacked = s.unpack(buf)
assert unpacked.to_dict() == s.to_dict()
+
def test_map():
- expected = b'\x02\x04\x74\x65\x73\x74\x04\x74\x65\x73\x74\x07\x61\x6e\x6f\x74\x68\x65\x72\x04\x63\x61\x73\x65'
- m = Map(Str, Str, value={'test': 'test', 'another': 'case'})
+ expected = b"\x02\x04\x74\x65\x73\x74\x04\x74\x65\x73\x74\x07\x61\x6e\x6f\x74\x68\x65\x72\x04\x63\x61\x73\x65"
+ m = Map(Str, Str, value={"test": "test", "another": "case"})
assert m.pack() == expected
M bare/types.py => bare/types.py +15 -5
@@ 239,6 239,7 @@ class Int(Field):
val = _read_varint(fp, signed=True)
return self.__class__(value=val)
+
class UInt(Field):
_type = BareType.UINT
@@ 248,7 249,10 @@ class UInt(Field):
if not isinstance(value, int):
return False, f"type: {type(value)} must be <int>"
if value < 0:
- return False, f"value: {value} is outside of valid range for this type: {self.__class__._type}",
+ return (
+ False,
+ f"value: {value} is outside of valid range for this type: {self.__class__._type}",
+ )
return True, None
def _pack(self, fp: typing.BinaryIO, value=None):
@@ 344,8 348,8 @@ class DataFixed(Field):
val = struct.unpack(f"<{length}s", fp)[0]
return self.__class__(value=val)
-class Enum(UInt):
+class Enum(UInt):
def __init__(self, enum, *args, **kwargs):
self._enum = enum
super().__init__(*args, **kwargs)
@@ 354,12 358,18 @@ class Enum(UInt):
if not isinstance(value, int):
return False, f"type: {type(value)} is not valid for Enum, must be <int>"
if value < 0:
- return False, f"value is not a valid value for Enum {self.__class__.__name__}"
+ return (
+ False,
+ f"value is not a valid value for Enum {self.__class__.__name__}",
+ )
values = set(item.value for item in self._enum.__members__.values())
if value not in values:
- return False, f"value {value} is not a valid Enum type for {self.__class__.__name__}"
+ return (
+ False,
+ f"value {value} is not a valid Enum type for {self.__class__.__name__}",
+ )
return True, None
- def _unpack(self, fp: typing.BinaryIO) -> 'UInt':
+ def _unpack(self, fp: typing.BinaryIO) -> "UInt":
val = _read_varint(fp, signed=False)
return self.__class__(self._enum, val)