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 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|