##// END OF EJS Templates
i1673 add tests for python3 exceptions
Justyna Ilczuk -
Show More
@@ -1,149 +1,184 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """Tests for IPython.core.ultratb
2 """Tests for IPython.core.ultratb
3 """
3 """
4 import io
4 import io
5 import os.path
5 import os.path
6 import unittest
6 import unittest
7
7
8 from IPython.testing import tools as tt
8 from IPython.testing import tools as tt
9 from IPython.testing.decorators import onlyif_unicode_paths
9 from IPython.testing.decorators import onlyif_unicode_paths
10 from IPython.utils.syspathcontext import prepended_to_syspath
10 from IPython.utils.syspathcontext import prepended_to_syspath
11 from IPython.utils.tempdir import TemporaryDirectory
11 from IPython.utils.tempdir import TemporaryDirectory
12 from IPython.utils.py3compat import PY3
12
13
13 ip = get_ipython()
14 ip = get_ipython()
14
15
15 file_1 = """1
16 file_1 = """1
16 2
17 2
17 3
18 3
18 def f():
19 def f():
19 1/0
20 1/0
20 """
21 """
21
22
22 file_2 = """def f():
23 file_2 = """def f():
23 1/0
24 1/0
24 """
25 """
25
26
26 class ChangedPyFileTest(unittest.TestCase):
27 class ChangedPyFileTest(unittest.TestCase):
27 def test_changing_py_file(self):
28 def test_changing_py_file(self):
28 """Traceback produced if the line where the error occurred is missing?
29 """Traceback produced if the line where the error occurred is missing?
29
30
30 https://github.com/ipython/ipython/issues/1456
31 https://github.com/ipython/ipython/issues/1456
31 """
32 """
32 with TemporaryDirectory() as td:
33 with TemporaryDirectory() as td:
33 fname = os.path.join(td, "foo.py")
34 fname = os.path.join(td, "foo.py")
34 with open(fname, "w") as f:
35 with open(fname, "w") as f:
35 f.write(file_1)
36 f.write(file_1)
36
37
37 with prepended_to_syspath(td):
38 with prepended_to_syspath(td):
38 ip.run_cell("import foo")
39 ip.run_cell("import foo")
39
40
40 with tt.AssertPrints("ZeroDivisionError"):
41 with tt.AssertPrints("ZeroDivisionError"):
41 ip.run_cell("foo.f()")
42 ip.run_cell("foo.f()")
42
43
43 # Make the file shorter, so the line of the error is missing.
44 # Make the file shorter, so the line of the error is missing.
44 with open(fname, "w") as f:
45 with open(fname, "w") as f:
45 f.write(file_2)
46 f.write(file_2)
46
47
47 # For some reason, this was failing on the *second* call after
48 # For some reason, this was failing on the *second* call after
48 # changing the file, so we call f() twice.
49 # changing the file, so we call f() twice.
49 with tt.AssertNotPrints("Internal Python error", channel='stderr'):
50 with tt.AssertNotPrints("Internal Python error", channel='stderr'):
50 with tt.AssertPrints("ZeroDivisionError"):
51 with tt.AssertPrints("ZeroDivisionError"):
51 ip.run_cell("foo.f()")
52 ip.run_cell("foo.f()")
52 with tt.AssertPrints("ZeroDivisionError"):
53 with tt.AssertPrints("ZeroDivisionError"):
53 ip.run_cell("foo.f()")
54 ip.run_cell("foo.f()")
54
55
55 iso_8859_5_file = u'''# coding: iso-8859-5
56 iso_8859_5_file = u'''# coding: iso-8859-5
56
57
57 def fail():
58 def fail():
58 """Π΄Π±Π˜Π–"""
59 """Π΄Π±Π˜Π–"""
59 1/0 # Π΄Π±Π˜Π–
60 1/0 # Π΄Π±Π˜Π–
60 '''
61 '''
61
62
62 class NonAsciiTest(unittest.TestCase):
63 class NonAsciiTest(unittest.TestCase):
63 @onlyif_unicode_paths
64 @onlyif_unicode_paths
64 def test_nonascii_path(self):
65 def test_nonascii_path(self):
65 # Non-ascii directory name as well.
66 # Non-ascii directory name as well.
66 with TemporaryDirectory(suffix=u'Γ©') as td:
67 with TemporaryDirectory(suffix=u'Γ©') as td:
67 fname = os.path.join(td, u"fooΓ©.py")
68 fname = os.path.join(td, u"fooΓ©.py")
68 with open(fname, "w") as f:
69 with open(fname, "w") as f:
69 f.write(file_1)
70 f.write(file_1)
70
71
71 with prepended_to_syspath(td):
72 with prepended_to_syspath(td):
72 ip.run_cell("import foo")
73 ip.run_cell("import foo")
73
74
74 with tt.AssertPrints("ZeroDivisionError"):
75 with tt.AssertPrints("ZeroDivisionError"):
75 ip.run_cell("foo.f()")
76 ip.run_cell("foo.f()")
76
77
77 def test_iso8859_5(self):
78 def test_iso8859_5(self):
78 with TemporaryDirectory() as td:
79 with TemporaryDirectory() as td:
79 fname = os.path.join(td, 'dfghjkl.py')
80 fname = os.path.join(td, 'dfghjkl.py')
80
81
81 with io.open(fname, 'w', encoding='iso-8859-5') as f:
82 with io.open(fname, 'w', encoding='iso-8859-5') as f:
82 f.write(iso_8859_5_file)
83 f.write(iso_8859_5_file)
83
84
84 with prepended_to_syspath(td):
85 with prepended_to_syspath(td):
85 ip.run_cell("from dfghjkl import fail")
86 ip.run_cell("from dfghjkl import fail")
86
87
87 with tt.AssertPrints("ZeroDivisionError"):
88 with tt.AssertPrints("ZeroDivisionError"):
88 with tt.AssertPrints(u'Π΄Π±Π˜Π–', suppress=False):
89 with tt.AssertPrints(u'Π΄Π±Π˜Π–', suppress=False):
89 ip.run_cell('fail()')
90 ip.run_cell('fail()')
90
91
91 indentationerror_file = """if True:
92 indentationerror_file = """if True:
92 zoon()
93 zoon()
93 """
94 """
94
95
95 class IndentationErrorTest(unittest.TestCase):
96 class IndentationErrorTest(unittest.TestCase):
96 def test_indentationerror_shows_line(self):
97 def test_indentationerror_shows_line(self):
97 # See issue gh-2398
98 # See issue gh-2398
98 with tt.AssertPrints("IndentationError"):
99 with tt.AssertPrints("IndentationError"):
99 with tt.AssertPrints("zoon()", suppress=False):
100 with tt.AssertPrints("zoon()", suppress=False):
100 ip.run_cell(indentationerror_file)
101 ip.run_cell(indentationerror_file)
101
102
102 with TemporaryDirectory() as td:
103 with TemporaryDirectory() as td:
103 fname = os.path.join(td, "foo.py")
104 fname = os.path.join(td, "foo.py")
104 with open(fname, "w") as f:
105 with open(fname, "w") as f:
105 f.write(indentationerror_file)
106 f.write(indentationerror_file)
106
107
107 with tt.AssertPrints("IndentationError"):
108 with tt.AssertPrints("IndentationError"):
108 with tt.AssertPrints("zoon()", suppress=False):
109 with tt.AssertPrints("zoon()", suppress=False):
109 ip.magic('run %s' % fname)
110 ip.magic('run %s' % fname)
110
111
111 se_file_1 = """1
112 se_file_1 = """1
112 2
113 2
113 7/
114 7/
114 """
115 """
115
116
116 se_file_2 = """7/
117 se_file_2 = """7/
117 """
118 """
118
119
119 class SyntaxErrorTest(unittest.TestCase):
120 class SyntaxErrorTest(unittest.TestCase):
120 def test_syntaxerror_without_lineno(self):
121 def test_syntaxerror_without_lineno(self):
121 with tt.AssertNotPrints("TypeError"):
122 with tt.AssertNotPrints("TypeError"):
122 with tt.AssertPrints("line unknown"):
123 with tt.AssertPrints("line unknown"):
123 ip.run_cell("raise SyntaxError()")
124 ip.run_cell("raise SyntaxError()")
124
125
125 def test_changing_py_file(self):
126 def test_changing_py_file(self):
126 with TemporaryDirectory() as td:
127 with TemporaryDirectory() as td:
127 fname = os.path.join(td, "foo.py")
128 fname = os.path.join(td, "foo.py")
128 with open(fname, 'w') as f:
129 with open(fname, 'w') as f:
129 f.write(se_file_1)
130 f.write(se_file_1)
130
131
131 with tt.AssertPrints(["7/", "SyntaxError"]):
132 with tt.AssertPrints(["7/", "SyntaxError"]):
132 ip.magic("run " + fname)
133 ip.magic("run " + fname)
133
134
134 # Modify the file
135 # Modify the file
135 with open(fname, 'w') as f:
136 with open(fname, 'w') as f:
136 f.write(se_file_2)
137 f.write(se_file_2)
137
138
138 # The SyntaxError should point to the correct line
139 # The SyntaxError should point to the correct line
139 with tt.AssertPrints(["7/", "SyntaxError"]):
140 with tt.AssertPrints(["7/", "SyntaxError"]):
140 ip.magic("run " + fname)
141 ip.magic("run " + fname)
141
142
142 def test_non_syntaxerror(self):
143 def test_non_syntaxerror(self):
143 # SyntaxTB may be called with an error other than a SyntaxError
144 # SyntaxTB may be called with an error other than a SyntaxError
144 # See e.g. gh-4361
145 # See e.g. gh-4361
145 try:
146 try:
146 raise ValueError('QWERTY')
147 raise ValueError('QWERTY')
147 except ValueError:
148 except ValueError:
148 with tt.AssertPrints('QWERTY'):
149 with tt.AssertPrints('QWERTY'):
149 ip.showsyntaxerror()
150 ip.showsyntaxerror()
151
152
153 class Python3ChainedExceptionsTest(unittest.TestCase):
154 DIRECT_CAUSE_ERROR_CODE = """
155 try:
156 x = 1 + 2
157 print(not_defined_here)
158 except Exception as e:
159 x += 55
160 x - 1
161 y = {}
162 raise KeyError('uh') from e
163 """
164
165 EXCEPTION_DURING_HANDLING_CODE = """
166 try:
167 x = 1 + 2
168 print(not_defined_here)
169 except Exception as e:
170 x += 55
171 x - 1
172 y = {}
173 raise KeyError('uh')
174 """
175
176 def test_direct_cause_error(self):
177 if PY3:
178 with tt.AssertPrints(["KeyError", "NameError", "direct cause"]):
179 ip.run_cell(self.DIRECT_CAUSE_ERROR_CODE)
180
181 def test_exception_during_handling_error(self):
182 if PY3:
183 with tt.AssertPrints(["KeyError", "NameError", "During handling"]):
184 ip.run_cell(self.EXCEPTION_DURING_HANDLING_CODE)
General Comments 0
You need to be logged in to leave comments. Login now