Skip to content

Commit 7c86225

Browse files
committed
contextlib: modify TestExitStack to work in uPy
1 parent 313073b commit 7c86225

File tree

1 file changed

+106
-91
lines changed

1 file changed

+106
-91
lines changed

contextlib/tests.py

+106-91
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import sys
12
import unittest
2-
from contextlib import closing, suppress
3+
from contextlib import closing, suppress, ExitStack
34

45

56
class ClosingTestCase(unittest.TestCase):
@@ -39,12 +40,12 @@ def test_suppress(self):
3940

4041
class TestExitStack(unittest.TestCase):
4142

42-
@support.requires_docstrings
43-
def test_instance_docs(self):
44-
# Issue 19330: ensure context manager instances have good docstrings
45-
cm_docstring = ExitStack.__doc__
46-
obj = ExitStack()
47-
self.assertEqual(obj.__doc__, cm_docstring)
43+
# @support.requires_docstrings
44+
# def test_instance_docs(self):
45+
# # Issue 19330: ensure context manager instances have good docstrings
46+
# cm_docstring = ExitStack.__doc__
47+
# obj = ExitStack()
48+
# self.assertEqual(obj.__doc__, cm_docstring)
4849

4950
def test_no_resources(self):
5051
with ExitStack():
@@ -74,10 +75,10 @@ def _exit(*args, **kwds):
7475
else:
7576
f = stack.callback(_exit)
7677
self.assertIs(f, _exit)
77-
for wrapper in stack._exit_callbacks:
78-
self.assertIs(wrapper.__wrapped__, _exit)
79-
self.assertNotEqual(wrapper.__name__, _exit.__name__)
80-
self.assertIsNone(wrapper.__doc__, _exit.__doc__)
78+
# for wrapper in stack._exit_callbacks:
79+
# self.assertIs(wrapper.__wrapped__, _exit)
80+
# self.assertNotEqual(wrapper.__name__, _exit.__name__)
81+
# self.assertIsNone(wrapper.__doc__, _exit.__doc__)
8182
self.assertEqual(result, expected)
8283

8384
def test_push(self):
@@ -87,9 +88,9 @@ def _expect_exc(exc_type, exc, exc_tb):
8788
def _suppress_exc(*exc_details):
8889
return True
8990
def _expect_ok(exc_type, exc, exc_tb):
90-
self.assertIsNone(exc_type)
91-
self.assertIsNone(exc)
92-
self.assertIsNone(exc_tb)
91+
assert exc_type is None
92+
assert exc is None
93+
assert exc_tb is None
9394
class ExitCM(object):
9495
def __init__(self, check_exc):
9596
self.check_exc = check_exc
@@ -99,19 +100,19 @@ def __exit__(self, *exc_details):
99100
self.check_exc(*exc_details)
100101
with ExitStack() as stack:
101102
stack.push(_expect_ok)
102-
self.assertIs(stack._exit_callbacks[-1], _expect_ok)
103+
self.assertIs(tuple(stack._exit_callbacks)[-1], _expect_ok)
103104
cm = ExitCM(_expect_ok)
104105
stack.push(cm)
105-
self.assertIs(stack._exit_callbacks[-1].__self__, cm)
106+
# self.assertIs(stack._exit_callbacks[-1].__self__, cm)
106107
stack.push(_suppress_exc)
107-
self.assertIs(stack._exit_callbacks[-1], _suppress_exc)
108+
self.assertIs(tuple(stack._exit_callbacks)[-1], _suppress_exc)
108109
cm = ExitCM(_expect_exc)
109110
stack.push(cm)
110-
self.assertIs(stack._exit_callbacks[-1].__self__, cm)
111+
# self.assertIs(stack._exit_callbacks[-1].__self__, cm)
111112
stack.push(_expect_exc)
112-
self.assertIs(stack._exit_callbacks[-1], _expect_exc)
113+
self.assertIs(tuple(stack._exit_callbacks)[-1], _expect_exc)
113114
stack.push(_expect_exc)
114-
self.assertIs(stack._exit_callbacks[-1], _expect_exc)
115+
self.assertIs(tuple(stack._exit_callbacks)[-1], _expect_exc)
115116
1/0
116117

117118
def test_enter_context(self):
@@ -127,9 +128,9 @@ def __exit__(self, *exc_details):
127128
@stack.callback # Registered first => cleaned up last
128129
def _exit():
129130
result.append(4)
130-
self.assertIsNotNone(_exit)
131+
assert _exit is not None
131132
stack.enter_context(cm)
132-
self.assertIs(stack._exit_callbacks[-1].__self__, cm)
133+
# self.assertIs(stack._exit_callbacks[-1].__self__, cm)
133134
result.append(2)
134135
self.assertEqual(result, [1, 2, 3, 4])
135136

