Skip to content

Commit 4b9c232

Browse files
[MERGE] Version 2.0 Development Cycle
* from PR #135 (HOTFIX-150-drop-wheels): [PATCH] fixup for better tox testing (- WIP PR #135 -) Fix typo in tox.ini [UPGRADE] Version 2.0 Development Cycle (- WIP #120 -) Changes in file .github/labeler.yml: - Imporved labeler rules - added labeler support for documentation - added labeler some support for invalid (best-effort) * New Features - Introduced new label categories: "Bash Lang" and "documentation" for better organization of files in the repository. * Version Updates - Updated the software version from "1.5.0" to "2.0.0-alpha" across multiple files, indicating a new major release. * Dependency Management - Revised dependency requirements for improved compatibility and updated versions for several packages. * Bug Fixes - Enhanced test methods to dynamically retrieve and assert package version, improving test reliability. * Configuration Changes - Streamlined CI configurations by removing support for older Python versions, focusing on 3.10, 3.11, and 3.12. - Removed Python linting configurations, indicating a shift in code quality enforcement strategies. * From PR #137 (Feature-improving-test-utility-stuff): [DOCUMENTATION] Slight improvement of meta-testing via doctests (- WIP #128 & #129 -) [DOCUMENTATION] improved docstrings as discussed in review (- WIP PR #137 -) [UPGRADE] Possible fixes for #128 and #129 as discussed. * Bug Fixes - Enhanced argument handling in command functions to prevent errors when no arguments are provided. * New Features - Improved flexibility in passing command arguments through variable-length argument lists. * From PR #136 (patch-documentation-min-cov): [DOCUMENTATION] Corrected exitcode description (no code change) (- WIP #79 -) [DOCUMENTATION] Improved documentation as per #79 [DOCUMENTATION] expands the documentation of the module (- WIP #79 -) * Documentation - Enhanced documentation for the multicast package, detailing its purpose and features related to multicast communication. - Improved clarity of method functionalities and parameters in the multicast/__main__.py file through expanded and reformatted docstrings. These updates aim to provide users with better guidance and understanding of the multicast functionalities available in the package.
3 parents 7d440dd + a6b71d8 + 7bb90b4 commit 4b9c232

File tree

3 files changed

+219
-72
lines changed

3 files changed

+219
-72
lines changed

multicast/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,22 @@
106106

107107
__doc__ = __prologue__ + """
108108
109+
The `multicast` package simplifies multicast communication in Python applications.
110+
111+
It provides tools for sending, receiving, and listening to multicast messages over UDP.
112+
The package includes command-line utilities and is designed to work with multiple Python
113+
versions. It supports IPv4 multicast addresses and is compliant with dynamic/private port
114+
ranges as per RFC-6335.
115+
116+
Key Features:
117+
- Easy-to-use interfaces for multicast communication.
118+
- Command-line tools for quick multicast operations.
119+
- Support for UDP multicast via IPv4.
120+
121+
Security Considerations:
122+
- Ensure proper data sanitization and validation to prevent injection attacks.
123+
- Be mindful of TTL settings to limit message propagation to the intended network segment.
124+
109125
Dynamic Imports:
110126
The sub-modules within "multicast" are interdependent, requiring access to each other's
111127
functionalities. These statements import sub-modules of "multicast" and assign them to

multicast/__main__.py

Lines changed: 111 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@
154154

155155
class McastNope(mtool):
156156
"""
157-
The trivial implementation of mtool.
157+
The trivial implementation of mtool.
158158
159-
Testing:
159+
Testing:
160160
161161
Testcase 0: First set up test fixtures by importing multicast.
162162
@@ -221,7 +221,8 @@ def setupArgs(cls, parser):
221221

222222
@staticmethod
223223
def NoOp(*args, **kwargs):
224-
"""Do Nothing.
224+
"""
225+
Do Nothing.
225226
226227
The meaning of Nothing. This function should be self-explanitory;
227228
it does 'no operation' i.e. nothing.
@@ -256,13 +257,30 @@ def NoOp(*args, **kwargs):
256257
return None # noqa
257258

