forked from fluentpython/example-code-2e
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mirror_gen_exc.py
98 lines (76 loc) · 2.29 KB
/
mirror_gen_exc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""
A "mirroring" ``stdout`` context manager.
While active, the context manager reverses text output to
``stdout``::
# tag::MIRROR_GEN_DEMO_1[]
>>> from mirror_gen import looking_glass
>>> with looking_glass() as what: # <1>
... print('Alice, Kitty and Snowdrop')
... print(what)
...
pordwonS dna yttiK ,ecilA
YKCOWREBBAJ
>>> what
'JABBERWOCKY'
# end::MIRROR_GEN_DEMO_1[]
This exposes the context manager operation::
# tag::MIRROR_GEN_DEMO_2[]
>>> from mirror_gen import looking_glass
>>> manager = looking_glass() # <1>
>>> manager # doctest: +ELLIPSIS
<contextlib._GeneratorContextManager object at 0x...>
>>> monster = manager.__enter__() # <2>
>>> monster == 'JABBERWOCKY' # <3>
eurT
>>> monster
'YKCOWREBBAJ'
>>> manager # doctest: +ELLIPSIS
>...x0 ta tcejbo reganaMtxetnoCrotareneG_.biltxetnoc<
>>> manager.__exit__(None, None, None) # <4>
False
>>> monster
'JABBERWOCKY'
# end::MIRROR_GEN_DEMO_2[]
The context manager can handle and "swallow" exceptions.
The following test does not pass under doctest (a
ZeroDivisionError is reported by doctest) but passes
if executed by hand in the Python 3 console (the exception
is handled by the context manager):
# tag::MIRROR_GEN_DEMO_3[]
>>> from mirror_gen_exc import looking_glass
>>> with looking_glass():
... print('Humpty Dumpty')
... x = 1/0 # <1>
... print('END') # <2>
...
ytpmuD ytpmuH
Please DO NOT divide by zero!
# end::MIRROR_GEN_DEMO_3[]
>>> with looking_glass():
... print('Humpty Dumpty')
... x = no_such_name # <1>
... print('END') # <2>
...
Traceback (most recent call last):
...
NameError: name 'no_such_name' is not defined
"""
# tag::MIRROR_GEN_EXC[]
import contextlib
import sys
@contextlib.contextmanager
def looking_glass():
original_write = sys.stdout.write
def reverse_write(text):
original_write(text[::-1])
sys.stdout.write = reverse_write
msg = '' # <1>
try:
yield 'JABBERWOCKY'
except ZeroDivisionError: # <2>
msg = 'Please DO NOT divide by zero!'
finally:
sys.stdout.write = original_write # <3>
if msg:
print(msg) # <4>
# end::MIRROR_GEN_EXC[]