1class LockPicker_0MI0600328:
2 DEFAULT_VALUES = {
3 int: int(),
4 str: str(),
5 float: float(),
6 bool: bool(),
7 list: list(),
8 dict: dict(),
9 set: set(),
10 tuple: tuple(),
11 complex: complex()
12 }
13
14 def __init__(self, lock):
15 self.lock = lock
16 self.args = []
17
18 def _handle_type_error(self, exc):
19 if exc.position is None:
20 return [None] * exc.expected
21
22 args_copy = self.args[:]
23 position = exc.position - 1
24 expected_type = exc.expected
25
26 args_copy[position] = self.DEFAULT_VALUES[expected_type]
27 return args_copy
28
29 def _handle_value_error(self, exc):
30 args_copy = self.args[:]
31 position = exc.position - 1
32 expected_value = exc.expected
33
34 args_copy[position] = expected_value
35 return args_copy
36
37 def unlock(self):
38 while True:
39 try:
40 if self.lock.pick(*self.args):
41 break
42 except TypeError as exc:
43 self.args = self._handle_type_error(exc)
44 except ValueError as exc:
45 self.args = self._handle_value_error(exc)
Резултат от контролното:
17/25 верни отговора.
14 точки.
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Йоан Байчев
13.11.2024 01:34Имах два файла challenge.py и качих грешния първо
|
| f | 1 | class LockPicker_0MI0600328: | f | 1 | class LockPicker_0MI0600328: |
| 2 | DEFAULT_VALUES = { | 2 | DEFAULT_VALUES = { | ||
| 3 | int: int(), | 3 | int: int(), | ||
| 4 | str: str(), | 4 | str: str(), | ||
| 5 | float: float(), | 5 | float: float(), | ||
| 6 | bool: bool(), | 6 | bool: bool(), | ||
| 7 | list: list(), | 7 | list: list(), | ||
| 8 | dict: dict(), | 8 | dict: dict(), | ||
| 9 | set: set(), | 9 | set: set(), | ||
| 10 | tuple: tuple(), | 10 | tuple: tuple(), | ||
| 11 | complex: complex() | 11 | complex: complex() | ||
| 12 | } | 12 | } | ||
| 13 | 13 | ||||
| 14 | def __init__(self, lock): | 14 | def __init__(self, lock): | ||
| 15 | self.lock = lock | 15 | self.lock = lock | ||
| 16 | self.args = [] | 16 | self.args = [] | ||
| 17 | 17 | ||||
| 18 | def _handle_type_error(self, exc): | 18 | def _handle_type_error(self, exc): | ||
| 19 | if exc.position is None: | 19 | if exc.position is None: | ||
| 20 | return [None] * exc.expected | 20 | return [None] * exc.expected | ||
| 21 | 21 | ||||
| 22 | args_copy = self.args[:] | 22 | args_copy = self.args[:] | ||
| 23 | position = exc.position - 1 | 23 | position = exc.position - 1 | ||
| 24 | expected_type = exc.expected | 24 | expected_type = exc.expected | ||
| 25 | 25 | ||||
| t | 26 | args_copy[position] = self.DEFAULT_VALUES[expected_type] if expected_type in self.DEFAULT_VALUES else None | t | 26 | args_copy[position] = self.DEFAULT_VALUES[expected_type] |
| 27 | return args_copy | 27 | return args_copy | ||
| 28 | 28 | ||||
| 29 | def _handle_value_error(self, exc): | 29 | def _handle_value_error(self, exc): | ||
| 30 | args_copy = self.args[:] | 30 | args_copy = self.args[:] | ||
| 31 | position = exc.position - 1 | 31 | position = exc.position - 1 | ||
| 32 | expected_value = exc.expected | 32 | expected_value = exc.expected | ||
| 33 | 33 | ||||
| 34 | args_copy[position] = expected_value | 34 | args_copy[position] = expected_value | ||
| 35 | return args_copy | 35 | return args_copy | ||
| 36 | 36 | ||||
| 37 | def unlock(self): | 37 | def unlock(self): | ||
| 38 | while True: | 38 | while True: | ||
| 39 | try: | 39 | try: | ||
| 40 | if self.lock.pick(*self.args): | 40 | if self.lock.pick(*self.args): | ||
| 41 | break | 41 | break | ||
| 42 | except TypeError as exc: | 42 | except TypeError as exc: | ||
| 43 | self.args = self._handle_type_error(exc) | 43 | self.args = self._handle_type_error(exc) | ||
| 44 | except ValueError as exc: | 44 | except ValueError as exc: | ||
| 45 | self.args = self._handle_value_error(exc) | 45 | self.args = self._handle_value_error(exc) | ||
| 46 | 46 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | class LockPicker_0MI0600328: | f | 1 | class LockPicker_0MI0600328: |
| 2 | DEFAULT_VALUES = { | 2 | DEFAULT_VALUES = { | ||
| 3 | int: int(), | 3 | int: int(), | ||
| 4 | str: str(), | 4 | str: str(), | ||
| 5 | float: float(), | 5 | float: float(), | ||
| 6 | bool: bool(), | 6 | bool: bool(), | ||
| 7 | list: list(), | 7 | list: list(), | ||
| 8 | dict: dict(), | 8 | dict: dict(), | ||
| 9 | set: set(), | 9 | set: set(), | ||
| 10 | tuple: tuple(), | 10 | tuple: tuple(), | ||
| 11 | complex: complex() | 11 | complex: complex() | ||
| 12 | } | 12 | } | ||
| 13 | 13 | ||||
| 14 | def __init__(self, lock): | 14 | def __init__(self, lock): | ||
| 15 | self.lock = lock | 15 | self.lock = lock | ||
| 16 | self.args = [] | 16 | self.args = [] | ||
| 17 | 17 | ||||
| 18 | def _handle_type_error(self, exc): | 18 | def _handle_type_error(self, exc): | ||
| 19 | if exc.position is None: | 19 | if exc.position is None: | ||
| 20 | return [None] * exc.expected | 20 | return [None] * exc.expected | ||
| 21 | 21 | ||||
| 22 | args_copy = self.args[:] | 22 | args_copy = self.args[:] | ||
| 23 | position = exc.position - 1 | 23 | position = exc.position - 1 | ||
| 24 | expected_type = exc.expected | 24 | expected_type = exc.expected | ||
| 25 | 25 | ||||
| t | 26 | args_copy[position] = self.DEFAULT_VALUES.get(expected_type, None) | t | 26 | args_copy[position] = self.DEFAULT_VALUES[expected_type] if expected_type in self.DEFAULT_VALUES else None |
| 27 | return args_copy | 27 | return args_copy | ||
| 28 | 28 | ||||
| 29 | def _handle_value_error(self, exc): | 29 | def _handle_value_error(self, exc): | ||
| 30 | args_copy = self.args[:] | 30 | args_copy = self.args[:] | ||
| 31 | position = exc.position - 1 | 31 | position = exc.position - 1 | ||
| 32 | expected_value = exc.expected | 32 | expected_value = exc.expected | ||
| 33 | 33 | ||||
| 34 | args_copy[position] = expected_value | 34 | args_copy[position] = expected_value | ||
| 35 | return args_copy | 35 | return args_copy | ||
| 36 | 36 | ||||
| 37 | def unlock(self): | 37 | def unlock(self): | ||
| 38 | while True: | 38 | while True: | ||
| 39 | try: | 39 | try: | ||
| 40 | if self.lock.pick(*self.args): | 40 | if self.lock.pick(*self.args): | ||
| 41 | break | 41 | break | ||
| 42 | except TypeError as exc: | 42 | except TypeError as exc: | ||
| 43 | self.args = self._handle_type_error(exc) | 43 | self.args = self._handle_type_error(exc) | ||
| 44 | except ValueError as exc: | 44 | except ValueError as exc: | ||
| 45 | self.args = self._handle_value_error(exc) | 45 | self.args = self._handle_value_error(exc) | ||
| 46 | 46 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| f | 1 | class LockPicker_0MI0600328: | f | 1 | class LockPicker_0MI0600328: |
| 2 | DEFAULT_VALUES = { | 2 | DEFAULT_VALUES = { | ||
| n | 3 | int: 0, | n | 3 | int: int(), |
| 4 | str: "", | 4 | str: str(), | ||
| 5 | float: 0.0, | 5 | float: float(), | ||
| 6 | bool: False, | 6 | bool: bool(), | ||
| 7 | list: [], | 7 | list: list(), | ||
| 8 | dict: {}, | 8 | dict: dict(), | ||
| 9 | set: set(), | 9 | set: set(), | ||
| n | 10 | tuple: (), | n | 10 | tuple: tuple(), |
| 11 | complex: complex(0, 0) | 11 | complex: complex() | ||
| 12 | } | 12 | } | ||
| 13 | 13 | ||||
| 14 | def __init__(self, lock): | 14 | def __init__(self, lock): | ||
| 15 | self.lock = lock | 15 | self.lock = lock | ||
| n | 16 | self.attempted_args = set() | n | 16 | self.args = [] |
| 17 | 17 | ||||
| n | 18 | def _handle_type_error(self, exc, args): | n | 18 | def _handle_type_error(self, exc): |
| 19 | if exc.position is None: | 19 | if exc.position is None: | ||
| n | 20 | expected_count = exc.expected | n | ||
| 21 | return [None] * expected_count | 20 | return [None] * exc.expected | ||
| 22 | 21 | ||||
| n | n | 22 | args_copy = self.args[:] | ||
| 23 | position = exc.position - 1 | 23 | position = exc.position - 1 | ||
| 24 | expected_type = exc.expected | 24 | expected_type = exc.expected | ||
| n | 25 | n | |||
| 26 | if (position, expected_type) in self.attempted_args: | ||||
| 27 | return args | ||||
| 28 | |||||
| 29 | args[position] = self.DEFAULT_VALUES.get(expected_type, None) | ||||
| 30 | self.attempted_args.add((position, expected_type)) | ||||
| 31 | return args | ||||
| 32 | 25 | ||||
| n | n | 26 | args_copy[position] = self.DEFAULT_VALUES.get(expected_type, None) | ||
| 27 | return args_copy | ||||
| 28 | |||||
| 33 | def _handle_value_error(self, ex, args): | 29 | def _handle_value_error(self, exc): | ||
| 30 | args_copy = self.args[:] | ||||
| 34 | position = ex.position - 1 | 31 | position = exc.position - 1 | ||
| 35 | expected_value = ex.expected | 32 | expected_value = exc.expected | ||
| 33 | |||||
| 36 | args[position] = expected_value | 34 | args_copy[position] = expected_value | ||
| 37 | return args | 35 | return args_copy | ||
| 38 | 36 | ||||
| 39 | def unlock(self): | 37 | def unlock(self): | ||
| n | 40 | args = [] | n | ||
| 41 | |||||
| 42 | while True: | 38 | while True: | ||
| 43 | try: | 39 | try: | ||
| n | 44 | if self.lock.pick(*args): | n | 40 | if self.lock.pick(*self.args): |
| 45 | break | 41 | break | ||
| t | 46 | except Exception as ex: | t | 42 | except TypeError as exc: |
| 47 | if isinstance(ex, TypeError): | ||||
| 48 | args = self._handle_type_error(ex, args) | 43 | self.args = self._handle_type_error(exc) | ||
| 49 | elif isinstance(ex, ValueError): | 44 | except ValueError as exc: | ||
| 50 | args = self._handle_value_error(ex, args) | 45 | self.args = self._handle_value_error(exc) | ||
| 51 | 46 |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| n | 1 | import unittest | n | 1 | class LockPicker_0MI0600328: |
| 2 | DEFAULT_VALUES = { | ||||
| 3 | int: 0, | ||||
| 4 | str: "", | ||||
| 5 | float: 0.0, | ||||
| 6 | bool: False, | ||||
| 7 | list: [], | ||||
| 8 | dict: {}, | ||||
| 9 | set: set(), | ||||
| 10 | tuple: (), | ||||
| 11 | complex: complex(0, 0) | ||||
| 12 | } | ||||
| 2 | 13 | ||||
| n | 3 | def optimize_exception_check(attr_name): | n | 14 | def __init__(self, lock): |
| 4 | def decorator(func): | 15 | self.lock = lock | ||
| 5 | def wrapper(self, exc_type): | 16 | self.attempted_args = set() | ||
| 6 | cache = getattr(self, attr_name) | ||||
| 7 | if exc_type in cache: | ||||
| 8 | return True | ||||
| 9 | 17 | ||||
| n | 10 | result = func(self, exc_type) # True or False | n | 18 | def _handle_type_error(self, exc, args): |
| 11 | if result: | 19 | if exc.position is None: | ||
| 12 | cache.add(exc_type) | 20 | expected_count = exc.expected | ||
| 13 | return result | 21 | return [None] * expected_count | ||
| 14 | return wrapper | ||||
| 15 | return decorator | ||||
| 16 | 22 | ||||
| n | n | 23 | position = exc.position - 1 | ||
| 24 | expected_type = exc.expected | ||||
| 25 | |||||
| 26 | if (position, expected_type) in self.attempted_args: | ||||
| 27 | return args | ||||
| 28 | |||||
| 29 | args[position] = self.DEFAULT_VALUES.get(expected_type, None) | ||||
| 30 | self.attempted_args.add((position, expected_type)) | ||||
| 31 | return args | ||||
| 17 | 32 | ||||
| n | 18 | class ProtectedSection: | n | 33 | def _handle_value_error(self, ex, args): |
| 19 | __counter = 0 | 34 | position = ex.position - 1 | ||
| 35 | expected_value = ex.expected | ||||
| 36 | args[position] = expected_value | ||||
| 37 | return args | ||||
| 20 | 38 | ||||
| n | 21 | def __init__(self, log=(), suppress=()): | n | 39 | def unlock(self): |
| 22 | if log is not None: | 40 | args = [] | ||
| 23 | for exc in log: | ||||
| 24 | if not issubclass(exc, Exception): | ||||
| 25 | raise TypeError("Not a valid exception type") | ||||
| 26 | 41 | ||||
| n | 27 | if suppress is not None: | n | 42 | while True: |
| 28 | for exc in suppress: | 43 | try: | ||
| 29 | if not issubclass(exc, Exception): | 44 | if self.lock.pick(*args): | ||
| 30 | raise TypeError("Not a valid exception type") | 45 | break | ||
| 46 | except Exception as ex: | ||||
| 47 | if isinstance(ex, TypeError): | ||||
| 48 | args = self._handle_type_error(ex, args) | ||||
| 49 | elif isinstance(ex, ValueError): | ||||
| 50 | args = self._handle_value_error(ex, args) | ||||
| 31 | 51 | ||||
| t | 32 | self._current_exception = None # Saves the specific or last "updated" exception in case of reuse of an already created instance | t | ||
| 33 | self.log_exceptions = set(log) | ||||
| 34 | self.suppress_exceptions = set(suppress) | ||||
| 35 | self._checked_exceptions_logs = set() # Optimization to avoid checking one exception n times | ||||
| 36 | self._checked_exceptions_suppress = set() # Optimization to avoid checking one exception n times | ||||
| 37 | self.exceptions_by_session = {} # Dictionary to store exceptions with their session ID | ||||
| 38 | |||||
| 39 | @optimize_exception_check("_checked_exceptions_logs") | ||||
| 40 | def is_exception_logged(self, exc_type): | ||||
| 41 | return exc_type in self.log_exceptions | ||||
| 42 | |||||
| 43 | @optimize_exception_check("_checked_exceptions_suppress") | ||||
| 44 | def is_exception_suppressed(self, exc_type): | ||||
| 45 | return exc_type in self.suppress_exceptions | ||||
| 46 | |||||
| 47 | def __enter__(self): | ||||
| 48 | self._current_exception = None | ||||
| 49 | return self | ||||
| 50 | |||||
| 51 | def __exit__(self, exc_type, exc_value, traceback): | ||||
| 52 | if exc_type: | ||||
| 53 | if self.is_exception_logged(exc_type): | ||||
| 54 | self.exceptions_by_session[self.__counter] = exc_value | ||||
| 55 | self.__counter += 1 | ||||
| 56 | self._current_exception = exc_value | ||||
| 57 | return True | ||||
| 58 | |||||
| 59 | if self.is_exception_suppressed(exc_type): | ||||
| 60 | self._current_exception = None | ||||
| 61 | self.__counter += 1 | ||||
| 62 | return True | ||||
| 63 | |||||
| 64 | return False | ||||
| 65 | |||||
| 66 | @property | ||||
| 67 | def exception(self): | ||||
| 68 | return self._current_exception | ||||
| 69 | |||||
| 70 | @property | ||||
| 71 | def exceptions(self): | ||||
| 72 | return self.exceptions_by_session | ||||
| 73 | |||||
| 74 | def get_exception_by_session(self, session_id): | ||||
| 75 | return self.exceptions_by_session.get(session_id, None) | ||||
| 76 | |||||
| 77 | |||||
| 78 | class TestProtectedSection(unittest.TestCase): | ||||
| 79 | |||||
| 80 | def test_log_exception(self): | ||||
| 81 | with ProtectedSection(log=(ZeroDivisionError,)) as err: | ||||
| 82 | x = 1 / 0 | ||||
| 83 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 84 | self.assertEqual(str(err.exception), "division by zero") | ||||
| 85 | |||||
| 86 | def test_suppress_exception(self): | ||||
| 87 | with ProtectedSection(suppress=(ZeroDivisionError,)) as err: | ||||
| 88 | x = 1 / 0 | ||||
| 89 | self.assertIsNone(err.exception) | ||||
| 90 | |||||
| 91 | def test_log_and_suppress_priority(self): | ||||
| 92 | with ProtectedSection(log=(ZeroDivisionError,), suppress=(TypeError, ZeroDivisionError)) as err: | ||||
| 93 | x = 1 / 0 | ||||
| 94 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 95 | self.assertEqual(str(err.exception), "division by zero") | ||||
| 96 | |||||
| 97 | def test_log_and_suppress_priority_with_multiple_exceptions(self): | ||||
| 98 | with ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ZeroDivisionError)) as err: | ||||
| 99 | x = 1 / 0 | ||||
| 100 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 101 | |||||
| 102 | def test_no_exception(self): | ||||
| 103 | with ProtectedSection(log=(), suppress=(TypeError,)) as err: | ||||
| 104 | x = 1 + 1 | ||||
| 105 | self.assertIsNone(err.exception) | ||||
| 106 | |||||
| 107 | def test_unhandled_exception(self): | ||||
| 108 | with self.assertRaises(ValueError): | ||||
| 109 | with ProtectedSection(log=(ZeroDivisionError,), suppress=(TypeError,)) as err: | ||||
| 110 | raise ValueError("err") | ||||
| 111 | self.assertIsNone(err.exception) | ||||
| 112 | |||||
| 113 | def test_empty_log_and_suppress(self): | ||||
| 114 | with self.assertRaises(ZeroDivisionError): | ||||
| 115 | with ProtectedSection() as err: | ||||
| 116 | x = 1 / 0 | ||||
| 117 | self.assertIsNone(err.exception) | ||||
| 118 | |||||
| 119 | def test_reuse_protected_section(self): | ||||
| 120 | protected_section = ProtectedSection(log=(ZeroDivisionError,)) | ||||
| 121 | |||||
| 122 | with protected_section as err: | ||||
| 123 | x = 1 / 0 | ||||
| 124 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 125 | |||||
| 126 | with protected_section as err: | ||||
| 127 | x = 1 + 1 | ||||
| 128 | self.assertIsNone(err.exception) | ||||
| 129 | |||||
| 130 | with self.assertRaises(TypeError): | ||||
| 131 | with protected_section as err: | ||||
| 132 | x = "text" + 5 | ||||
| 133 | self.assertIsNone(err.exception) | ||||
| 134 | |||||
| 135 | with protected_section as err: | ||||
| 136 | x = 1 / 0 | ||||
| 137 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 138 | |||||
| 139 | def test_suppress_then_log_exception(self): | ||||
| 140 | with ProtectedSection(log=(IndexError,), suppress=(ZeroDivisionError,)) as err: | ||||
| 141 | y = [][2332] | ||||
| 142 | self.assertIsInstance(err.exception, IndexError) | ||||
| 143 | |||||
| 144 | def test_suppress_then_no_exception(self): | ||||
| 145 | protected_section = ProtectedSection(suppress=(ZeroDivisionError,)) | ||||
| 146 | |||||
| 147 | with protected_section as err: | ||||
| 148 | x = 1 / 0 | ||||
| 149 | self.assertIsNone(err.exception) | ||||
| 150 | |||||
| 151 | with protected_section as err: | ||||
| 152 | x = 1 + 1 | ||||
| 153 | self.assertIsNone(err.exception) | ||||
| 154 | |||||
| 155 | def test_complex_combination(self): | ||||
| 156 | protected_section = ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ValueError)) | ||||
| 157 | |||||
| 158 | with protected_section as err: | ||||
| 159 | x = 1 / 0 | ||||
| 160 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 161 | self.assertEqual(str(err.exception), "division by zero") | ||||
| 162 | |||||
| 163 | with protected_section as err: | ||||
| 164 | x = "text" + 5 | ||||
| 165 | self.assertIsNone(err.exception) | ||||
| 166 | |||||
| 167 | with protected_section as err: | ||||
| 168 | y = [][2332] | ||||
| 169 | self.assertIsInstance(err.exception, IndexError) | ||||
| 170 | |||||
| 171 | with protected_section as err: | ||||
| 172 | raise ValueError("err") | ||||
| 173 | self.assertIsNone(err.exception) | ||||
| 174 | |||||
| 175 | with self.assertRaises(KeyError): | ||||
| 176 | with protected_section as err: | ||||
| 177 | raise KeyError("key err") | ||||
| 178 | self.assertIsNone(err.exception) | ||||
| 179 | |||||
| 180 | with protected_section as err: | ||||
| 181 | x = 1 + 1 | ||||
| 182 | self.assertIsNone(err.exception) | ||||
| 183 | |||||
| 184 | with protected_section as err: | ||||
| 185 | x = "text" + 5 | ||||
| 186 | self.assertIsNone(err.exception) | ||||
| 187 | |||||
| 188 | with protected_section as err: | ||||
| 189 | x = 1 / 0 | ||||
| 190 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 191 | |||||
| 192 | with protected_section as err: | ||||
| 193 | raise ValueError("another error") | ||||
| 194 | self.assertIsNone(err.exception) | ||||
| 195 | |||||
| 196 | with protected_section as err: | ||||
| 197 | z = [][999] | ||||
| 198 | self.assertIsInstance(err.exception, IndexError) | ||||
| 199 | |||||
| 200 | with protected_section as err: | ||||
| 201 | x = "string" + 5 | ||||
| 202 | self.assertIsNone(err.exception) | ||||
| 203 | |||||
| 204 | with protected_section as err: | ||||
| 205 | x = 1 / 0 | ||||
| 206 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 207 | |||||
| 208 | with protected_section as err: | ||||
| 209 | result = 42 * 42 | ||||
| 210 | self.assertIsNone(err.exception) | ||||
| 211 | |||||
| 212 | def test_complex_combination_with_empty_cases(self): | ||||
| 213 | protected_section = ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ValueError)) | ||||
| 214 | |||||
| 215 | with protected_section as err: | ||||
| 216 | x = 1 / 0 | ||||
| 217 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 218 | self.assertEqual(str(err.exception), "division by zero") | ||||
| 219 | |||||
| 220 | with protected_section as err: | ||||
| 221 | x = "text" + 5 | ||||
| 222 | self.assertIsNone(err.exception) | ||||
| 223 | |||||
| 224 | with protected_section as err: | ||||
| 225 | y = [][2332] | ||||
| 226 | self.assertIsInstance(err.exception, IndexError) | ||||
| 227 | |||||
| 228 | with protected_section as err: | ||||
| 229 | raise ValueError("err") | ||||
| 230 | self.assertIsNone(err.exception) | ||||
| 231 | |||||
| 232 | with self.assertRaises(KeyError): | ||||
| 233 | with protected_section as err: | ||||
| 234 | raise KeyError("key error") | ||||
| 235 | self.assertIsNone(err.exception) | ||||
| 236 | |||||
| 237 | with protected_section as err: | ||||
| 238 | x = 1 + 1 | ||||
| 239 | self.assertIsNone(err.exception) | ||||
| 240 | |||||
| 241 | with protected_section as err: | ||||
| 242 | x = "text" + 5 | ||||
| 243 | self.assertIsNone(err.exception) | ||||
| 244 | |||||
| 245 | with protected_section as err: | ||||
| 246 | x = 1 / 0 | ||||
| 247 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 248 | |||||
| 249 | with protected_section as err: | ||||
| 250 | raise ValueError("another error") | ||||
| 251 | self.assertIsNone(err.exception) | ||||
| 252 | |||||
| 253 | with protected_section as err: | ||||
| 254 | z = [][999] | ||||
| 255 | self.assertIsInstance(err.exception, IndexError) | ||||
| 256 | |||||
| 257 | with protected_section as err: | ||||
| 258 | x = "string" + 5 | ||||
| 259 | self.assertIsNone(err.exception) | ||||
| 260 | |||||
| 261 | with protected_section as err: | ||||
| 262 | x = 1 / 0 | ||||
| 263 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 264 | |||||
| 265 | with protected_section as err: | ||||
| 266 | result = 42 * 42 | ||||
| 267 | self.assertIsNone(err.exception) | ||||
| 268 | |||||
| 269 | protected_section_empty_log = ProtectedSection(log=(), suppress=(TypeError,)) | ||||
| 270 | |||||
| 271 | with protected_section_empty_log as err: | ||||
| 272 | x = "text" + 5 | ||||
| 273 | self.assertIsNone(err.exception) | ||||
| 274 | |||||
| 275 | with self.assertRaises(ZeroDivisionError): | ||||
| 276 | with protected_section_empty_log as err: | ||||
| 277 | x = 1 / 0 | ||||
| 278 | self.assertIsNone(err.exception) | ||||
| 279 | |||||
| 280 | protected_section_empty_suppress = ProtectedSection(log=(ZeroDivisionError,), suppress=()) | ||||
| 281 | |||||
| 282 | with protected_section_empty_suppress as err: | ||||
| 283 | x = 1 / 0 | ||||
| 284 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||||
| 285 | |||||
| 286 | with self.assertRaises(TypeError): | ||||
| 287 | with protected_section_empty_suppress as err: | ||||
| 288 | x = "text" + 5 | ||||
| 289 | self.assertIsNone(err.exception) | ||||
| 290 | |||||
| 291 | protected_section_empty_both = ProtectedSection() | ||||
| 292 | |||||
| 293 | with self.assertRaises(ZeroDivisionError): | ||||
| 294 | with protected_section_empty_both as err: | ||||
| 295 | x = 1 / 0 | ||||
| 296 | self.assertIsNone(err.exception) | ||||
| 297 | |||||
| 298 | with self.assertRaises(TypeError): | ||||
| 299 | with protected_section_empty_both as err: | ||||
| 300 | x = "text" + 5 | ||||
| 301 | self.assertIsNone(err.exception) | ||||
| 302 | |||||
| 303 | with protected_section_empty_both as err: | ||||
| 304 | x = 1 + 1 | ||||
| 305 | self.assertIsNone(err.exception) | ||||
| 306 | |||||
| 307 | # Viktor ? | ||||
| 308 | def test_reuse_protected_section_with_reset_exception(self): | ||||
| 309 | protected_section = ProtectedSection(log=(ValueError,)) | ||||
| 310 | |||||
| 311 | with protected_section as cm1: | ||||
| 312 | raise ValueError('Text 1') | ||||
| 313 | self.assertIsInstance(cm1.exception, ValueError) | ||||
| 314 | self.assertEqual(str(cm1.exception), 'Text 1') | ||||
| 315 | |||||
| 316 | with protected_section as cm2: | ||||
| 317 | raise ValueError('Text 2') | ||||
| 318 | self.assertIsInstance(cm2.exception, ValueError) | ||||
| 319 | self.assertEqual(str(cm2.exception), 'Text 2') | ||||
| 320 | |||||
| 321 | self.assertEqual(str(cm1.exception), 'Text 2') | ||||
| 322 | |||||
| 323 | |||||
| 324 | if __name__ == "__main__": | ||||
| 325 | unittest.main() |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||
| t | 1 | import unittest | t | 1 | import unittest |
| 2 | 2 | ||||
| 3 | def optimize_exception_check(attr_name): | 3 | def optimize_exception_check(attr_name): | ||
| 4 | def decorator(func): | 4 | def decorator(func): | ||
| 5 | def wrapper(self, exc_type): | 5 | def wrapper(self, exc_type): | ||
| 6 | cache = getattr(self, attr_name) | 6 | cache = getattr(self, attr_name) | ||
| 7 | if exc_type in cache: | 7 | if exc_type in cache: | ||
| 8 | return True | 8 | return True | ||
| 9 | 9 | ||||
| 10 | result = func(self, exc_type) # True or False | 10 | result = func(self, exc_type) # True or False | ||
| 11 | if result: | 11 | if result: | ||
| 12 | cache.add(exc_type) | 12 | cache.add(exc_type) | ||
| 13 | return result | 13 | return result | ||
| 14 | return wrapper | 14 | return wrapper | ||
| 15 | return decorator | 15 | return decorator | ||
| 16 | 16 | ||||
| 17 | 17 | ||||
| 18 | class ProtectedSection: | 18 | class ProtectedSection: | ||
| 19 | __counter = 0 | 19 | __counter = 0 | ||
| 20 | 20 | ||||
| 21 | def __init__(self, log=(), suppress=()): | 21 | def __init__(self, log=(), suppress=()): | ||
| 22 | if log is not None: | 22 | if log is not None: | ||
| 23 | for exc in log: | 23 | for exc in log: | ||
| 24 | if not issubclass(exc, Exception): | 24 | if not issubclass(exc, Exception): | ||
| 25 | raise TypeError("Not a valid exception type") | 25 | raise TypeError("Not a valid exception type") | ||
| 26 | 26 | ||||
| 27 | if suppress is not None: | 27 | if suppress is not None: | ||
| 28 | for exc in suppress: | 28 | for exc in suppress: | ||
| 29 | if not issubclass(exc, Exception): | 29 | if not issubclass(exc, Exception): | ||
| 30 | raise TypeError("Not a valid exception type") | 30 | raise TypeError("Not a valid exception type") | ||
| 31 | 31 | ||||
| 32 | self._current_exception = None # Saves the specific or last "updated" exception in case of reuse of an already created instance | 32 | self._current_exception = None # Saves the specific or last "updated" exception in case of reuse of an already created instance | ||
| 33 | self.log_exceptions = set(log) | 33 | self.log_exceptions = set(log) | ||
| 34 | self.suppress_exceptions = set(suppress) | 34 | self.suppress_exceptions = set(suppress) | ||
| 35 | self._checked_exceptions_logs = set() # Optimization to avoid checking one exception n times | 35 | self._checked_exceptions_logs = set() # Optimization to avoid checking one exception n times | ||
| 36 | self._checked_exceptions_suppress = set() # Optimization to avoid checking one exception n times | 36 | self._checked_exceptions_suppress = set() # Optimization to avoid checking one exception n times | ||
| 37 | self.exceptions_by_session = {} # Dictionary to store exceptions with their session ID | 37 | self.exceptions_by_session = {} # Dictionary to store exceptions with their session ID | ||
| 38 | 38 | ||||
| 39 | @optimize_exception_check("_checked_exceptions_logs") | 39 | @optimize_exception_check("_checked_exceptions_logs") | ||
| 40 | def is_exception_logged(self, exc_type): | 40 | def is_exception_logged(self, exc_type): | ||
| 41 | return exc_type in self.log_exceptions | 41 | return exc_type in self.log_exceptions | ||
| 42 | 42 | ||||
| 43 | @optimize_exception_check("_checked_exceptions_suppress") | 43 | @optimize_exception_check("_checked_exceptions_suppress") | ||
| 44 | def is_exception_suppressed(self, exc_type): | 44 | def is_exception_suppressed(self, exc_type): | ||
| 45 | return exc_type in self.suppress_exceptions | 45 | return exc_type in self.suppress_exceptions | ||
| 46 | 46 | ||||
| 47 | def __enter__(self): | 47 | def __enter__(self): | ||
| 48 | self._current_exception = None | 48 | self._current_exception = None | ||
| 49 | return self | 49 | return self | ||
| 50 | 50 | ||||
| 51 | def __exit__(self, exc_type, exc_value, traceback): | 51 | def __exit__(self, exc_type, exc_value, traceback): | ||
| 52 | if exc_type: | 52 | if exc_type: | ||
| 53 | if self.is_exception_logged(exc_type): | 53 | if self.is_exception_logged(exc_type): | ||
| 54 | self.exceptions_by_session[self.__counter] = exc_value | 54 | self.exceptions_by_session[self.__counter] = exc_value | ||
| 55 | self.__counter += 1 | 55 | self.__counter += 1 | ||
| 56 | self._current_exception = exc_value | 56 | self._current_exception = exc_value | ||
| 57 | return True | 57 | return True | ||
| 58 | 58 | ||||
| 59 | if self.is_exception_suppressed(exc_type): | 59 | if self.is_exception_suppressed(exc_type): | ||
| 60 | self._current_exception = None | 60 | self._current_exception = None | ||
| 61 | self.__counter += 1 | 61 | self.__counter += 1 | ||
| 62 | return True | 62 | return True | ||
| 63 | 63 | ||||
| 64 | return False | 64 | return False | ||
| 65 | 65 | ||||
| 66 | @property | 66 | @property | ||
| 67 | def exception(self): | 67 | def exception(self): | ||
| 68 | return self._current_exception | 68 | return self._current_exception | ||
| 69 | 69 | ||||
| 70 | @property | 70 | @property | ||
| 71 | def exceptions(self): | 71 | def exceptions(self): | ||
| 72 | return self.exceptions_by_session | 72 | return self.exceptions_by_session | ||
| 73 | 73 | ||||
| 74 | def get_exception_by_session(self, session_id): | 74 | def get_exception_by_session(self, session_id): | ||
| 75 | return self.exceptions_by_session.get(session_id, None) | 75 | return self.exceptions_by_session.get(session_id, None) | ||
| 76 | 76 | ||||
| 77 | 77 | ||||
| 78 | class TestProtectedSection(unittest.TestCase): | 78 | class TestProtectedSection(unittest.TestCase): | ||
| 79 | 79 | ||||
| 80 | def test_log_exception(self): | 80 | def test_log_exception(self): | ||
| 81 | with ProtectedSection(log=(ZeroDivisionError,)) as err: | 81 | with ProtectedSection(log=(ZeroDivisionError,)) as err: | ||
| 82 | x = 1 / 0 | 82 | x = 1 / 0 | ||
| 83 | self.assertIsInstance(err.exception, ZeroDivisionError) | 83 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 84 | self.assertEqual(str(err.exception), "division by zero") | 84 | self.assertEqual(str(err.exception), "division by zero") | ||
| 85 | 85 | ||||
| 86 | def test_suppress_exception(self): | 86 | def test_suppress_exception(self): | ||
| 87 | with ProtectedSection(suppress=(ZeroDivisionError,)) as err: | 87 | with ProtectedSection(suppress=(ZeroDivisionError,)) as err: | ||
| 88 | x = 1 / 0 | 88 | x = 1 / 0 | ||
| 89 | self.assertIsNone(err.exception) | 89 | self.assertIsNone(err.exception) | ||
| 90 | 90 | ||||
| 91 | def test_log_and_suppress_priority(self): | 91 | def test_log_and_suppress_priority(self): | ||
| 92 | with ProtectedSection(log=(ZeroDivisionError,), suppress=(TypeError, ZeroDivisionError)) as err: | 92 | with ProtectedSection(log=(ZeroDivisionError,), suppress=(TypeError, ZeroDivisionError)) as err: | ||
| 93 | x = 1 / 0 | 93 | x = 1 / 0 | ||
| 94 | self.assertIsInstance(err.exception, ZeroDivisionError) | 94 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 95 | self.assertEqual(str(err.exception), "division by zero") | 95 | self.assertEqual(str(err.exception), "division by zero") | ||
| 96 | 96 | ||||
| 97 | def test_log_and_suppress_priority_with_multiple_exceptions(self): | 97 | def test_log_and_suppress_priority_with_multiple_exceptions(self): | ||
| 98 | with ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ZeroDivisionError)) as err: | 98 | with ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ZeroDivisionError)) as err: | ||
| 99 | x = 1 / 0 | 99 | x = 1 / 0 | ||
| 100 | self.assertIsInstance(err.exception, ZeroDivisionError) | 100 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 101 | 101 | ||||
| 102 | def test_no_exception(self): | 102 | def test_no_exception(self): | ||
| 103 | with ProtectedSection(log=(), suppress=(TypeError,)) as err: | 103 | with ProtectedSection(log=(), suppress=(TypeError,)) as err: | ||
| 104 | x = 1 + 1 | 104 | x = 1 + 1 | ||
| 105 | self.assertIsNone(err.exception) | 105 | self.assertIsNone(err.exception) | ||
| 106 | 106 | ||||
| 107 | def test_unhandled_exception(self): | 107 | def test_unhandled_exception(self): | ||
| 108 | with self.assertRaises(ValueError): | 108 | with self.assertRaises(ValueError): | ||
| 109 | with ProtectedSection(log=(ZeroDivisionError,), suppress=(TypeError,)) as err: | 109 | with ProtectedSection(log=(ZeroDivisionError,), suppress=(TypeError,)) as err: | ||
| 110 | raise ValueError("err") | 110 | raise ValueError("err") | ||
| 111 | self.assertIsNone(err.exception) | 111 | self.assertIsNone(err.exception) | ||
| 112 | 112 | ||||
| 113 | def test_empty_log_and_suppress(self): | 113 | def test_empty_log_and_suppress(self): | ||
| 114 | with self.assertRaises(ZeroDivisionError): | 114 | with self.assertRaises(ZeroDivisionError): | ||
| 115 | with ProtectedSection() as err: | 115 | with ProtectedSection() as err: | ||
| 116 | x = 1 / 0 | 116 | x = 1 / 0 | ||
| 117 | self.assertIsNone(err.exception) | 117 | self.assertIsNone(err.exception) | ||
| 118 | 118 | ||||
| 119 | def test_reuse_protected_section(self): | 119 | def test_reuse_protected_section(self): | ||
| 120 | protected_section = ProtectedSection(log=(ZeroDivisionError,)) | 120 | protected_section = ProtectedSection(log=(ZeroDivisionError,)) | ||
| 121 | 121 | ||||
| 122 | with protected_section as err: | 122 | with protected_section as err: | ||
| 123 | x = 1 / 0 | 123 | x = 1 / 0 | ||
| 124 | self.assertIsInstance(err.exception, ZeroDivisionError) | 124 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 125 | 125 | ||||
| 126 | with protected_section as err: | 126 | with protected_section as err: | ||
| 127 | x = 1 + 1 | 127 | x = 1 + 1 | ||
| 128 | self.assertIsNone(err.exception) | 128 | self.assertIsNone(err.exception) | ||
| 129 | 129 | ||||
| 130 | with self.assertRaises(TypeError): | 130 | with self.assertRaises(TypeError): | ||
| 131 | with protected_section as err: | 131 | with protected_section as err: | ||
| 132 | x = "text" + 5 | 132 | x = "text" + 5 | ||
| 133 | self.assertIsNone(err.exception) | 133 | self.assertIsNone(err.exception) | ||
| 134 | 134 | ||||
| 135 | with protected_section as err: | 135 | with protected_section as err: | ||
| 136 | x = 1 / 0 | 136 | x = 1 / 0 | ||
| 137 | self.assertIsInstance(err.exception, ZeroDivisionError) | 137 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 138 | 138 | ||||
| 139 | def test_suppress_then_log_exception(self): | 139 | def test_suppress_then_log_exception(self): | ||
| 140 | with ProtectedSection(log=(IndexError,), suppress=(ZeroDivisionError,)) as err: | 140 | with ProtectedSection(log=(IndexError,), suppress=(ZeroDivisionError,)) as err: | ||
| 141 | y = [][2332] | 141 | y = [][2332] | ||
| 142 | self.assertIsInstance(err.exception, IndexError) | 142 | self.assertIsInstance(err.exception, IndexError) | ||
| 143 | 143 | ||||
| 144 | def test_suppress_then_no_exception(self): | 144 | def test_suppress_then_no_exception(self): | ||
| 145 | protected_section = ProtectedSection(suppress=(ZeroDivisionError,)) | 145 | protected_section = ProtectedSection(suppress=(ZeroDivisionError,)) | ||
| 146 | 146 | ||||
| 147 | with protected_section as err: | 147 | with protected_section as err: | ||
| 148 | x = 1 / 0 | 148 | x = 1 / 0 | ||
| 149 | self.assertIsNone(err.exception) | 149 | self.assertIsNone(err.exception) | ||
| 150 | 150 | ||||
| 151 | with protected_section as err: | 151 | with protected_section as err: | ||
| 152 | x = 1 + 1 | 152 | x = 1 + 1 | ||
| 153 | self.assertIsNone(err.exception) | 153 | self.assertIsNone(err.exception) | ||
| 154 | 154 | ||||
| 155 | def test_complex_combination(self): | 155 | def test_complex_combination(self): | ||
| 156 | protected_section = ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ValueError)) | 156 | protected_section = ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ValueError)) | ||
| 157 | 157 | ||||
| 158 | with protected_section as err: | 158 | with protected_section as err: | ||
| 159 | x = 1 / 0 | 159 | x = 1 / 0 | ||
| 160 | self.assertIsInstance(err.exception, ZeroDivisionError) | 160 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 161 | self.assertEqual(str(err.exception), "division by zero") | 161 | self.assertEqual(str(err.exception), "division by zero") | ||
| 162 | 162 | ||||
| 163 | with protected_section as err: | 163 | with protected_section as err: | ||
| 164 | x = "text" + 5 | 164 | x = "text" + 5 | ||
| 165 | self.assertIsNone(err.exception) | 165 | self.assertIsNone(err.exception) | ||
| 166 | 166 | ||||
| 167 | with protected_section as err: | 167 | with protected_section as err: | ||
| 168 | y = [][2332] | 168 | y = [][2332] | ||
| 169 | self.assertIsInstance(err.exception, IndexError) | 169 | self.assertIsInstance(err.exception, IndexError) | ||
| 170 | 170 | ||||
| 171 | with protected_section as err: | 171 | with protected_section as err: | ||
| 172 | raise ValueError("err") | 172 | raise ValueError("err") | ||
| 173 | self.assertIsNone(err.exception) | 173 | self.assertIsNone(err.exception) | ||
| 174 | 174 | ||||
| 175 | with self.assertRaises(KeyError): | 175 | with self.assertRaises(KeyError): | ||
| 176 | with protected_section as err: | 176 | with protected_section as err: | ||
| 177 | raise KeyError("key err") | 177 | raise KeyError("key err") | ||
| 178 | self.assertIsNone(err.exception) | 178 | self.assertIsNone(err.exception) | ||
| 179 | 179 | ||||
| 180 | with protected_section as err: | 180 | with protected_section as err: | ||
| 181 | x = 1 + 1 | 181 | x = 1 + 1 | ||
| 182 | self.assertIsNone(err.exception) | 182 | self.assertIsNone(err.exception) | ||
| 183 | 183 | ||||
| 184 | with protected_section as err: | 184 | with protected_section as err: | ||
| 185 | x = "text" + 5 | 185 | x = "text" + 5 | ||
| 186 | self.assertIsNone(err.exception) | 186 | self.assertIsNone(err.exception) | ||
| 187 | 187 | ||||
| 188 | with protected_section as err: | 188 | with protected_section as err: | ||
| 189 | x = 1 / 0 | 189 | x = 1 / 0 | ||
| 190 | self.assertIsInstance(err.exception, ZeroDivisionError) | 190 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 191 | 191 | ||||
| 192 | with protected_section as err: | 192 | with protected_section as err: | ||
| 193 | raise ValueError("another error") | 193 | raise ValueError("another error") | ||
| 194 | self.assertIsNone(err.exception) | 194 | self.assertIsNone(err.exception) | ||
| 195 | 195 | ||||
| 196 | with protected_section as err: | 196 | with protected_section as err: | ||
| 197 | z = [][999] | 197 | z = [][999] | ||
| 198 | self.assertIsInstance(err.exception, IndexError) | 198 | self.assertIsInstance(err.exception, IndexError) | ||
| 199 | 199 | ||||
| 200 | with protected_section as err: | 200 | with protected_section as err: | ||
| 201 | x = "string" + 5 | 201 | x = "string" + 5 | ||
| 202 | self.assertIsNone(err.exception) | 202 | self.assertIsNone(err.exception) | ||
| 203 | 203 | ||||
| 204 | with protected_section as err: | 204 | with protected_section as err: | ||
| 205 | x = 1 / 0 | 205 | x = 1 / 0 | ||
| 206 | self.assertIsInstance(err.exception, ZeroDivisionError) | 206 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 207 | 207 | ||||
| 208 | with protected_section as err: | 208 | with protected_section as err: | ||
| 209 | result = 42 * 42 | 209 | result = 42 * 42 | ||
| 210 | self.assertIsNone(err.exception) | 210 | self.assertIsNone(err.exception) | ||
| 211 | 211 | ||||
| 212 | def test_complex_combination_with_empty_cases(self): | 212 | def test_complex_combination_with_empty_cases(self): | ||
| 213 | protected_section = ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ValueError)) | 213 | protected_section = ProtectedSection(log=(ZeroDivisionError, IndexError), suppress=(TypeError, ValueError)) | ||
| 214 | 214 | ||||
| 215 | with protected_section as err: | 215 | with protected_section as err: | ||
| 216 | x = 1 / 0 | 216 | x = 1 / 0 | ||
| 217 | self.assertIsInstance(err.exception, ZeroDivisionError) | 217 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 218 | self.assertEqual(str(err.exception), "division by zero") | 218 | self.assertEqual(str(err.exception), "division by zero") | ||
| 219 | 219 | ||||
| 220 | with protected_section as err: | 220 | with protected_section as err: | ||
| 221 | x = "text" + 5 | 221 | x = "text" + 5 | ||
| 222 | self.assertIsNone(err.exception) | 222 | self.assertIsNone(err.exception) | ||
| 223 | 223 | ||||
| 224 | with protected_section as err: | 224 | with protected_section as err: | ||
| 225 | y = [][2332] | 225 | y = [][2332] | ||
| 226 | self.assertIsInstance(err.exception, IndexError) | 226 | self.assertIsInstance(err.exception, IndexError) | ||
| 227 | 227 | ||||
| 228 | with protected_section as err: | 228 | with protected_section as err: | ||
| 229 | raise ValueError("err") | 229 | raise ValueError("err") | ||
| 230 | self.assertIsNone(err.exception) | 230 | self.assertIsNone(err.exception) | ||
| 231 | 231 | ||||
| 232 | with self.assertRaises(KeyError): | 232 | with self.assertRaises(KeyError): | ||
| 233 | with protected_section as err: | 233 | with protected_section as err: | ||
| 234 | raise KeyError("key error") | 234 | raise KeyError("key error") | ||
| 235 | self.assertIsNone(err.exception) | 235 | self.assertIsNone(err.exception) | ||
| 236 | 236 | ||||
| 237 | with protected_section as err: | 237 | with protected_section as err: | ||
| 238 | x = 1 + 1 | 238 | x = 1 + 1 | ||
| 239 | self.assertIsNone(err.exception) | 239 | self.assertIsNone(err.exception) | ||
| 240 | 240 | ||||
| 241 | with protected_section as err: | 241 | with protected_section as err: | ||
| 242 | x = "text" + 5 | 242 | x = "text" + 5 | ||
| 243 | self.assertIsNone(err.exception) | 243 | self.assertIsNone(err.exception) | ||
| 244 | 244 | ||||
| 245 | with protected_section as err: | 245 | with protected_section as err: | ||
| 246 | x = 1 / 0 | 246 | x = 1 / 0 | ||
| 247 | self.assertIsInstance(err.exception, ZeroDivisionError) | 247 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 248 | 248 | ||||
| 249 | with protected_section as err: | 249 | with protected_section as err: | ||
| 250 | raise ValueError("another error") | 250 | raise ValueError("another error") | ||
| 251 | self.assertIsNone(err.exception) | 251 | self.assertIsNone(err.exception) | ||
| 252 | 252 | ||||
| 253 | with protected_section as err: | 253 | with protected_section as err: | ||
| 254 | z = [][999] | 254 | z = [][999] | ||
| 255 | self.assertIsInstance(err.exception, IndexError) | 255 | self.assertIsInstance(err.exception, IndexError) | ||
| 256 | 256 | ||||
| 257 | with protected_section as err: | 257 | with protected_section as err: | ||
| 258 | x = "string" + 5 | 258 | x = "string" + 5 | ||
| 259 | self.assertIsNone(err.exception) | 259 | self.assertIsNone(err.exception) | ||
| 260 | 260 | ||||
| 261 | with protected_section as err: | 261 | with protected_section as err: | ||
| 262 | x = 1 / 0 | 262 | x = 1 / 0 | ||
| 263 | self.assertIsInstance(err.exception, ZeroDivisionError) | 263 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 264 | 264 | ||||
| 265 | with protected_section as err: | 265 | with protected_section as err: | ||
| 266 | result = 42 * 42 | 266 | result = 42 * 42 | ||
| 267 | self.assertIsNone(err.exception) | 267 | self.assertIsNone(err.exception) | ||
| 268 | 268 | ||||
| 269 | protected_section_empty_log = ProtectedSection(log=(), suppress=(TypeError,)) | 269 | protected_section_empty_log = ProtectedSection(log=(), suppress=(TypeError,)) | ||
| 270 | 270 | ||||
| 271 | with protected_section_empty_log as err: | 271 | with protected_section_empty_log as err: | ||
| 272 | x = "text" + 5 | 272 | x = "text" + 5 | ||
| 273 | self.assertIsNone(err.exception) | 273 | self.assertIsNone(err.exception) | ||
| 274 | 274 | ||||
| 275 | with self.assertRaises(ZeroDivisionError): | 275 | with self.assertRaises(ZeroDivisionError): | ||
| 276 | with protected_section_empty_log as err: | 276 | with protected_section_empty_log as err: | ||
| 277 | x = 1 / 0 | 277 | x = 1 / 0 | ||
| 278 | self.assertIsNone(err.exception) | 278 | self.assertIsNone(err.exception) | ||
| 279 | 279 | ||||
| 280 | protected_section_empty_suppress = ProtectedSection(log=(ZeroDivisionError,), suppress=()) | 280 | protected_section_empty_suppress = ProtectedSection(log=(ZeroDivisionError,), suppress=()) | ||
| 281 | 281 | ||||
| 282 | with protected_section_empty_suppress as err: | 282 | with protected_section_empty_suppress as err: | ||
| 283 | x = 1 / 0 | 283 | x = 1 / 0 | ||
| 284 | self.assertIsInstance(err.exception, ZeroDivisionError) | 284 | self.assertIsInstance(err.exception, ZeroDivisionError) | ||
| 285 | 285 | ||||
| 286 | with self.assertRaises(TypeError): | 286 | with self.assertRaises(TypeError): | ||
| 287 | with protected_section_empty_suppress as err: | 287 | with protected_section_empty_suppress as err: | ||
| 288 | x = "text" + 5 | 288 | x = "text" + 5 | ||
| 289 | self.assertIsNone(err.exception) | 289 | self.assertIsNone(err.exception) | ||
| 290 | 290 | ||||
| 291 | protected_section_empty_both = ProtectedSection() | 291 | protected_section_empty_both = ProtectedSection() | ||
| 292 | 292 | ||||
| 293 | with self.assertRaises(ZeroDivisionError): | 293 | with self.assertRaises(ZeroDivisionError): | ||
| 294 | with protected_section_empty_both as err: | 294 | with protected_section_empty_both as err: | ||
| 295 | x = 1 / 0 | 295 | x = 1 / 0 | ||
| 296 | self.assertIsNone(err.exception) | 296 | self.assertIsNone(err.exception) | ||
| 297 | 297 | ||||
| 298 | with self.assertRaises(TypeError): | 298 | with self.assertRaises(TypeError): | ||
| 299 | with protected_section_empty_both as err: | 299 | with protected_section_empty_both as err: | ||
| 300 | x = "text" + 5 | 300 | x = "text" + 5 | ||
| 301 | self.assertIsNone(err.exception) | 301 | self.assertIsNone(err.exception) | ||
| 302 | 302 | ||||
| 303 | with protected_section_empty_both as err: | 303 | with protected_section_empty_both as err: | ||
| 304 | x = 1 + 1 | 304 | x = 1 + 1 | ||
| 305 | self.assertIsNone(err.exception) | 305 | self.assertIsNone(err.exception) | ||
| 306 | 306 | ||||
| 307 | # Viktor ? | 307 | # Viktor ? | ||
| 308 | def test_reuse_protected_section_with_reset_exception(self): | 308 | def test_reuse_protected_section_with_reset_exception(self): | ||
| 309 | protected_section = ProtectedSection(log=(ValueError,)) | 309 | protected_section = ProtectedSection(log=(ValueError,)) | ||
| 310 | 310 | ||||
| 311 | with protected_section as cm1: | 311 | with protected_section as cm1: | ||
| 312 | raise ValueError('Text 1') | 312 | raise ValueError('Text 1') | ||
| 313 | self.assertIsInstance(cm1.exception, ValueError) | 313 | self.assertIsInstance(cm1.exception, ValueError) | ||
| 314 | self.assertEqual(str(cm1.exception), 'Text 1') | 314 | self.assertEqual(str(cm1.exception), 'Text 1') | ||
| 315 | 315 | ||||
| 316 | with protected_section as cm2: | 316 | with protected_section as cm2: | ||
| 317 | raise ValueError('Text 2') | 317 | raise ValueError('Text 2') | ||
| 318 | self.assertIsInstance(cm2.exception, ValueError) | 318 | self.assertIsInstance(cm2.exception, ValueError) | ||
| 319 | self.assertEqual(str(cm2.exception), 'Text 2') | 319 | self.assertEqual(str(cm2.exception), 'Text 2') | ||
| 320 | 320 | ||||
| 321 | self.assertEqual(str(cm1.exception), 'Text 2') | 321 | self.assertEqual(str(cm1.exception), 'Text 2') | ||
| 322 | 322 | ||||
| 323 | 323 | ||||
| 324 | if __name__ == "__main__": | 324 | if __name__ == "__main__": | ||
| 325 | unittest.main() | 325 | unittest.main() |
| Legends | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||