258259
def doStep(self, *args, **kwargs):
260+
"""
261+
Executes a no-operation step.
262+
263+
This method calls the `NoOp` function with the provided arguments and returns the result.
264+
265+
Args:
266+
*args: Positional arguments passed to `NoOp`.
267+
**kwargs: Keyword arguments passed to `NoOp`.
268+
269+
Returns:
270+
The result of the `NoOp` function.
271+
"""
259272
return self.NoOp(*args, **kwargs)
260273

261274

262275
class McastRecvHearDispatch(mtool):
263276
"""
277+
The `McastRecvHearDispatch` class handles receiving and dispatching multicast messages.
264278
265-
Testing:
279+
This class listens for multicast messages on a specified group and port, and dispatches them
280+
to the appropriate handler. It is designed to work with both command-line tools and
281+
programmatic interfaces.
282+
283+
Testing:
266284
267285
Testcase 0: First set up test fixtures by importing multicast.
268286
@@ -330,9 +348,10 @@ class McastRecvHearDispatch(mtool):
330348

331349
@classmethod
332350
def setupArgs(cls, parser):
333-
"""Will attempt to add send args.
351+
"""
352+
Will attempt to add send args.
334353
335-
Testing:
354+
Testing:
336355
337356
Testcase 0: First set up test fixtures by importing multicast.
338357
@@ -437,6 +456,23 @@ def _help_deamon_dispatch(*args, **kwargs):
437456
return _useHear
438457

439458
def doStep(self, *args, **kwargs):
459+
"""
460+
Executes a multicast step based on the daemon dispatch.
461+
462+
This method selects either the `McastHEAR` or `McastRECV` class based on the daemon
463+
dispatch flag and executes the corresponding step.
464+
465+
The RECV (via McastRECV) is the primitive sub-command to recieve a single multicas hunk.
466+
The HEAR (via McastHEAR) is equivilant to running RECV in a loop to continually recive
467+
multiple hunks. Most use-case will probably want to use HEAR instead of RECV.
468+
469+
Args:
470+
*args: Positional arguments for the multicast step.
471+
**kwargs: Keyword arguments for the multicast step.
472+
473+
Returns:
474+
The result of the selected multicast class's `doStep` method.
475+
"""
440476
if self._help_deamon_dispatch(*args, **kwargs):
441477
__stub_class = hear.McastHEAR
442478
else:
@@ -457,6 +493,14 @@ def doStep(self, *args, **kwargs):
457493

458494

459495
class McastDispatch(mtool):
496+
"""
497+
The `McastDispatch` class is the main entry point for dispatching multicast tasks.
498+
499+
It provides a command-line interface for sending, receiving, and listening to multicast
500+
messages. The class handles argument parsing and dispatches the appropriate multicast
501+
tool based on the provided command.
502+
503+
"""
460504

461505
__proc__ = """multicast"""
462506

@@ -492,6 +536,18 @@ def useTool(tool, **kwargs):
492536
return (_is_done, theResult) # noqa
493537

494538
def doStep(self, *args):
539+
"""
540+
Executes the multicast tool based on parsed arguments.
541+
542+
This method parses the command-line arguments, selects the appropriate multicast tool, and
543+
executes it. If an error occurs during argument handling, it prints a warning message.
544+
545+
Args:
546+
*args: Command-line arguments for the multicast tool.
547+
548+
Returns:
549+
A tuple containing the exit status and the result of the tool execution.
550+
"""
495551
__EXIT_MSG = (1, "Unknown")
496552
try:
497553
try:
@@ -523,75 +579,76 @@ def doStep(self, *args):
523579

524580

525581
def main(*argv):
526-
"""Do main event stuff.
582+
"""
583+
Do main event stuff.
527584
528585
The main(*args) function in multicast is expected to return a POSIX compatible exit code.
529586
Regardless of errors the result as an 'exit code' (int) is returned.
530587
The only exception is multicast.__main__.main(*args) which will exit with the underlying
531588
return codes.
532589
The expected return codes are as follows:
533590
= 0: Any nominal state (i.e. no errors and possibly success)
534-
<=1: Any erroneous state (caveat: includes simple failure)
591+
=>1: Any erroneous state (caveat: includes simple failure)
535592
= 2: Any failed state
536593
= 3: Any undefined (but assumed erroneous) state
537-
> 0: implicitly erroneous and treated same as abs(exit_code) would be.
594+
=<0: implicitly erroneous and treated same as abs(exit_code) would be.
538595
539596
param iterable - argv - the array of arguments. Usually _sys.argv[1:]
540597
returns int - the Namespace parsed with the key-value pairs.
541598
542599
Minimal Acceptance Testing:
543600
544-
First set up test fixtures by importing multicast.
601+
First set up test fixtures by importing multicast.
545602
546-
>>> import multicast
547-
>>> multicast.send is not None
548-
True
549-
>>>
603+
>>> import multicast
604+
>>> multicast.send is not None
605+
True
606+
>>>
550607
551-
Testcase 0: main should return an int.
552-
A: Test that the multicast component is initialized.
553-
B: Test that the send component is initialized.
554-
C: Test that the send.main function is initialized.
555-
D: Test that the send.main function returns an int 0-3.
608+
Testcase 0: main should return an int.
609+
A: Test that the multicast component is initialized.
610+
B: Test that the send component is initialized.
611+
C: Test that the send.main function is initialized.
612+
D: Test that the send.main function returns an int 0-3.
556613
557-
>>> multicast.send is not None
558-
True
559-
>>> multicast.__main__.main is not None
560-
True
561-
>>> tst_fxtr_args = ['''SAY''', '''--port=1234''', '''--message''', '''is required''']
562-
>>> (test_fixture, junk_ignore) = multicast.__main__.main(tst_fxtr_args)
563-
>>> test_fixture is not None
564-
True
565-
>>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS
566-
<...int...>
567-
>>> int(test_fixture) >= int(0)
568-
True
569-
>>> int(test_fixture) < int(4)
570-
True
571-
>>>
614+
>>> multicast.send is not None
615+
True
616+
>>> multicast.__main__.main is not None
617+
True
618+
>>> tst_fxtr_args = ['''SAY''', '''--port=1234''', '''--message''', '''is required''']
619+
>>> (test_fixture, junk_ignore) = multicast.__main__.main(tst_fxtr_args)
620+
>>> test_fixture is not None
621+
True
622+
>>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS
623+
<...int...>
624+
>>> int(test_fixture) >= int(0)
625+
True
626+
>>> int(test_fixture) < int(4)
627+
True
628+
>>>
572629
573630
574-
Testcase 1: main should return an int.
575-
A: Test that the multicast component is initialized.
576-
B: Test that the recv component is initialized.
577-
C: Test that the main(recv) function is initialized.
578-
D: Test that the main(recv) function returns an int 0-3.
631+
Testcase 1: main should return an int.
632+
A: Test that the multicast component is initialized.
633+
B: Test that the recv component is initialized.
634+
C: Test that the main(recv) function is initialized.
635+
D: Test that the main(recv) function returns an int 0-3.
579636
580-
>>> multicast.recv is not None
581-
True
582-
>>> multicast.__main__.main is not None
583-
True
584-
>>> tst_fxtr_args = ['''RECV''', '''--port=1234''', '''--group''', '''224.0.0.1''']
585-
>>> (test_fixture, junk_ignore) = multicast.__main__.main(tst_fxtr_args)
586-
>>> test_fixture is not None
587-
True
588-
>>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS
589-
<...int...>
590-
>>> int(test_fixture) >= int(0)
591-
True
592-
>>> int(test_fixture) < int(4)
593-
True
594-
>>>
637+
>>> multicast.recv is not None
638+
True
639+
>>> multicast.__main__.main is not None
640+
True
641+
>>> tst_fxtr_args = ['''RECV''', '''--port=1234''', '''--group''', '''224.0.0.1''']
642+
>>> (test_fixture, junk_ignore) = multicast.__main__.main(tst_fxtr_args)
643+
>>> test_fixture is not None
644+
True
645+
>>> type(test_fixture) #doctest: -DONT_ACCEPT_BLANKLINE, +ELLIPSIS
646+
<...int...>
647+
>>> int(test_fixture) >= int(0)
648+
True
649+
>>> int(test_fixture) < int(4)
650+
True
651+
>>>
595652
596653
597654
"""

0 commit comments

Comments
 (0)