@@ -139,7 +140,7 @@ def test_close(self):
139140
@stack.callback
140141
def _exit():
141142
result.append(1)
142-
self.assertIsNotNone(_exit)
143+
assert _exit is not None
143144
stack.close()
144145
result.append(2)
145146
self.assertEqual(result, [1, 2])
@@ -150,7 +151,7 @@ def test_pop_all(self):
150151
@stack.callback
151152
def _exit():
152153
result.append(3)
153-
self.assertIsNotNone(_exit)
154+
assert _exit is not None
154155
new_stack = stack.pop_all()
155156
result.append(1)
156157
result.append(2)
@@ -171,12 +172,14 @@ def test_exit_suppress(self):
171172
def test_exit_exception_chaining_reference(self):
172173
# Sanity check to make sure that ExitStack chaining matches
173174
# actual nested with statements
175+
exc_chain = []
174176
class RaiseExc:
175177
def __init__(self, exc):
176178
self.exc = exc
177179
def __enter__(self):
178180
return self
179181
def __exit__(self, *exc_details):
182+
exc_chain.append(exc_details[0])
180183
raise self.exc
181184

182185
class RaiseExcWithContext:
@@ -187,8 +190,10 @@ def __enter__(self):
187190
return self
188191
def __exit__(self, *exc_details):
189192
try:
193+
exc_chain.append(exc_details[0])
190194
raise self.inner
191195
except:
196+
exc_chain.append(sys.exc_info()[0])
192197
raise self.outer
193198

194199
class SuppressExc:
@@ -205,26 +210,35 @@ def __exit__(self, *exc_details):
205210
with RaiseExc(ValueError):
206211
1 / 0
207212
except IndexError as exc:
208-
self.assertIsInstance(exc.__context__, KeyError)
209-
self.assertIsInstance(exc.__context__.__context__, AttributeError)
213+
# self.assertIsInstance(exc.__context__, KeyError)
214+
# self.assertIsInstance(exc.__context__.__context__, AttributeError)
210215
# Inner exceptions were suppressed
211-
self.assertIsNone(exc.__context__.__context__.__context__)
216+
# self.assertIsNone(exc.__context__.__context__.__context__)
217+
exc_chain.append(type(exc))
218+
assert tuple(exc_chain) == (ZeroDivisionError, None, AttributeError, KeyError, IndexError)
212219
else:
213220
self.fail("Expected IndexError, but no exception was raised")
214221
# Check the inner exceptions
215222
inner_exc = SuppressExc.saved_details[1]
216223
self.assertIsInstance(inner_exc, ValueError)
217-
self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)
224+
# self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)
218225

219226
def test_exit_exception_chaining(self):
220227
# Ensure exception chaining matches the reference behaviour
228+
exc_chain = []
221229
def raise_exc(exc):
230+
frame_exc = sys.exc_info()[0]
231+
if frame_exc is not None:
232+
exc_chain.append(frame_exc)
233+
exc_chain.append(exc)
222234
raise exc
223235

224236
saved_details = None
225237
def suppress_exc(*exc_details):
226238
nonlocal saved_details
227239
saved_details = exc_details
240+
assert exc_chain[-1] == exc_details[0]
241+
exc_chain[-1] = None
228242
return True
229243

230244
try:
@@ -236,16 +250,17 @@ def suppress_exc(*exc_details):
236250
stack.callback(raise_exc, ValueError)
237251
1 / 0
238252
except IndexError as exc:
239-
self.assertIsInstance(exc.__context__, KeyError)
240-
self.assertIsInstance(exc.__context__.__context__, AttributeError)
253+
# self.assertIsInstance(exc.__context__, KeyError)
254+
# self.assertIsInstance(exc.__context__.__context__, AttributeError)
241255
# Inner exceptions were suppressed
242-
self.assertIsNone(exc.__context__.__context__.__context__)
256+
# self.assertIsNone(exc.__context__.__context__.__context__)
257+
assert tuple(exc_chain) == (ZeroDivisionError, None, AttributeError, KeyError, IndexError)
243258
else:
244259
self.fail("Expected IndexError, but no exception was raised")
245260
# Check the inner exceptions
246261
inner_exc = saved_details[1]
247262
self.assertIsInstance(inner_exc, ValueError)
248-
self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)
263+
# self.assertIsInstance(inner_exc.__context__, ZeroDivisionError)
249264

250265
def test_exit_exception_non_suppressing(self):
251266
# http://bugs.python.org/issue19092
@@ -274,64 +289,64 @@ def suppress_exc(*exc_details):
274289
else:
275290
self.fail("Expected KeyError, but no exception was raised")
276291

