Skip to content

Commit

Permalink
Provide container emulation methods for Message and Bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
nocarryr committed Mar 5, 2021
1 parent c71ff6d commit c454ae5
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
26 changes: 22 additions & 4 deletions src/oscpython/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def add_argument(self, value: Any) -> Argument:
If the value is an instance of :class:`~.arguments.Argument` it will
be added without copying
"""
ix = len(self.arguments)
ix = len(self)
if isinstance(value, Argument):
arg = value
arg.index = ix
Expand All @@ -144,7 +144,7 @@ def build_packet(self) -> bytes:
typetags = TypeTags()
pack_list = ArgumentList([self.address, typetags])

for arg in self.arguments:
for arg in self:
pack_list.append(arg)
typetags.append(arg.tag)
return pack_list.pack()
Expand All @@ -163,6 +163,15 @@ def parse(cls, packet_data: bytes) -> Tuple['Message', bytes]:
args.append(arg)
return (cls.create(address, *args), packet_data)

def __iter__(self):
yield from self.arguments

def __len__(self):
return len(self.arguments)

def __getitem__(self, key):
return self.arguments[key].value

@dataclass
class Bundle(Packet):
"""An OSC Bundle
Expand All @@ -180,7 +189,7 @@ class Bundle(Packet):
def add_packet(self, packet: Packet):
"""Add a :class:`Message` or :class:`Bundle` to the :attr:`packets` list
"""
ix = len(self.packets)
ix = len(self)
packet.parent_index = ix
packet.parent_bundle = self
self.packets.append(packet)
Expand All @@ -193,7 +202,7 @@ def build_packet(self) -> bytes:
TimeTagArgument(value=self.timetag),
])

for packet in self.packets:
for packet in self:
_packet_data = packet.build_packet()
pack_list.append(BlobArgument(_packet_data))
return pack_list.pack()
Expand All @@ -218,3 +227,12 @@ def parse(cls, packet_data: bytes) -> Tuple['Bundle', bytes]:
# assert remaining == packet_data

return (bun, packet_data)

def __iter__(self):
yield from self.packets

def __len__(self):
return len(self.packets)

def __getitem__(self, key):
return self.packets[key]
31 changes: 20 additions & 11 deletions tests/test_packets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


def check_message_args(msg: Message, all_arg_bytes: bytes):
for arg in msg.arguments:
for arg in msg:
try:
bytes_expected = arg.build_packet()
except ValueError as exc:
Expand All @@ -20,8 +20,8 @@ def check_message_args(msg: Message, all_arg_bytes: bytes):

def check_parsed_message(expected_msg: Message, parsed_msg: Message):
assert parsed_msg.address == expected_msg.address
assert len(parsed_msg.arguments) == len(expected_msg.arguments)
for parg, marg in zip(parsed_msg.arguments, expected_msg.arguments):
assert len(parsed_msg) == len(expected_msg)
for parg, marg in zip(parsed_msg, expected_msg):
assert parg.__class__ is marg.__class__
if isinstance(parg, (arguments.Float32Argument, arguments.Float64Argument)):
assert parg.value == pytest.approx(marg.value)
Expand All @@ -36,6 +36,12 @@ def test_message_arguments(message_args):
typetags_length = len(typetags_expected)

msg = Message.create(address, *arg_values)
assert len(msg) == len(list(msg)) == len(msg.arguments)

for i, arg in enumerate(msg):
assert arg is msg.arguments[i]
assert arg.value == msg[i] == arg_values[i]

msg_bytes = msg.build_packet()
assert len(msg_bytes) % 4 == 0
address_bytes = msg_bytes[:8]
Expand Down Expand Up @@ -73,7 +79,10 @@ def test_bundle(message_args):
for msg in messages:
bun.add_packet(msg)

for i, msg in enumerate(messages):
assert len(bun) == len(list(bun)) == len(messages) == len(bun.packets)

for i, msg in enumerate(bun):
assert msg is bun[i] is bun.packets[i]
assert msg.parent_bundle is bun
assert msg.parent_index == i

Expand Down Expand Up @@ -124,7 +133,7 @@ def test_bundle(message_args):
print(f'parsed={parsed}, remaining={remaining}')
assert parsed.timetag == bun.timetag
assert len(parsed.packets) == len(bun.packets)
for parsed_pkt, bun_pkt in zip(parsed.packets, bun.packets):
for parsed_pkt, bun_pkt in zip(parsed, bun):
check_parsed_message(bun_pkt, parsed_pkt)


Expand Down Expand Up @@ -157,7 +166,7 @@ def test_bundle_timestamps(message_args, faker):
assert parsed.timetag == bun.timetag
assert parsed.timetag.to_datetime() == dt

for parsed_pkt, bun_pkt in zip(parsed.packets, bun.packets):
for parsed_pkt, bun_pkt in zip(parsed, bun):
check_parsed_message(bun_pkt, parsed_pkt)

def test_nested_bundles(message_addresses, random_arguments, faker):
Expand Down Expand Up @@ -228,14 +237,14 @@ def create_bundle(parent=None, depth=0, parent_address=''):
def check_bundle(orig_bun, parsed_bun, depth=0):
assert orig_bun.timetag == parsed_bun.timetag
assert orig_bun.parent_index == parsed_bun.parent_index
assert len(orig_bun.packets) == len(parsed_bun.packets)
assert len(orig_bun) == len(parsed_bun)

all_parsed_bundle_dts.add(parsed_bun.timetag.to_datetime())
if depth not in all_parsed_addresses:
all_parsed_addresses[depth] = []
num_packets = 1

for orig_pkt, parsed_pkt in zip(orig_bun.packets, parsed_bun.packets):
for orig_pkt, parsed_pkt in zip(orig_bun, parsed_bun):
assert isinstance(parsed_pkt, Packet)
if isinstance(orig_pkt, Message):
assert orig_pkt.address == parsed_pkt.address
Expand Down Expand Up @@ -269,14 +278,14 @@ def test_random_addrs_and_args(message_addresses, random_arguments):
arg_values = [next(random_arguments) for _ in range(args_per_message)]
msg = Message.create(address, *arg_values)
bun.add_packet(msg)
if len(bun.packets) == messages_per_bundle:
if len(bun) == messages_per_bundle:
bun_bytes = bun.build_packet()

parsed, remaining = Packet.parse(bun_bytes)
# print(f'parsed={parsed}, remaining={remaining}')
assert parsed.timetag == bun.timetag
assert len(parsed.packets) == len(bun.packets)
for parsed_pkt, bun_pkt in zip(parsed.packets, bun.packets):
assert len(parsed) == len(bun)
for parsed_pkt, bun_pkt in zip(parsed, bun):
check_parsed_message(bun_pkt, parsed_pkt)

bun = None

0 comments on commit c454ae5

Please sign in to comment.