Show More
@@ -27,7 +27,11 b' from IPython.core.inputtransformer import InputTransformer' | |||
|
27 | 27 | from IPython.core import interactiveshell |
|
28 | 28 | from IPython.core.oinspect import OInfo |
|
29 | 29 | from IPython.testing.decorators import ( |
|
30 | skipif, skip_win32, onlyif_unicode_paths, onlyif_cmds_exist, | |
|
30 | skipif, | |
|
31 | skip_win32, | |
|
32 | onlyif_unicode_paths, | |
|
33 | onlyif_cmds_exist, | |
|
34 | skip_if_not_osx, | |
|
31 | 35 | ) |
|
32 | 36 | from IPython.testing import tools as tt |
|
33 | 37 | from IPython.utils.process import find_cmd |
@@ -124,16 +128,16 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
124 | 128 | newlen = len(ip.user_ns['In']) |
|
125 | 129 | self.assertEqual(oldlen+1, newlen) |
|
126 | 130 | self.assertEqual(ip.user_ns['In'][-1],'1;') |
|
127 | ||
|
131 | ||
|
128 | 132 | def test_magic_names_in_string(self): |
|
129 | 133 | ip.run_cell('a = """\n%exit\n"""') |
|
130 | 134 | self.assertEqual(ip.user_ns['a'], '\n%exit\n') |
|
131 | ||
|
135 | ||
|
132 | 136 | def test_trailing_newline(self): |
|
133 | 137 | """test that running !(command) does not raise a SyntaxError""" |
|
134 | 138 | ip.run_cell('!(true)\n', False) |
|
135 | 139 | ip.run_cell('!(true)\n\n\n', False) |
|
136 | ||
|
140 | ||
|
137 | 141 | def test_gh_597(self): |
|
138 | 142 | """Pretty-printing lists of objects with non-ascii reprs may cause |
|
139 | 143 | problems.""" |
@@ -142,8 +146,7 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
142 | 146 | return "\xe9"*50 |
|
143 | 147 | import IPython.core.formatters |
|
144 | 148 | f = IPython.core.formatters.PlainTextFormatter() |
|
145 | f([Spam(),Spam()]) | |
|
146 | ||
|
149 | f([Spam(), Spam()]) | |
|
147 | 150 | |
|
148 | 151 | def test_future_flags(self): |
|
149 | 152 | """Check that future flags are used for parsing code (gh-777)""" |
@@ -163,9 +166,9 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
163 | 166 | " def __init__(self,x=[]):\n" |
|
164 | 167 | " list.__init__(self,x)")) |
|
165 | 168 | ip.run_cell("w=Mylist([1,2,3])") |
|
166 | ||
|
169 | ||
|
167 | 170 | from pickle import dumps |
|
168 | ||
|
171 | ||
|
169 | 172 | # We need to swap in our main module - this is only necessary |
|
170 | 173 | # inside the test framework, because IPython puts the interactive module |
|
171 | 174 | # in place (but the test framework undoes this). |
@@ -176,7 +179,7 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
176 | 179 | finally: |
|
177 | 180 | sys.modules['__main__'] = _main |
|
178 | 181 | self.assertTrue(isinstance(res, bytes)) |
|
179 | ||
|
182 | ||
|
180 | 183 | def test_global_ns(self): |
|
181 | 184 | "Code in functions must be able to access variables outside them." |
|
182 | 185 | ip = get_ipython() |
@@ -222,13 +225,13 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
222 | 225 | self.assertEqual(ip.var_expand(u'echo {f}'), u'echo Ca\xf1o') |
|
223 | 226 | self.assertEqual(ip.var_expand(u'echo {f[:-1]}'), u'echo Ca\xf1') |
|
224 | 227 | self.assertEqual(ip.var_expand(u'echo {1*2}'), u'echo 2') |
|
225 | ||
|
228 | ||
|
226 | 229 | self.assertEqual(ip.var_expand(u"grep x | awk '{print $1}'"), u"grep x | awk '{print $1}'") |
|
227 | 230 | |
|
228 | 231 | ip.user_ns['f'] = b'Ca\xc3\xb1o' |
|
229 | 232 | # This should not raise any exception: |
|
230 | 233 | ip.var_expand(u'echo $f') |
|
231 | ||
|
234 | ||
|
232 | 235 | def test_var_expand_local(self): |
|
233 | 236 | """Test local variable expansion in !system and %magic calls""" |
|
234 | 237 | # !system |
@@ -253,7 +256,7 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
253 | 256 | |
|
254 | 257 | def test_var_expand_self(self): |
|
255 | 258 | """Test variable expansion with the name 'self', which was failing. |
|
256 | ||
|
259 | ||
|
257 | 260 | See https://github.com/ipython/ipython/issues/1878#issuecomment-7698218 |
|
258 | 261 | """ |
|
259 | 262 | ip.run_cell( |
@@ -273,7 +276,7 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
273 | 276 | self.assertEqual(ip.var_expand(u"{asdf}"), u"{asdf}") |
|
274 | 277 | # ZeroDivisionError |
|
275 | 278 | self.assertEqual(ip.var_expand(u"{1/0}"), u"{1/0}") |
|
276 | ||
|
279 | ||
|
277 | 280 | def test_silent_postexec(self): |
|
278 | 281 | """run_cell(silent=True) doesn't invoke pre/post_run_cell callbacks""" |
|
279 | 282 | pre_explicit = mock.Mock() |
@@ -281,12 +284,12 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
281 | 284 | post_explicit = mock.Mock() |
|
282 | 285 | post_always = mock.Mock() |
|
283 | 286 | all_mocks = [pre_explicit, pre_always, post_explicit, post_always] |
|
284 | ||
|
287 | ||
|
285 | 288 | ip.events.register('pre_run_cell', pre_explicit) |
|
286 | 289 | ip.events.register('pre_execute', pre_always) |
|
287 | 290 | ip.events.register('post_run_cell', post_explicit) |
|
288 | 291 | ip.events.register('post_execute', post_always) |
|
289 | ||
|
292 | ||
|
290 | 293 | try: |
|
291 | 294 | ip.run_cell("1", silent=True) |
|
292 | 295 | assert pre_always.called |
@@ -317,29 +320,29 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
317 | 320 | ip.events.unregister('pre_execute', pre_always) |
|
318 | 321 | ip.events.unregister('post_run_cell', post_explicit) |
|
319 | 322 | ip.events.unregister('post_execute', post_always) |
|
320 | ||
|
323 | ||
|
321 | 324 | def test_silent_noadvance(self): |
|
322 | 325 | """run_cell(silent=True) doesn't advance execution_count""" |
|
323 | 326 | ec = ip.execution_count |
|
324 | 327 | # silent should force store_history=False |
|
325 | 328 | ip.run_cell("1", store_history=True, silent=True) |
|
326 | ||
|
329 | ||
|
327 | 330 | self.assertEqual(ec, ip.execution_count) |
|
328 | 331 | # double-check that non-silent exec did what we expected |
|
329 | 332 | # silent to avoid |
|
330 | 333 | ip.run_cell("1", store_history=True) |
|
331 | 334 | self.assertEqual(ec+1, ip.execution_count) |
|
332 | ||
|
335 | ||
|
333 | 336 | def test_silent_nodisplayhook(self): |
|
334 | 337 | """run_cell(silent=True) doesn't trigger displayhook""" |
|
335 | 338 | d = dict(called=False) |
|
336 | ||
|
339 | ||
|
337 | 340 | trap = ip.display_trap |
|
338 | 341 | save_hook = trap.hook |
|
339 | ||
|
342 | ||
|
340 | 343 | def failing_hook(*args, **kwargs): |
|
341 | 344 | d['called'] = True |
|
342 | ||
|
345 | ||
|
343 | 346 | try: |
|
344 | 347 | trap.hook = failing_hook |
|
345 | 348 | res = ip.run_cell("1", silent=True) |
@@ -354,7 +357,7 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
354 | 357 | |
|
355 | 358 | def test_ofind_line_magic(self): |
|
356 | 359 | from IPython.core.magic import register_line_magic |
|
357 | ||
|
360 | ||
|
358 | 361 | @register_line_magic |
|
359 | 362 | def lmagic(line): |
|
360 | 363 | "A line magic" |
@@ -370,10 +373,10 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
370 | 373 | parent=None, |
|
371 | 374 | ) |
|
372 | 375 | self.assertEqual(lfind, info) |
|
373 | ||
|
376 | ||
|
374 | 377 | def test_ofind_cell_magic(self): |
|
375 | 378 | from IPython.core.magic import register_cell_magic |
|
376 | ||
|
379 | ||
|
377 | 380 | @register_cell_magic |
|
378 | 381 | def cmagic(line, cell): |
|
379 | 382 | "A cell magic" |
@@ -490,7 +493,7 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
490 | 493 | def my_handler(shell, etype, value, tb, tb_offset=None): |
|
491 | 494 | called.append(etype) |
|
492 | 495 | shell.showtraceback((etype, value, tb), tb_offset=tb_offset) |
|
493 | ||
|
496 | ||
|
494 | 497 | ip.set_custom_exc((ValueError,), my_handler) |
|
495 | 498 | try: |
|
496 | 499 | res = ip.run_cell("raise ValueError('test')") |
@@ -501,7 +504,7 b' class InteractiveShellTestCase(unittest.TestCase):' | |||
|
501 | 504 | finally: |
|
502 | 505 | # Reset the custom exception hook |
|
503 | 506 | ip.set_custom_exc((), None) |
|
504 | ||
|
507 | ||
|
505 | 508 | @mock.patch("builtins.print") |
|
506 | 509 | def test_showtraceback_with_surrogates(self, mocked_print): |
|
507 | 510 | values = [] |
@@ -618,7 +621,7 b' class ExitCodeChecks(tt.TempFileMixin):' | |||
|
618 | 621 | def test_exit_code_error(self): |
|
619 | 622 | self.system('exit 1') |
|
620 | 623 | self.assertEqual(ip.user_ns['_exit_code'], 1) |
|
621 | ||
|
624 | ||
|
622 | 625 | @skipif(not hasattr(signal, 'SIGALRM')) |
|
623 | 626 | def test_exit_code_signal(self): |
|
624 | 627 | self.mktmp("import signal, time\n" |
@@ -626,7 +629,7 b' class ExitCodeChecks(tt.TempFileMixin):' | |||
|
626 | 629 | "time.sleep(1)\n") |
|
627 | 630 | self.system("%s %s" % (sys.executable, self.fname)) |
|
628 | 631 | self.assertEqual(ip.user_ns['_exit_code'], -signal.SIGALRM) |
|
629 | ||
|
632 | ||
|
630 | 633 | @onlyif_cmds_exist("csh") |
|
631 | 634 | def test_exit_code_signal_csh(self): # pragma: no cover |
|
632 | 635 | SHELL = os.environ.get("SHELL", None) |
@@ -730,7 +733,7 b' class TestAstTransform(unittest.TestCase):' | |||
|
730 | 733 | def setUp(self): |
|
731 | 734 | self.negator = Negator() |
|
732 | 735 | ip.ast_transformers.append(self.negator) |
|
733 | ||
|
736 | ||
|
734 | 737 | def tearDown(self): |
|
735 | 738 | ip.ast_transformers.remove(self.negator) |
|
736 | 739 | |
@@ -752,7 +755,7 b' class TestAstTransform(unittest.TestCase):' | |||
|
752 | 755 | def f(x): |
|
753 | 756 | called.add(x) |
|
754 | 757 | ip.push({'f':f}) |
|
755 | ||
|
758 | ||
|
756 | 759 | with tt.AssertPrints("std. dev. of"): |
|
757 | 760 | ip.run_line_magic("timeit", "-n1 f(1)") |
|
758 | 761 | self.assertEqual(called, {-1}) |
@@ -761,29 +764,29 b' class TestAstTransform(unittest.TestCase):' | |||
|
761 | 764 | with tt.AssertPrints("std. dev. of"): |
|
762 | 765 | ip.run_cell_magic("timeit", "-n1 f(2)", "f(3)") |
|
763 | 766 | self.assertEqual(called, {-2, -3}) |
|
764 | ||
|
767 | ||
|
765 | 768 | def test_time(self): |
|
766 | 769 | called = [] |
|
767 | 770 | def f(x): |
|
768 | 771 | called.append(x) |
|
769 | 772 | ip.push({'f':f}) |
|
770 | ||
|
773 | ||
|
771 | 774 | # Test with an expression |
|
772 | 775 | with tt.AssertPrints("Wall time: "): |
|
773 | 776 | ip.run_line_magic("time", "f(5+9)") |
|
774 | 777 | self.assertEqual(called, [-14]) |
|
775 | 778 | called[:] = [] |
|
776 | ||
|
779 | ||
|
777 | 780 | # Test with a statement (different code path) |
|
778 | 781 | with tt.AssertPrints("Wall time: "): |
|
779 | 782 | ip.run_line_magic("time", "a = f(-3 + -2)") |
|
780 | 783 | self.assertEqual(called, [5]) |
|
781 | ||
|
784 | ||
|
782 | 785 | def test_macro(self): |
|
783 | 786 | ip.push({'a':10}) |
|
784 | 787 | # The AST transformation makes this do a+=-1 |
|
785 | 788 | ip.define_macro("amacro", "a+=1\nprint(a)") |
|
786 | ||
|
789 | ||
|
787 | 790 | with tt.AssertPrints("9"): |
|
788 | 791 | ip.run_cell("amacro") |
|
789 | 792 | with tt.AssertPrints("8"): |
@@ -836,21 +839,21 b' class TestAstTransform2(unittest.TestCase):' | |||
|
836 | 839 | def setUp(self): |
|
837 | 840 | self.intwrapper = IntegerWrapper() |
|
838 | 841 | ip.ast_transformers.append(self.intwrapper) |
|
839 | ||
|
842 | ||
|
840 | 843 | self.calls = [] |
|
841 | 844 | def Integer(*args): |
|
842 | 845 | self.calls.append(args) |
|
843 | 846 | return args |
|
844 | 847 | ip.push({"Integer": Integer}) |
|
845 | ||
|
848 | ||
|
846 | 849 | def tearDown(self): |
|
847 | 850 | ip.ast_transformers.remove(self.intwrapper) |
|
848 | 851 | del ip.user_ns['Integer'] |
|
849 | ||
|
852 | ||
|
850 | 853 | def test_run_cell(self): |
|
851 | 854 | ip.run_cell("n = 2") |
|
852 | 855 | self.assertEqual(self.calls, [(2,)]) |
|
853 | ||
|
856 | ||
|
854 | 857 | # This shouldn't throw an error |
|
855 | 858 | ip.run_cell("o = 2.0") |
|
856 | 859 | self.assertEqual(ip.user_ns['o'], 2.0) |
@@ -887,10 +890,10 b' class TestAstTransformError(unittest.TestCase):' | |||
|
887 | 890 | def test_unregistering(self): |
|
888 | 891 | err_transformer = ErrorTransformer() |
|
889 | 892 | ip.ast_transformers.append(err_transformer) |
|
890 | ||
|
893 | ||
|
891 | 894 | with self.assertWarnsRegex(UserWarning, "It will be unregistered"): |
|
892 | 895 | ip.run_cell("1 + 2") |
|
893 | ||
|
896 | ||
|
894 | 897 | # This should have been removed. |
|
895 | 898 | self.assertNotIn(err_transformer, ip.ast_transformers) |
|
896 | 899 | |
@@ -901,7 +904,7 b' class StringRejector(ast.NodeTransformer):' | |||
|
901 | 904 | Used to verify that NodeTransformers can signal that a piece of code should |
|
902 | 905 | not be executed by throwing an InputRejected. |
|
903 | 906 | """ |
|
904 | ||
|
907 | ||
|
905 | 908 | def visit_Constant(self, node): |
|
906 | 909 | if isinstance(node.value, str): |
|
907 | 910 | raise InputRejected("test") |
@@ -941,18 +944,18 b' def test__IPYTHON__():' | |||
|
941 | 944 | class DummyRepr(object): |
|
942 | 945 | def __repr__(self): |
|
943 | 946 | return "DummyRepr" |
|
944 | ||
|
947 | ||
|
945 | 948 | def _repr_html_(self): |
|
946 | 949 | return "<b>dummy</b>" |
|
947 | ||
|
950 | ||
|
948 | 951 | def _repr_javascript_(self): |
|
949 | 952 | return "console.log('hi');", {'key': 'value'} |
|
950 | ||
|
953 | ||
|
951 | 954 | |
|
952 | 955 | def test_user_variables(): |
|
953 | 956 | # enable all formatters |
|
954 | 957 | ip.display_formatter.active_types = ip.display_formatter.format_types |
|
955 | ||
|
958 | ||
|
956 | 959 | ip.user_ns['dummy'] = d = DummyRepr() |
|
957 | 960 | keys = {'dummy', 'doesnotexist'} |
|
958 | 961 | r = ip.user_expressions({ key:key for key in keys}) |
@@ -974,7 +977,7 b' def test_user_variables():' | |||
|
974 | 977 | |
|
975 | 978 | # back to text only |
|
976 | 979 | ip.display_formatter.active_types = ['text/plain'] |
|
977 | ||
|
980 | ||
|
978 | 981 | def test_user_expression(): |
|
979 | 982 | # enable all formatters |
|
980 | 983 | ip.display_formatter.active_types = ip.display_formatter.format_types |
@@ -1199,3 +1202,20 b' class TestShowTracebackAttack(unittest.TestCase):' | |||
|
1199 | 1202 | assert result.result is None |
|
1200 | 1203 | assert isinstance(result.error_in_exec, AssertionError) |
|
1201 | 1204 | assert str(result.error_in_exec) == "This should not raise an exception" |
|
1205 | ||
|
1206 | ||
|
1207 | @skip_if_not_osx | |
|
1208 | def test_enable_gui_osx(): | |
|
1209 | simple_prompt = ip.simple_prompt | |
|
1210 | ip.simple_prompt = False | |
|
1211 | ||
|
1212 | ip.enable_gui("osx") | |
|
1213 | assert ip.active_eventloop == "osx" | |
|
1214 | ip.enable_gui() | |
|
1215 | ||
|
1216 | # The following line fails for IPython <= 8.25.0 | |
|
1217 | ip.enable_gui("macosx") | |
|
1218 | assert ip.active_eventloop == "osx" | |
|
1219 | ip.enable_gui() | |
|
1220 | ||
|
1221 | ip.simple_prompt = simple_prompt |
@@ -943,6 +943,11 b' class TerminalInteractiveShell(InteractiveShell):' | |||
|
943 | 943 | active_eventloop: Optional[str] = None |
|
944 | 944 | |
|
945 | 945 | def enable_gui(self, gui: Optional[str] = None) -> None: |
|
946 | if gui: | |
|
947 | from ..core.pylabtools import _convert_gui_from_matplotlib | |
|
948 | ||
|
949 | gui = _convert_gui_from_matplotlib(gui) | |
|
950 | ||
|
946 | 951 | if self.simple_prompt is True and gui is not None: |
|
947 | 952 | print( |
|
948 | 953 | f'Cannot install event loop hook for "{gui}" when running with `--simple-prompt`.' |
@@ -147,10 +147,13 b' skip_osx = skipif(sys.platform == \'darwin\',"This test does not run under OS X")' | |||
|
147 | 147 | |
|
148 | 148 | |
|
149 | 149 | # Decorators to skip tests if not on specific platforms. |
|
150 |
skip_if_not_win32 = skipif(sys.platform != |
|
|
151 | "This test only runs under Windows") | |
|
152 | skip_if_not_linux = skipif(not sys.platform.startswith('linux'), | |
|
153 | "This test only runs under Linux") | |
|
150 | skip_if_not_win32 = skipif(sys.platform != "win32", "This test only runs under Windows") | |
|
151 | skip_if_not_linux = skipif( | |
|
152 | not sys.platform.startswith("linux"), "This test only runs under Linux" | |
|
153 | ) | |
|
154 | skip_if_not_osx = skipif( | |
|
155 | not sys.platform.startswith("darwin"), "This test only runs under macOS" | |
|
156 | ) | |
|
154 | 157 | |
|
155 | 158 | _x11_skip_cond = (sys.platform not in ('darwin', 'win32') and |
|
156 | 159 | os.environ.get('DISPLAY', '') == '') |
General Comments 0
You need to be logged in to leave comments.
Login now