python-osc 1.8.0__tar.gz → 1.8.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. {python-osc-1.8.0 → python-osc-1.8.2}/MANIFEST.in +1 -0
  2. python-osc-1.8.2/PKG-INFO +202 -0
  3. {python-osc-1.8.0 → python-osc-1.8.2}/README.rst +6 -6
  4. python-osc-1.8.2/pyproject.toml +21 -0
  5. python-osc-1.8.2/python_osc.egg-info/PKG-INFO +202 -0
  6. {python-osc-1.8.0 → python-osc-1.8.2}/python_osc.egg-info/SOURCES.txt +2 -1
  7. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/dispatcher.py +10 -11
  8. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_bundle.py +6 -8
  9. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_bundle_builder.py +3 -1
  10. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_message.py +7 -4
  11. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_message_builder.py +21 -18
  12. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_packet.py +5 -5
  13. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_server.py +12 -7
  14. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/parsing/ntp.py +5 -4
  15. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/parsing/osc_types.py +9 -5
  16. python-osc-1.8.2/pythonosc/test/parsing/__init__.py +0 -0
  17. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_message.py +8 -6
  18. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_message_builder.py +1 -1
  19. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_server.py +3 -3
  20. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/udp_client.py +12 -9
  21. python-osc-1.8.2/setup.cfg +18 -0
  22. python-osc-1.8.0/PKG-INFO +0 -178
  23. python-osc-1.8.0/python_osc.egg-info/PKG-INFO +0 -178
  24. python-osc-1.8.0/setup.cfg +0 -7
  25. python-osc-1.8.0/setup.py +0 -41
  26. {python-osc-1.8.0 → python-osc-1.8.2}/LICENSE.txt +0 -0
  27. {python-osc-1.8.0 → python-osc-1.8.2}/python_osc.egg-info/dependency_links.txt +0 -0
  28. {python-osc-1.8.0 → python-osc-1.8.2}/python_osc.egg-info/top_level.txt +0 -0
  29. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/__init__.py +0 -0
  30. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/parsing/__init__.py +0 -0
  31. /python-osc-1.8.0/pythonosc/test/__init__.py → /python-osc-1.8.2/pythonosc/py.typed +0 -0
  32. {python-osc-1.8.0/pythonosc/test/parsing → python-osc-1.8.2/pythonosc/test}/__init__.py +0 -0
  33. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/parsing/test_ntp.py +0 -0
  34. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/parsing/test_osc_types.py +0 -0
  35. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_dispatcher.py +0 -0
  36. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_bundle.py +0 -0
  37. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_bundle_builder.py +0 -0
  38. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_packet.py +0 -0
  39. {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_udp_client.py +0 -0
@@ -1,2 +1,3 @@
1
1
  include README.rst
2
2
  include LICENSE.txt
3
+ include pythonosc/py.typed
@@ -0,0 +1,202 @@
1
+ Metadata-Version: 2.1
2
+ Name: python-osc
3
+ Version: 1.8.2
4
+ Summary: Open Sound Control server and client implementations in pure Python
5
+ Author-email: attwad <tmusoft@gmail.com>
6
+ License: This is free and unencumbered software released into the public domain.
7
+
8
+ Anyone is free to copy, modify, publish, use, compile, sell, or
9
+ distribute this software, either in source code form or as a compiled
10
+ binary, for any purpose, commercial or non-commercial, and by any
11
+ means.
12
+
13
+ In jurisdictions that recognize copyright laws, the author or authors
14
+ of this software dedicate any and all copyright interest in the
15
+ software to the public domain. We make this dedication for the benefit
16
+ of the public at large and to the detriment of our heirs and
17
+ successors. We intend this dedication to be an overt act of
18
+ relinquishment in perpetuity of all present and future rights to this
19
+ software under copyright law.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ OTHER DEALINGS IN THE SOFTWARE.
28
+
29
+ For more information, please refer to <http://unlicense.org/>
30
+
31
+ Project-URL: Repository, https://github.com/attwad/python-osc
32
+ Keywords: osc,sound,midi,music
33
+ Classifier: Development Status :: 5 - Production/Stable
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: Freely Distributable
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Topic :: Multimedia :: Sound/Audio
38
+ Classifier: Topic :: System :: Networking
39
+ Requires-Python: >=3.7
40
+ Description-Content-Type: text/x-rst
41
+ License-File: LICENSE.txt
42
+
43
+ ==========
44
+ python-osc
45
+ ==========
46
+
47
+ Open Sound Control server and client implementations in **pure python**.
48
+
49
+ .. image:: https://github.com/attwad/python-osc/actions/workflows/python-test.yml/badge.svg
50
+ :target: https://github.com/attwad/python-osc/actions/workflows/python-test.yml
51
+
52
+
53
+ Current status
54
+ ==============
55
+
56
+ This library was developed following the
57
+ `OpenSoundControl Specification 1.0 <https://opensoundcontrol.stanford.edu/spec-1_0.html>`_
58
+ and is currently in a stable state.
59
+
60
+ Features
61
+ ========
62
+
63
+ * UDP blocking/threading/forking/asyncio server implementations
64
+ * UDP client
65
+ * int, int64, float, string, double, MIDI, timestamps, blob, nil OSC arguments
66
+ * simple OSC address<->callback matching system
67
+ * extensive unit test coverage
68
+ * basic client and server examples
69
+
70
+ Documentation
71
+ =============
72
+
73
+ Available at https://python-osc.readthedocs.io/.
74
+
75
+ Installation
76
+ ============
77
+
78
+ python-osc is a pure python library that has no external dependencies,
79
+ to install it just use pip (prefered):
80
+
81
+ .. image:: https://img.shields.io/pypi/v/python-osc.svg
82
+ :target: https://pypi.python.org/pypi/python-osc
83
+
84
+ .. code-block:: bash
85
+
86
+ $ pip install python-osc
87
+
88
+ or from the raw sources for the development version:
89
+
90
+ .. code-block:: bash
91
+
92
+ $ python setup.py test
93
+ $ python setup.py install
94
+
95
+ Examples
96
+ ========
97
+
98
+ Simple client
99
+ -------------
100
+
101
+ .. code-block:: python
102
+
103
+ """Small example OSC client
104
+
105
+ This program sends 10 random values between 0.0 and 1.0 to the /filter address,
106
+ waiting for 1 seconds between each value.
107
+ """
108
+ import argparse
109
+ import random
110
+ import time
111
+
112
+ from pythonosc import udp_client
113
+
114
+
115
+ if __name__ == "__main__":
116
+ parser = argparse.ArgumentParser()
117
+ parser.add_argument("--ip", default="127.0.0.1",
118
+ help="The ip of the OSC server")
119
+ parser.add_argument("--port", type=int, default=5005,
120
+ help="The port the OSC server is listening on")
121
+ args = parser.parse_args()
122
+
123
+ client = udp_client.SimpleUDPClient(args.ip, args.port)
124
+
125
+ for x in range(10):
126
+ client.send_message("/filter", random.random())
127
+ time.sleep(1)
128
+
129
+ Simple server
130
+ -------------
131
+
132
+ .. code-block:: python
133
+
134
+ """Small example OSC server
135
+
136
+ This program listens to several addresses, and prints some information about
137
+ received packets.
138
+ """
139
+ import argparse
140
+ import math
141
+
142
+ from pythonosc.dispatcher import Dispatcher
143
+ from pythonosc import osc_server
144
+
145
+ def print_volume_handler(unused_addr, args, volume):
146
+ print("[{0}] ~ {1}".format(args[0], volume))
147
+
148
+ def print_compute_handler(unused_addr, args, volume):
149
+ try:
150
+ print("[{0}] ~ {1}".format(args[0], args[1](volume)))
151
+ except ValueError: pass
152
+
153
+ if __name__ == "__main__":
154
+ parser = argparse.ArgumentParser()
155
+ parser.add_argument("--ip",
156
+ default="127.0.0.1", help="The ip to listen on")
157
+ parser.add_argument("--port",
158
+ type=int, default=5005, help="The port to listen on")
159
+ args = parser.parse_args()
160
+
161
+ dispatcher = Dispatcher()
162
+ dispatcher.map("/filter", print)
163
+ dispatcher.map("/volume", print_volume_handler, "Volume")
164
+ dispatcher.map("/logvolume", print_compute_handler, "Log volume", math.log)
165
+
166
+ server = osc_server.ThreadingOSCUDPServer(
167
+ (args.ip, args.port), dispatcher)
168
+ print("Serving on {}".format(server.server_address))
169
+ server.serve_forever()
170
+
171
+ Building bundles
172
+ ----------------
173
+
174
+ .. code-block:: python
175
+
176
+ from pythonosc import osc_bundle_builder
177
+ from pythonosc import osc_message_builder
178
+
179
+ bundle = osc_bundle_builder.OscBundleBuilder(
180
+ osc_bundle_builder.IMMEDIATELY)
181
+ msg = osc_message_builder.OscMessageBuilder(address="/SYNC")
182
+ msg.add_arg(4.0)
183
+ # Add 4 messages in the bundle, each with more arguments.
184
+ bundle.add_content(msg.build())
185
+ msg.add_arg(2)
186
+ bundle.add_content(msg.build())
187
+ msg.add_arg("value")
188
+ bundle.add_content(msg.build())
189
+ msg.add_arg(b"\x01\x02\x03")
190
+ bundle.add_content(msg.build())
191
+
192
+ sub_bundle = bundle.build()
193
+ # Now add the same bundle inside itself.
194
+ bundle.add_content(sub_bundle)
195
+ # The bundle has 5 elements in total now.
196
+
197
+ bundle = bundle.build()
198
+ # You can now send it via a client as described in other examples.
199
+
200
+ License?
201
+ ========
202
+ Unlicensed, do what you want with it. (http://unlicense.org)
@@ -2,7 +2,7 @@
2
2
  python-osc
3
3
  ==========
4
4
 
5
- Open Sound Control server and client implementations in **pure python** (3.5+).
5
+ Open Sound Control server and client implementations in **pure python**.
6
6
 
7
7
  .. image:: https://github.com/attwad/python-osc/actions/workflows/python-test.yml/badge.svg
8
8
  :target: https://github.com/attwad/python-osc/actions/workflows/python-test.yml
@@ -11,8 +11,8 @@ Open Sound Control server and client implementations in **pure python** (3.5+).
11
11
  Current status
12
12
  ==============
13
13
 
14
- This library was developped following the specifications at
15
- http://opensoundcontrol.org/spec-1_0
14
+ This library was developed following the
15
+ `OpenSoundControl Specification 1.0 <https://opensoundcontrol.stanford.edu/spec-1_0.html>`_
16
16
  and is currently in a stable state.
17
17
 
18
18
  Features
@@ -20,7 +20,7 @@ Features
20
20
 
21
21
  * UDP blocking/threading/forking/asyncio server implementations
22
22
  * UDP client
23
- * int, int64, float, string, double, MIDI, timestamps, blob OSC arguments
23
+ * int, int64, float, string, double, MIDI, timestamps, blob, nil OSC arguments
24
24
  * simple OSC address<->callback matching system
25
25
  * extensive unit test coverage
26
26
  * basic client and server examples
@@ -97,7 +97,7 @@ Simple server
97
97
  import argparse
98
98
  import math
99
99
 
100
- from pythonosc import dispatcher
100
+ from pythonosc.dispatcher import Dispatcher
101
101
  from pythonosc import osc_server
102
102
 
103
103
  def print_volume_handler(unused_addr, args, volume):
@@ -116,7 +116,7 @@ Simple server
116
116
  type=int, default=5005, help="The port to listen on")
117
117
  args = parser.parse_args()
118
118
 
119
- dispatcher = dispatcher.Dispatcher()
119
+ dispatcher = Dispatcher()
120
120
  dispatcher.map("/filter", print)
121
121
  dispatcher.map("/volume", print_volume_handler, "Volume")
122
122
  dispatcher.map("/logvolume", print_compute_handler, "Log volume", math.log)
@@ -0,0 +1,21 @@
1
+ [project]
2
+ name = "python-osc"
3
+ version="1.8.2"
4
+ description="Open Sound Control server and client implementations in pure Python"
5
+ readme="README.rst"
6
+ requires-python=">=3.7"
7
+ license = {file = "LICENSE.txt"}
8
+ authors = [
9
+ {name = "attwad", email = "tmusoft@gmail.com"},
10
+ ]
11
+ keywords = ["osc", "sound", "midi", "music"]
12
+ classifiers=[
13
+ 'Development Status :: 5 - Production/Stable',
14
+ 'Intended Audience :: Developers',
15
+ 'License :: Freely Distributable',
16
+ 'Programming Language :: Python :: 3',
17
+ 'Topic :: Multimedia :: Sound/Audio',
18
+ 'Topic :: System :: Networking',
19
+ ]
20
+ [project.urls]
21
+ Repository = "https://github.com/attwad/python-osc"
@@ -0,0 +1,202 @@
1
+ Metadata-Version: 2.1
2
+ Name: python-osc
3
+ Version: 1.8.2
4
+ Summary: Open Sound Control server and client implementations in pure Python
5
+ Author-email: attwad <tmusoft@gmail.com>
6
+ License: This is free and unencumbered software released into the public domain.
7
+
8
+ Anyone is free to copy, modify, publish, use, compile, sell, or
9
+ distribute this software, either in source code form or as a compiled
10
+ binary, for any purpose, commercial or non-commercial, and by any
11
+ means.
12
+
13
+ In jurisdictions that recognize copyright laws, the author or authors
14
+ of this software dedicate any and all copyright interest in the
15
+ software to the public domain. We make this dedication for the benefit
16
+ of the public at large and to the detriment of our heirs and
17
+ successors. We intend this dedication to be an overt act of
18
+ relinquishment in perpetuity of all present and future rights to this
19
+ software under copyright law.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27
+ OTHER DEALINGS IN THE SOFTWARE.
28
+
29
+ For more information, please refer to <http://unlicense.org/>
30
+
31
+ Project-URL: Repository, https://github.com/attwad/python-osc
32
+ Keywords: osc,sound,midi,music
33
+ Classifier: Development Status :: 5 - Production/Stable
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: Freely Distributable
36
+ Classifier: Programming Language :: Python :: 3
37
+ Classifier: Topic :: Multimedia :: Sound/Audio
38
+ Classifier: Topic :: System :: Networking
39
+ Requires-Python: >=3.7
40
+ Description-Content-Type: text/x-rst
41
+ License-File: LICENSE.txt
42
+
43
+ ==========
44
+ python-osc
45
+ ==========
46
+
47
+ Open Sound Control server and client implementations in **pure python**.
48
+
49
+ .. image:: https://github.com/attwad/python-osc/actions/workflows/python-test.yml/badge.svg
50
+ :target: https://github.com/attwad/python-osc/actions/workflows/python-test.yml
51
+
52
+
53
+ Current status
54
+ ==============
55
+
56
+ This library was developed following the
57
+ `OpenSoundControl Specification 1.0 <https://opensoundcontrol.stanford.edu/spec-1_0.html>`_
58
+ and is currently in a stable state.
59
+
60
+ Features
61
+ ========
62
+
63
+ * UDP blocking/threading/forking/asyncio server implementations
64
+ * UDP client
65
+ * int, int64, float, string, double, MIDI, timestamps, blob, nil OSC arguments
66
+ * simple OSC address<->callback matching system
67
+ * extensive unit test coverage
68
+ * basic client and server examples
69
+
70
+ Documentation
71
+ =============
72
+
73
+ Available at https://python-osc.readthedocs.io/.
74
+
75
+ Installation
76
+ ============
77
+
78
+ python-osc is a pure python library that has no external dependencies,
79
+ to install it just use pip (prefered):
80
+
81
+ .. image:: https://img.shields.io/pypi/v/python-osc.svg
82
+ :target: https://pypi.python.org/pypi/python-osc
83
+
84
+ .. code-block:: bash
85
+
86
+ $ pip install python-osc
87
+
88
+ or from the raw sources for the development version:
89
+
90
+ .. code-block:: bash
91
+
92
+ $ python setup.py test
93
+ $ python setup.py install
94
+
95
+ Examples
96
+ ========
97
+
98
+ Simple client
99
+ -------------
100
+
101
+ .. code-block:: python
102
+
103
+ """Small example OSC client
104
+
105
+ This program sends 10 random values between 0.0 and 1.0 to the /filter address,
106
+ waiting for 1 seconds between each value.
107
+ """
108
+ import argparse
109
+ import random
110
+ import time
111
+
112
+ from pythonosc import udp_client
113
+
114
+
115
+ if __name__ == "__main__":
116
+ parser = argparse.ArgumentParser()
117
+ parser.add_argument("--ip", default="127.0.0.1",
118
+ help="The ip of the OSC server")
119
+ parser.add_argument("--port", type=int, default=5005,
120
+ help="The port the OSC server is listening on")
121
+ args = parser.parse_args()
122
+
123
+ client = udp_client.SimpleUDPClient(args.ip, args.port)
124
+
125
+ for x in range(10):
126
+ client.send_message("/filter", random.random())
127
+ time.sleep(1)
128
+
129
+ Simple server
130
+ -------------
131
+
132
+ .. code-block:: python
133
+
134
+ """Small example OSC server
135
+
136
+ This program listens to several addresses, and prints some information about
137
+ received packets.
138
+ """
139
+ import argparse
140
+ import math
141
+
142
+ from pythonosc.dispatcher import Dispatcher
143
+ from pythonosc import osc_server
144
+
145
+ def print_volume_handler(unused_addr, args, volume):
146
+ print("[{0}] ~ {1}".format(args[0], volume))
147
+
148
+ def print_compute_handler(unused_addr, args, volume):
149
+ try:
150
+ print("[{0}] ~ {1}".format(args[0], args[1](volume)))
151
+ except ValueError: pass
152
+
153
+ if __name__ == "__main__":
154
+ parser = argparse.ArgumentParser()
155
+ parser.add_argument("--ip",
156
+ default="127.0.0.1", help="The ip to listen on")
157
+ parser.add_argument("--port",
158
+ type=int, default=5005, help="The port to listen on")
159
+ args = parser.parse_args()
160
+
161
+ dispatcher = Dispatcher()
162
+ dispatcher.map("/filter", print)
163
+ dispatcher.map("/volume", print_volume_handler, "Volume")
164
+ dispatcher.map("/logvolume", print_compute_handler, "Log volume", math.log)
165
+
166
+ server = osc_server.ThreadingOSCUDPServer(
167
+ (args.ip, args.port), dispatcher)
168
+ print("Serving on {}".format(server.server_address))
169
+ server.serve_forever()
170
+
171
+ Building bundles
172
+ ----------------
173
+
174
+ .. code-block:: python
175
+
176
+ from pythonosc import osc_bundle_builder
177
+ from pythonosc import osc_message_builder
178
+
179
+ bundle = osc_bundle_builder.OscBundleBuilder(
180
+ osc_bundle_builder.IMMEDIATELY)
181
+ msg = osc_message_builder.OscMessageBuilder(address="/SYNC")
182
+ msg.add_arg(4.0)
183
+ # Add 4 messages in the bundle, each with more arguments.
184
+ bundle.add_content(msg.build())
185
+ msg.add_arg(2)
186
+ bundle.add_content(msg.build())
187
+ msg.add_arg("value")
188
+ bundle.add_content(msg.build())
189
+ msg.add_arg(b"\x01\x02\x03")
190
+ bundle.add_content(msg.build())
191
+
192
+ sub_bundle = bundle.build()
193
+ # Now add the same bundle inside itself.
194
+ bundle.add_content(sub_bundle)
195
+ # The bundle has 5 elements in total now.
196
+
197
+ bundle = bundle.build()
198
+ # You can now send it via a client as described in other examples.
199
+
200
+ License?
201
+ ========
202
+ Unlicensed, do what you want with it. (http://unlicense.org)
@@ -1,8 +1,8 @@
1
1
  LICENSE.txt
2
2
  MANIFEST.in
3
3
  README.rst
4
+ pyproject.toml
4
5
  setup.cfg
5
- setup.py
6
6
  python_osc.egg-info/PKG-INFO
7
7
  python_osc.egg-info/SOURCES.txt
8
8
  python_osc.egg-info/dependency_links.txt
@@ -15,6 +15,7 @@ pythonosc/osc_message.py
15
15
  pythonosc/osc_message_builder.py
16
16
  pythonosc/osc_packet.py
17
17
  pythonosc/osc_server.py
18
+ pythonosc/py.typed
18
19
  pythonosc/udp_client.py
19
20
  pythonosc/parsing/__init__.py
20
21
  pythonosc/parsing/ntp.py
@@ -6,8 +6,7 @@ import logging
6
6
  import re
7
7
  import time
8
8
  from pythonosc import osc_packet
9
- from typing import overload, List, Union, Any, Generator, Tuple
10
- from types import FunctionType
9
+ from typing import overload, List, Union, Any, Generator, Tuple, Callable, Optional, DefaultDict
11
10
  from pythonosc.osc_message import OscMessage
12
11
 
13
12
 
@@ -19,7 +18,7 @@ class Handler(object):
19
18
  message if any were passed.
20
19
  """
21
20
 
22
- def __init__(self, _callback: FunctionType, _args: Union[Any, List[Any]],
21
+ def __init__(self, _callback: Callable, _args: Union[Any, List[Any]],
23
22
  _needs_reply_address: bool = False) -> None:
24
23
  """
25
24
  Args:
@@ -32,13 +31,13 @@ class Handler(object):
32
31
  self.needs_reply_address = _needs_reply_address
33
32
 
34
33
  # needed for test module
35
- def __eq__(self, other) -> bool:
34
+ def __eq__(self, other: Any) -> bool:
36
35
  return (type(self) == type(other) and
37
36
  self.callback == other.callback and
38
37
  self.args == other.args and
39
38
  self.needs_reply_address == other.needs_reply_address)
40
39
 
41
- def invoke(self, client_address: str, message: OscMessage) -> None:
40
+ def invoke(self, client_address: Tuple[str, int], message: OscMessage) -> None:
42
41
  """Invokes the associated callback function
43
42
 
44
43
  Args:
@@ -64,10 +63,10 @@ class Dispatcher(object):
64
63
  """
65
64
 
66
65
  def __init__(self) -> None:
67
- self._map = collections.defaultdict(list)
68
- self._default_handler = None
66
+ self._map = collections.defaultdict(list) # type: DefaultDict[str, List[Handler]]
67
+ self._default_handler = None # type: Optional[Handler]
69
68
 
70
- def map(self, address: str, handler: FunctionType, *args: Union[Any, List[Any]],
69
+ def map(self, address: str, handler: Callable, *args: Union[Any, List[Any]],
71
70
  needs_reply_address: bool = False) -> Handler:
72
71
  """Map an address to a handler
73
72
 
@@ -108,7 +107,7 @@ class Dispatcher(object):
108
107
  pass
109
108
 
110
109
  @overload
111
- def unmap(self, address: str, handler: FunctionType, *args: Union[Any, List[Any]],
110
+ def unmap(self, address: str, handler: Callable, *args: Union[Any, List[Any]],
112
111
  needs_reply_address: bool = False) -> None:
113
112
  """Remove an already mapped handler from an address
114
113
 
@@ -133,7 +132,7 @@ class Dispatcher(object):
133
132
  if str(e) == "list.remove(x): x not in list":
134
133
  raise ValueError("Address '%s' doesn't have handler '%s' mapped to it" % (address, handler)) from e
135
134
 
136
- def handlers_for_address(self, address_pattern: str) -> Generator[None, Handler, None]:
135
+ def handlers_for_address(self, address_pattern: str) -> Generator[Handler, None, None]:
137
136
  """Yields handlers matching an address
138
137
 
139
138
 
@@ -195,7 +194,7 @@ class Dispatcher(object):
195
194
  except osc_packet.ParseError:
196
195
  pass
197
196
 
198
- def set_default_handler(self, handler: FunctionType, needs_reply_address: bool = False) -> None:
197
+ def set_default_handler(self, handler: Callable, needs_reply_address: bool = False) -> None:
199
198
  """Sets the default handler
200
199
 
201
200
  The default handler is invoked every time no other handler is mapped to an address.
@@ -3,7 +3,7 @@ import logging
3
3
  from pythonosc import osc_message
4
4
  from pythonosc.parsing import osc_types
5
5
 
6
- from typing import Any, Iterator
6
+ from typing import Any, Iterator, List, Union
7
7
 
8
8
  _BUNDLE_PREFIX = b"#bundle\x00"
9
9
 
@@ -37,10 +37,8 @@ class OscBundle(object):
37
37
  # Get the contents as a list of OscBundle and OscMessage.
38
38
  self._contents = self._parse_contents(index)
39
39
 
40
- # Return type is actually List[OscBundle], but that would require import annotations from __future__, which is
41
- # python 3.7+ only.
42
- def _parse_contents(self, index: int) -> Any:
43
- contents = []
40
+ def _parse_contents(self, index: int) -> List[Union['OscBundle', osc_message.OscMessage]]:
41
+ contents = [] # type: List[Union[OscBundle, osc_message.OscMessage]]
44
42
 
45
43
  try:
46
44
  # An OSC Bundle Element consists of its size and its contents.
@@ -61,7 +59,7 @@ class OscBundle(object):
61
59
  contents.append(osc_message.OscMessage(content_dgram))
62
60
  else:
63
61
  logging.warning(
64
- "Could not identify content type of dgram %s" % content_dgram)
62
+ "Could not identify content type of dgram %r" % content_dgram)
65
63
  except (osc_types.ParseError, osc_message.ParseError, IndexError) as e:
66
64
  raise ParseError("Could not parse a content datagram: %s" % e)
67
65
 
@@ -73,7 +71,7 @@ class OscBundle(object):
73
71
  return dgram.startswith(_BUNDLE_PREFIX)
74
72
 
75
73
  @property
76
- def timestamp(self) -> int:
74
+ def timestamp(self) -> float:
77
75
  """Returns the timestamp associated with this bundle."""
78
76
  return self._timestamp
79
77
 
@@ -92,7 +90,7 @@ class OscBundle(object):
92
90
  """Returns the datagram from which this bundle was built."""
93
91
  return self._dgram
94
92
 
95
- def content(self, index) -> Any:
93
+ def content(self, index: int) -> Any:
96
94
  """Returns the bundle's content 0-indexed."""
97
95
  return self._contents[index]
98
96
 
@@ -1,5 +1,7 @@
1
1
  """Build OSC bundles for client applications."""
2
2
 
3
+ from typing import List
4
+
3
5
  from pythonosc import osc_bundle
4
6
  from pythonosc import osc_message
5
7
  from pythonosc.parsing import osc_types
@@ -23,7 +25,7 @@ class OscBundleBuilder(object):
23
25
  seconds since the epoch in UTC or IMMEDIATELY.
24
26
  """
25
27
  self._timestamp = timestamp
26
- self._contents = []
28
+ self._contents = [] # type: List[osc_bundle.OscBundle]
27
29
 
28
30
  def add_content(self, content: osc_bundle.OscBundle) -> None:
29
31
  """Add a new content to this bundle.
@@ -19,7 +19,7 @@ class OscMessage(object):
19
19
 
20
20
  def __init__(self, dgram: bytes) -> None:
21
21
  self._dgram = dgram
22
- self._parameters = []
22
+ self._parameters = [] # type: List[Any]
23
23
  self._parse_datagram()
24
24
 
25
25
  def _parse_datagram(self) -> None:
@@ -34,10 +34,11 @@ class OscMessage(object):
34
34
  if type_tag.startswith(','):
35
35
  type_tag = type_tag[1:]
36
36
 
37
- params = []
37
+ params = [] # type: List[Any]
38
38
  param_stack = [params]
39
39
  # Parse each parameter given its type.
40
40
  for param in type_tag:
41
+ val = NotImplemented # type: Any
41
42
  if param == "i": # Integer.
42
43
  val, index = osc_types.get_int(self._dgram, index)
43
44
  elif param == "h": # Int64.
@@ -60,8 +61,10 @@ class OscMessage(object):
60
61
  val = True
61
62
  elif param == "F": # False.
62
63
  val = False
64
+ elif param == "N": # Nil.
65
+ val = None
63
66
  elif param == "[": # Array start.
64
- array = []
67
+ array = [] # type: List[Any]
65
68
  param_stack[-1].append(array)
66
69
  param_stack.append(array)
67
70
  elif param == "]": # Array stop.
@@ -105,6 +108,6 @@ class OscMessage(object):
105
108
  """Convenience method for list(self) to get the list of parameters."""
106
109
  return list(self)
107
110
 
108
- def __iter__(self) -> Iterator[float]:
111
+ def __iter__(self) -> Iterator[Any]:
109
112
  """Returns an iterator over the parameters of this message."""
110
113
  return iter(self._parameters)