277-
def test_exit_exception_with_correct_context(self):
278-
# http://bugs.python.org/issue20317
279-
@contextmanager
280-
def gets_the_context_right(exc):
281-
try:
282-
yield
283-
finally:
284-
raise exc
285-
286-
exc1 = Exception(1)
287-
exc2 = Exception(2)
288-
exc3 = Exception(3)
289-
exc4 = Exception(4)
290-
291-
# The contextmanager already fixes the context, so prior to the
292-
# fix, ExitStack would try to fix it *again* and get into an
293-
# infinite self-referential loop
294-
try:
295-
with ExitStack() as stack:
296-
stack.enter_context(gets_the_context_right(exc4))
297-
stack.enter_context(gets_the_context_right(exc3))
298-
stack.enter_context(gets_the_context_right(exc2))
299-
raise exc1
300-
except Exception as exc:
301-
self.assertIs(exc, exc4)
302-
self.assertIs(exc.__context__, exc3)
303-
self.assertIs(exc.__context__.__context__, exc2)
304-
self.assertIs(exc.__context__.__context__.__context__, exc1)
305-
self.assertIsNone(
306-
exc.__context__.__context__.__context__.__context__)
307-
308-
def test_exit_exception_with_existing_context(self):
309-
# Addresses a lack of test coverage discovered after checking in a
310-
# fix for issue 20317 that still contained debugging code.
311-
def raise_nested(inner_exc, outer_exc):
312-
try:
313-
raise inner_exc
314-
finally:
315-
raise outer_exc
316-
exc1 = Exception(1)
317-
exc2 = Exception(2)
318-
exc3 = Exception(3)
319-
exc4 = Exception(4)
320-
exc5 = Exception(5)
321-
try:
322-
with ExitStack() as stack:
323-
stack.callback(raise_nested, exc4, exc5)
324-
stack.callback(raise_nested, exc2, exc3)
325-
raise exc1
326-
except Exception as exc:
327-
self.assertIs(exc, exc5)
328-
self.assertIs(exc.__context__, exc4)
329-
self.assertIs(exc.__context__.__context__, exc3)
330-
self.assertIs(exc.__context__.__context__.__context__, exc2)
331-
self.assertIs(
332-
exc.__context__.__context__.__context__.__context__, exc1)
333-
self.assertIsNone(
334-
exc.__context__.__context__.__context__.__context__.__context__)
292+
# def test_exit_exception_with_correct_context(self):
293+
# # http://bugs.python.org/issue20317
294+
# @contextmanager
295+
# def gets_the_context_right(exc):
296+
# try:
297+
# yield
298+
# finally:
299+
# raise exc
300+
#
301+
# exc1 = Exception(1)
302+
# exc2 = Exception(2)
303+
# exc3 = Exception(3)
304+
# exc4 = Exception(4)
305+
#
306+
# # The contextmanager already fixes the context, so prior to the
307+
# # fix, ExitStack would try to fix it *again* and get into an
308+
# # infinite self-referential loop
309+
# try:
310+
# with ExitStack() as stack:
311+
# stack.enter_context(gets_the_context_right(exc4))
312+
# stack.enter_context(gets_the_context_right(exc3))
313+
# stack.enter_context(gets_the_context_right(exc2))
314+
# raise exc1
315+
# except Exception as exc:
316+
# self.assertIs(exc, exc4)
317+
# self.assertIs(exc.__context__, exc3)
318+
# self.assertIs(exc.__context__.__context__, exc2)
319+
# self.assertIs(exc.__context__.__context__.__context__, exc1)
320+
# self.assertIsNone(
321+
# exc.__context__.__context__.__context__.__context__)
322+
323+
# def test_exit_exception_with_existing_context(self):
324+
# # Addresses a lack of test coverage discovered after checking in a
325+
# # fix for issue 20317 that still contained debugging code.
326+
# def raise_nested(inner_exc, outer_exc):
327+
# try:
328+
# raise inner_exc
329+
# finally:
330+
# raise outer_exc
331+
# exc1 = Exception(1)
332+
# exc2 = Exception(2)
333+
# exc3 = Exception(3)
334+
# exc4 = Exception(4)
335+
# exc5 = Exception(5)
336+
# try:
337+
# with ExitStack() as stack:
338+
# stack.callback(raise_nested, exc4, exc5)
339+
# stack.callback(raise_nested, exc2, exc3)
340+
# raise exc1
341+
# except Exception as exc:
342+
# self.assertIs(exc, exc5)
343+
# self.assertIs(exc.__context__, exc4)
344+
# self.assertIs(exc.__context__.__context__, exc3)
345+
# self.assertIs(exc.__context__.__context__.__context__, exc2)
346+
# self.assertIs(
347+
# exc.__context__.__context__.__context__.__context__, exc1)
348+
# self.assertIsNone(
349+
# exc.__context__.__context__.__context__.__context__.__context__)
335350

336351

337352

@@ -364,7 +379,7 @@ class Example(object): pass
364379
stack = ExitStack()
365380
self.assertRaises(AttributeError, stack.enter_context, cm)
366381
stack.push(cm)
367-
self.assertIs(stack._exit_callbacks[-1], cm)
382+
self.assertIs(tuple(stack._exit_callbacks)[-1], cm)
368383

369384

370385
if __name__ == '__main__':

0 commit comments

Comments
 (0)