/ipykernel/inprocess/tests/test_kernel.py

https://github.com/ipython/ipykernel · Python · 100 lines · 61 code · 14 blank · 25 comment · 9 complexity · b1db7500cd384f14f90faec01d2ced35 MD5 · raw file

  1. # Copyright (c) IPython Development Team.
  2. # Distributed under the terms of the Modified BSD License.
  3. from io import StringIO
  4. import sys
  5. import unittest
  6. from ipykernel.inprocess.blocking import BlockingInProcessKernelClient
  7. from ipykernel.inprocess.manager import InProcessKernelManager
  8. from ipykernel.inprocess.ipkernel import InProcessKernel
  9. from ipykernel.tests.utils import assemble_output
  10. from IPython.testing.decorators import skipif_not_matplotlib
  11. from IPython.utils.io import capture_output
  12. def _init_asyncio_patch():
  13. """set default asyncio policy to be compatible with tornado
  14. Tornado 6 (at least) is not compatible with the default
  15. asyncio implementation on Windows
  16. Pick the older SelectorEventLoopPolicy on Windows
  17. if the known-incompatible default policy is in use.
  18. do this as early as possible to make it a low priority and overrideable
  19. ref: https://github.com/tornadoweb/tornado/issues/2608
  20. FIXME: if/when tornado supports the defaults in asyncio,
  21. remove and bump tornado requirement for py38
  22. """
  23. if sys.platform.startswith("win") and sys.version_info >= (3, 8):
  24. import asyncio
  25. try:
  26. from asyncio import (
  27. WindowsProactorEventLoopPolicy,
  28. WindowsSelectorEventLoopPolicy,
  29. )
  30. except ImportError:
  31. pass
  32. # not affected
  33. else:
  34. if type(asyncio.get_event_loop_policy()) is WindowsProactorEventLoopPolicy:
  35. # WindowsProactorEventLoopPolicy is not compatible with tornado 6
  36. # fallback to the pre-3.8 default of Selector
  37. asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())
  38. class InProcessKernelTestCase(unittest.TestCase):
  39. def setUp(self):
  40. _init_asyncio_patch()
  41. self.km = InProcessKernelManager()
  42. self.km.start_kernel()
  43. self.kc = self.km.client()
  44. self.kc.start_channels()
  45. self.kc.wait_for_ready()
  46. @skipif_not_matplotlib
  47. def test_pylab(self):
  48. """Does %pylab work in the in-process kernel?"""
  49. kc = self.kc
  50. kc.execute('%pylab')
  51. out, err = assemble_output(kc.iopub_channel)
  52. self.assertIn('matplotlib', out)
  53. def test_raw_input(self):
  54. """ Does the in-process kernel handle raw_input correctly?
  55. """
  56. io = StringIO('foobar\n')
  57. sys_stdin = sys.stdin
  58. sys.stdin = io
  59. try:
  60. self.kc.execute('x = input()')
  61. finally:
  62. sys.stdin = sys_stdin
  63. assert self.km.kernel.shell.user_ns.get('x') == 'foobar'
  64. def test_stdout(self):
  65. """ Does the in-process kernel correctly capture IO?
  66. """
  67. kernel = InProcessKernel()
  68. with capture_output() as io:
  69. kernel.shell.run_cell('print("foo")')
  70. assert io.stdout == 'foo\n'
  71. kc = BlockingInProcessKernelClient(kernel=kernel, session=kernel.session)
  72. kernel.frontends.append(kc)
  73. kc.execute('print("bar")')
  74. out, err = assemble_output(kc.iopub_channel)
  75. assert out == 'bar\n'
  76. def test_getpass_stream(self):
  77. "Tests that kernel getpass accept the stream parameter"
  78. kernel = InProcessKernel()
  79. kernel._allow_stdin = True
  80. kernel._input_request = lambda *args, **kwargs : None
  81. kernel.getpass(stream='non empty')