Skip to content

Commit 5e3f5da

Browse files
Changes in file multicast/exceptions.py:
- fix for PYL-W1113 in class ShutdownCommandReceived Changes in file tests/test_exceptions.py: - added additional test cases for related changes
1 parent 6a6c35a commit 5e3f5da

File tree

2 files changed

+93
-10
lines changed

2 files changed

+93
-10
lines changed

multicast/exceptions.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# you may not use this file except in compliance with the License.
1010
# You may obtain a copy of the License at
1111
# ..........................................
12-
# http://www.github.com/reactive-firewall/python-repo/LICENSE.md
12+
# https://www.github.com/reactive-firewall/multicast/LICENSE.md
1313
# ..........................................
1414
# Unless required by applicable law or agreed to in writing, software
1515
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -284,7 +284,7 @@ class ShutdownCommandReceived(RuntimeError):
284284

285285
__name__ = """multicast.exceptions.ShutdownCommandReceived"""
286286

287-
def __init__(self, message="SHUTDOWN", *args, **kwargs):
287+
def __init__(self, *args, **kwargs):
288288
"""
289289
Initialize the ShutdownCommandReceived exception.
290290
@@ -345,10 +345,37 @@ def __init__(self, message="SHUTDOWN", *args, **kwargs):
345345
... except ShutdownCommandReceived as e:
346346
... str(e) == "Custom message"
347347
True
348+
349+
Testcase 7: Initialization with different call to init:
350+
A. - Initializes a ShutdownCommandReceived with a specific exit code.
351+
B. - Checks the message is still set, as normally would.
352+
C. - Checks the cause is set, as super class would.
353+
D. - Checks the specific exit code is NOT sixty-five (65) but rather still 143.
354+
355+
>>> pre_made_args = [ValueError("inner Cause"), "A Pre-made SHUTDOWN", int(65)]
356+
>>> error = ShutdownCommandReceived(*pre_made_args)
357+
>>> error.message
358+
'A Pre-made SHUTDOWN'
359+
>>> error.__cause__ #doctest: +ELLIPSIS
360+
ValueError...inner Cause...
361+
>>> error.exit_code
362+
143
348363
"""
364+
if len(args) > 0 and isinstance(args[0], BaseException):
365+
cause = args[0]
366+
args = args[1:]
367+
else:
368+
cause = kwargs.pop("__cause__", None)
369+
if len(args) > 0 and isinstance(args[0], str):
370+
message = args[0]
371+
args = args[1:]
372+
else:
373+
message = kwargs.pop("message", "SHUTDOWN")
349374
if not isinstance(message, str):
350375
raise TypeError("[CWE-573] message must be a string")
351376
super().__init__(message, *args, **kwargs)
377+
if cause is not None:
378+
self.__cause__ = cause
352379
self.message = message
353380
self.exit_code = 143 # Use SIGTERM exit code for graceful shutdown
354381

tests/test_exceptions.py

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
#! /usr/bin/env python
1+
#! /usr/bin/env python3
22
# -*- coding: utf-8 -*-
33

4-
# Python Test Repo Template
4+
# Python Multicast Repo
55
# ..................................
66
# Copyright (c) 2017-2024, Mr. Walls
77
# ..................................
88
# Licensed under MIT (the "License");
99
# you may not use this file except in compliance with the License.
1010
# You may obtain a copy of the License at
1111
# ..........................................
12-
# http://www.github.com/reactive-firewall/python-repo/LICENSE.md
12+
# https://www.github.com/reactive-firewall/multicast/LICENSE.md
1313
# ..........................................
1414
# Unless required by applicable law or agreed to in writing, software
1515
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,16 +20,26 @@
2020
__module__ = """tests"""
2121

2222
try:
23+
"""Handle imports with CWE-758 mitigation.
24+
25+
This implementation uses a nested try-except pattern to:
26+
1. Attempt direct context import
27+
2. Fallback to relative import
28+
3. Validate context module integrity
29+
4. Import required dependencies
30+
31+
References:
32+
- CWE-758: Reliance on Undefined, Unspecified, or Implementation-Defined Behavior
33+
"""
2334
try:
2435
import context
25-
except Exception as ImportErr: # pragma: no branch
26-
ImportErr = None
27-
del ImportErr # skipcq - cleanup any error leaks early
36+
except ImportError as _: # pragma: no branch
37+
del _ # skipcq - cleanup any error vars early
2838
from . import context
2939
if context.__name__ is None:
30-
raise ImportError("[CWE-758] Failed to import context") from None
40+
raise ModuleNotFoundError("[CWE-758] Failed to import context") from None
3141
else:
32-
from context import multicast
42+
from context import multicast # pylint: disable=cyclic-import - skipcq: PYL-R0401
3343
from context import unittest
3444
from context import BasicUsageTestSuite
3545
except Exception as _cause: # pragma: no branch
@@ -82,6 +92,52 @@ def test_command_execution_error_with_cause(self):
8292
self.assertEqual(error.message, "Test with cause")
8393
self.assertEqual(error.exit_code, 77)
8494

95+
def test_shutdown_received_error_with_args(self):
96+
"""
97+
Test ShutdownCommandReceived initialization with custom message and exit code.
98+
99+
Verifies that both the message and exit code are correctly assigned when
100+
explicitly provided during initialization.
101+
"""
102+
error = multicast.exceptions.ShutdownCommandReceived("Test Shutdown", 42)
103+
self.assertEqual(error.message, "Test Shutdown")
104+
self.assertIsNotEqual(error.exit_code, 42, "Unexpectedly was able to overide exit code!")
105+
self.assertEqual(error.exit_code, 143)
106+
107+
def test_shutdown_received_error_default_exit_code(self):
108+
"""Test ShutdownCommandReceived initialization with default exit code.
109+
110+
Verifies that the exit code defaults to 143 when only a message is provided.
111+
"""
112+
error = multicast.exceptions.ShutdownCommandReceived("Test Shutdown")
113+
self.assertEqual(error.exit_code, 143)
114+
115+
def test_shutdown_received_error_GIVEN_no_args(self):
116+
"""Test ShutdownCommandReceived initialization with default exit code.
117+
118+
Verifies that the exit code defaults to 143 when no arguments are provided.
119+
Verifies that the message defaults to 'SHUTDOWN' when no arguments are provided.
120+
"""
121+
error = multicast.exceptions.ShutdownCommandReceived()
122+
self.assertEqual(error.message, "SHUTDOWN")
123+
self.assertEqual(error.exit_code, 143)
124+
125+
def test_shutdown_received_error_with_cause(self):
126+
"""Test ShutdownCommandReceived initialization with a cause.
127+
128+
Verifies that the error properly chains exceptions when initialized with a
129+
cause, maintaining both the cause reference and custom attributes.
130+
"""
131+
test_cause = RuntimeError("test")
132+
self.assertIsNotNone(test_cause)
133+
error = multicast.exceptions.ShutdownCommandReceived(test_cause, "Shutdown with cause", 77)
134+
self.assertIsNotNone(error)
135+
self.assertIsNotNone(error.__cause__)
136+
self.assertEqual(error.__cause__, test_cause)
137+
self.assertEqual(error.message, "Shutdown with cause")
138+
self.assertIsNotEqual(error.exit_code, 77, "Unexpectedly was able to overide exit code!")
139+
self.assertEqual(error.exit_code, 143)
140+
85141

86142
# leave this part
87143
if __name__ == '__main__':

0 commit comments

Comments
 (0)