Skip to content

Commit 40f303e

Browse files
committed
support for wildcards in dispatch patterns
1 parent c3b8b7c commit 40f303e

2 files changed

Lines changed: 27 additions & 5 deletions

File tree

pythonosc/dispatcher.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ def handlers_for_address(self, address_pattern):
3535
# '?' in the OSC Address Pattern matches any single character.
3636
# Let's consider numbers and _ "characters" too here, it's not said
3737
# explicitly in the specification but it sounds good.
38-
address_pattern = re.escape(address_pattern)
39-
pattern = address_pattern.replace('\\?', '\\w?')
38+
escaped_address_pattern = re.escape(address_pattern)
39+
pattern = escaped_address_pattern.replace('\\?', '\\w?')
4040
# '*' in the OSC Address Pattern matches any sequence of zero or more
4141
# characters.
4242
pattern = pattern.replace('\\*', '[\w|\+]*')
@@ -45,7 +45,12 @@ def handlers_for_address(self, address_pattern):
4545
pattern = pattern + '$'
4646
pattern = re.compile(pattern)
4747
matched = [
48-
handler for addr, handler in self._map.items() if pattern.match(addr)]
48+
handler for addr, handler in self._map.items()
49+
if ( pattern.match(addr) # wildcards could be in the incoming pattern
50+
# .. or the mapped pattern
51+
or (('*' in addr) and re.match(addr.replace('*','[^/]*?/*'), address_pattern))
52+
)
53+
]
4954
if not matched and self._default_handler:
5055
matched.append(Handler(self._default_handler, []))
5156
logging.debug('No handler matched but default handler present, added it.')

pythonosc/test/test_dispatcher.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def test_empty_by_default(self):
1818
def test_use_default_handler_when_set_and_no_match(self):
1919
handler = object()
2020
self.dispatcher.set_default_handler(handler)
21-
self.assertEqual([(handler, [])], self.dispatcher.handlers_for_address('/test'))
21+
self.assertEqual([dispatcher.Handler(handler, [])], self.dispatcher.handlers_for_address('/test'))
2222

2323
def test_simple_map_and_match(self):
2424
handler = object()
@@ -27,7 +27,7 @@ def test_simple_map_and_match(self):
2727
self.assertEqual(
2828
[(handler, [1, 2, 3])], self.dispatcher.handlers_for_address('/test'))
2929
self.assertEqual(
30-
[(handler, [])], self.dispatcher.handlers_for_address('/test2'))
30+
[dispatcher.Handler(handler, [])], self.dispatcher.handlers_for_address('/test2'))
3131

3232
def test_example_from_spec(self):
3333
addresses = [
@@ -89,5 +89,22 @@ def test_call_correct_dispatcher_on_star(self):
8989
self.sortAndAssertSequenceEqual(
9090
[(1, [])], self.dispatcher.handlers_for_address('/a+b'))
9191

92+
def test_map_star(self):
93+
self.dispatcher.map('/starbase/*', 1)
94+
self.sortAndAssertSequenceEqual(
95+
[(1, [])], self.dispatcher.handlers_for_address("/starbase/bar"))
96+
97+
def test_map_root_star(self):
98+
self.dispatcher.map('/*', 1)
99+
self.sortAndAssertSequenceEqual(
100+
[(1, [])], self.dispatcher.handlers_for_address("/anything/matches"))
101+
102+
def test_map_double_stars(self):
103+
self.dispatcher.map('/foo/*/bar/*', 1)
104+
self.sortAndAssertSequenceEqual(
105+
[(1, [])], self.dispatcher.handlers_for_address("/foo/wild/bar/wild"))
106+
self.sortAndAssertSequenceEqual(
107+
[], self.dispatcher.handlers_for_address("/foo/wild/nomatch/wild"))
108+
92109
if __name__ == "__main__":
93110
unittest.main()

0 commit comments

Comments
 (0)