OILS / mycpp / examples / test_io_os_error.py View on Github | oilshell.org

131 lines, 57 significant
1#!/usr/bin/env python2
2"""
3exceptions.py
4"""
5from __future__ import print_function
6
7#from errno import EISDIR
8import os
9from mycpp.mylib import log, print_stderr
10
11from typing import List, Any
12#import posix_ as posix
13
14
15def Close(fd):
16 # type: (int) -> None
17
18 #raise OSError(EISDIR)
19 raise OSError(0)
20
21
22def Pop(fd):
23 # type: (int) -> None
24
25 try:
26 #posix.close(fd)
27 Close(fd)
28 except (IOError, OSError) as e:
29 #log('Error closing descriptor %d: %s', rf.orig_fd, pyutil.strerror(e))
30 log('Error closing descriptor %d', fd)
31 raise
32
33
34def AppBundleMain(argv):
35 # type: (List[str]) -> int
36
37 Pop(3)
38
39 return 0
40
41
42def TestRethrow():
43 # type: () -> int
44 """
45 This is fine, the problem was throwing an exceptinon in a DESTRUCTOR
46 """
47 argv = [] # type: List[str]
48
49 try:
50 return AppBundleMain(argv)
51
52 except ValueError as e:
53 return 2
54 #except error.Usage as e:
55 # #builtin.Help(['oil-usage'], util.GetResourceLoader())
56 # log('oil: %s', e.msg)
57 # return 2
58
59 except KeyboardInterrupt:
60 print('')
61 return 130 # 128 + 2
62
63 except (IOError, OSError) as e:
64 if 0:
65 import traceback
66 traceback.print_exc()
67
68 # test this with prlimit --nproc=1 --pid=$$
69 #print_stderr('osh I/O error (main): %s' % posix.strerror(e.errno))
70 print_stderr('osh I/O error (main)')
71 return 2 # dash gives status 2
72
73
74class ctx_TerminalControl(object):
75
76 def __init__(self):
77 # type: () -> None
78
79 log('TerminalControl init')
80
81 def __enter__(self):
82 # type: () -> None
83 pass
84
85 def __exit__(self, type, value, traceback):
86 # type: (Any, Any, Any) -> None
87 log('TerminalControl exit')
88
89 TestRethrow()
90
91 # https://akrzemi1.wordpress.com/2011/09/21/destructors-that-throw/
92
93 # Quote: Until any exception gets out from the destructor we can throw at
94 # will inside, even from other destructors, and this does not account for
95 # double-exception situation or "throwing from destructor during stack
96 # unwinding." Let's illustrate it with an example.
97 log('Throw and Catch within destructor seems OK')
98
99
100def TestDestructor():
101 # type: () -> None
102
103 with ctx_TerminalControl():
104 log('hi')
105
106
107def run_tests():
108 # type: () -> int
109
110 TestRethrow()
111
112 log('')
113 log('TestDestructor')
114 log('')
115
116 TestDestructor()
117
118 return 0
119
120
121def run_benchmarks():
122 # type: () -> None
123 raise NotImplementedError()
124
125
126if __name__ == '__main__':
127 if os.getenv('BENCHMARK'):
128 log('Benchmarking...')
129 run_benchmarks()
130 else:
131 run_tests()