|
171 | 171 |
|
172 | 172 | try: |
173 | 173 | import sys |
| 174 | + import warnings |
174 | 175 | if 'multicast' not in sys.modules: |
175 | 176 | # skipcq |
176 | 177 | from . import multicast as multicast # pylint: disable=cyclic-import - skipcq: PYL-C0414 |
|
211 | 212 | ) |
212 | 213 |
|
213 | 214 |
|
| 215 | +_mcast_recv_bind_not_join_prefix = "Unusual call to multicast.joinstep with no groups." |
| 216 | + |
| 217 | + |
| 218 | +_mcast_recv_just_bind_code = """ |
| 219 | +sock = multicast.genSocket() if isock is None else isock |
| 220 | +sock.bind((multicast._MCAST_DEFAULT_GROUP, port)) |
| 221 | +
|
| 222 | +""" |
| 223 | + |
| 224 | + |
| 225 | +_mcast_recv_bind_not_join_msg = "...".join([ |
| 226 | + "Consider using", |
| 227 | + _mcast_recv_just_bind_code, |
| 228 | + "instead, for improved performance. Otherwise specify the multicast bind group.", |
| 229 | +]) |
| 230 | + |
| 231 | + |
| 232 | +_mcast_recv_empty_join_warn_message = "\n".join([ |
| 233 | + _mcast_recv_bind_not_join_prefix, |
| 234 | + _mcast_recv_bind_not_join_msg, |
| 235 | +]) |
| 236 | + |
| 237 | + |
| 238 | +_mcast_recv_lazy_bind_warning_message = "\n".join([ |
| 239 | + "Lazy call to multicast.joinstep with unspecified bind group.", |
| 240 | + f"Will bind to {multicast._MCAST_DEFAULT_BIND_IP}.", |
| 241 | + "Tip: Pass a value for bind_group to suppress this message", |
| 242 | + "(such as 'bind_group=multicast._MCAST_DEFAULT_BIND_IP')", |
| 243 | +]) |
| 244 | + |
| 245 | +_mcast_recv_join_only_multicast_warn_msg = "\n".join([ |
| 246 | + _mcast_recv_bind_not_join_prefix, |
| 247 | + "Just use socket.Socket.bind(...) for non-multicast networking.", |
| 248 | +]) |
| 249 | + |
| 250 | + |
| 251 | +def _validate_join_args(groups=None, port=None, iface=None, bind_group=None, isock=None): |
| 252 | + """Validates joinstep arguments. |
| 253 | +
|
| 254 | + This is a helper function and should NOT be called directly. |
| 255 | +
|
| 256 | + Returns: |
| 257 | + List of inputs after normalizing. |
| 258 | + """ |
| 259 | + if not groups: |
| 260 | + groups = [] |
| 261 | + if __debug__: # pragma: no branch |
| 262 | + if not bind_group: |
| 263 | + warnings.warn( |
| 264 | + _mcast_recv_empty_join_warn_message, |
| 265 | + category=SyntaxWarning, |
| 266 | + stacklevel=3, |
| 267 | + ) |
| 268 | + else: |
| 269 | + if multicast.env.validate_multicast_address(bind_group): |
| 270 | + groups = [bind_group] |
| 271 | + else: |
| 272 | + warnings.warn( |
| 273 | + _mcast_recv_join_only_multicast_warn_msg, |
| 274 | + category=SyntaxWarning, |
| 275 | + stacklevel=3, |
| 276 | + ) |
| 277 | + else: |
| 278 | + if multicast.env.validate_multicast_address(bind_group): |
| 279 | + groups = [bind_group] |
| 280 | + else: |
| 281 | + if __debug__ and not bind_group: # pragma: no branch |
| 282 | + if (len(groups) == 1) and (groups[0] != multicast._MCAST_DEFAULT_BIND_IP): |
| 283 | + warnings.warn( |
| 284 | + _mcast_recv_lazy_bind_warning_message, |
| 285 | + category=ResourceWarning, |
| 286 | + stacklevel=3, |
| 287 | + ) |
| 288 | + return (groups, port, iface, bind_group, isock) |
| 289 | + |
| 290 | + |
214 | 291 | def joinstep(groups, port, iface=None, bind_group=None, isock=None): |
215 | 292 | """ |
216 | 293 | Join multicast groups to prepare for receiving messages. |
@@ -292,14 +369,13 @@ def joinstep(groups, port, iface=None, bind_group=None, isock=None): |
292 | 369 |
|
293 | 370 |
|
294 | 371 | """ |
295 | | - if not groups: |
296 | | - groups = [] |
| 372 | + groups, _, _, bind_group, _ = _validate_join_args(groups=groups, bind_group=bind_group) |
297 | 373 | if isock is None: |
298 | 374 | sock = multicast.genSocket() |
299 | 375 | else: |
300 | 376 | sock = isock.dup() |
301 | 377 | try: |
302 | | - sock.bind(('224.0.0.1' if bind_group is None else bind_group, port)) |
| 378 | + sock.bind((multicast._MCAST_DEFAULT_BIND_IP if bind_group is None else bind_group, port)) |
303 | 379 | for group in groups: |
304 | 380 | mreq = _struct.pack( |
305 | 381 | '4sl' if iface is None else '4s4s', |
|
0 commit comments