Skip to content

Commit c77fb34

Browse files
authored
fix: handle iter-/generators correctly in MidiOut.send_message (#186)
Signed-off-by: Christopher Arndt <[email protected]>
1 parent c0b9381 commit c77fb34

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ help:
1818
@echo "release - package a release"
1919
@echo "release_upload - package a release and upload it to PyPI"
2020
@echo "requirements - generate 'requirement-dev.txt' from 'requirements-dev.in'"
21-
@echo "test - run tests on every supported Python version with tox"
21+
@echo "test - run tests with pytest"
2222

2323
build: $(SOURCES)
2424
if [[ -d "$(BUILDDIR)" ]]; then \

src/_rtmidi.pyx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,11 +1101,16 @@ cdef class MidiOut(MidiBase):
11011101
if not message:
11021102
raise ValueError("'message' must not be empty.")
11031103

1104-
if len(message) > 3 and message[0] != 0xF0:
1105-
raise ValueError("'message' longer than 3 bytes but does not "
1106-
"start with 0xF0.")
1104+
try:
1105+
msg_v.reserve(len(message))
1106+
except TypeError:
1107+
pass
11071108

11081109
for c in message:
11091110
msg_v.push_back(c)
11101111

1112+
if msg_v.size() > 3 and msg_v.at(0) != 0xF0:
1113+
raise ValueError("'message' longer than 3 bytes but does not "
1114+
"start with 0xF0.")
1115+
11111116
self.thisptr.sendMessage(&msg_v)

tests/test_rtmidi.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
class BaseTests:
1313
NOTE_ON = [0x90, 48, 100]
1414
NOTE_OFF = [0x80, 48, 16]
15+
SYSEX_IDENTITY_REQUEST = [0xF0, 0x7E, 0x7F, 6, 1, 0xF7]
1516
IN_CLIENT_NAME = "RtMidiTestCase In"
1617
OUT_CLIENT_NAME = "RtMidiTestCase Out"
1718
IN_PORT_NAME = 'testin'
@@ -67,10 +68,32 @@ def test_send_and_get_message(self):
6768
self.midi_out.send_message(self.NOTE_ON)
6869
self.midi_out.send_message(self.NOTE_OFF)
6970
time.sleep(self.DELAY)
70-
message_1, _ = self.midi_in.get_message()
71-
message_2, _ = self.midi_in.get_message()
72-
self.assertEqual(message_1, self.NOTE_ON)
73-
self.assertEqual(message_2, self.NOTE_OFF)
71+
event_1 = self.midi_in.get_message()
72+
event_2 = self.midi_in.get_message()
73+
self.assertTrue(isinstance(event_1, tuple))
74+
self.assertTrue(isinstance(event_2, tuple))
75+
self.assertEqual(event_1[0], self.NOTE_ON)
76+
self.assertEqual(event_2[0], self.NOTE_OFF)
77+
78+
def test_send_supports_iterator(self):
79+
self.set_up_loopback()
80+
self.midi_out.send_message(iter(self.NOTE_ON))
81+
time.sleep(self.DELAY)
82+
event = self.midi_in.get_message()
83+
self.assertTrue(isinstance(event, tuple))
84+
self.assertEqual(event[0], self.NOTE_ON)
85+
86+
def test_send_raises_if_message_too_long(self):
87+
self.assertRaises(ValueError, self.midi_out.send_message, [1, 2, 3, 4])
88+
89+
def test_send_accepts_sysex(self):
90+
self.set_up_loopback()
91+
self.midi_in.ignore_types(sysex=False)
92+
self.midi_out.send_message(self.SYSEX_IDENTITY_REQUEST)
93+
time.sleep(self.DELAY)
94+
event = self.midi_in.get_message()
95+
self.assertTrue(isinstance(event, tuple))
96+
self.assertEqual(event[0], self.SYSEX_IDENTITY_REQUEST)
7497

7598
def test_callback(self):
7699
messages = []

0 commit comments

Comments
 (0)