Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/upstream/master'
Browse files Browse the repository at this point in the history
Conflicts:
	ipykernel/kernelbase.py
  • Loading branch information
Quentin Peter committed Mar 28, 2020
2 parents 99e3d4f + ff122dd commit 37ecad1
Show file tree
Hide file tree
Showing 16 changed files with 194 additions and 52 deletions.
29 changes: 23 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
language: python
python:
- "nightly"
- 3.8
- 3.7
- 3.6
- 3.5
matrix:
include:
- arch: arm64
python: "nightly"
dist: bionic
- arch: amd64
python: "nightly"
- arch: arm64
python: 3.5
- arch: amd64
python: 3.5
- arch: arm64
python: 3.6
- arch: amd64
python: 3.6
- arch: arm64
python: 3.7
- arch: amd64
python: 3.7
- arch: arm64
python: 3.8
- arch: amd64
python: 3.8
sudo: false
dist: xenial
install:
Expand Down
7 changes: 5 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ clone_depth: 1
environment:

matrix:
- python: "C:/Python38-x64"
- python: "C:/Python36-x64"
- python: "C:/Python36"
- python: "C:/Python35"

cache:
- C:\Users\appveyor\AppData\Local\pip\Cache

init:
- cmd: set PATH=%python%;%python%\scripts;%PATH%

install:
- cmd: |
python -m pip install --upgrade setuptools pip wheel
Expand All @@ -25,8 +27,9 @@ install:
pip install matplotlib numpy
pip freeze
- cmd: python -c "import ipykernel.kernelspec; ipykernel.kernelspec.install(user=True)"

test_script:
- cmd: pytest -v --cov ipykernel ipykernel
- cmd: pytest -v -x --cov ipykernel ipykernel

on_success:
- cmd: pip install codecov
Expand Down
26 changes: 26 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
Changes in IPython kernel
=========================

5.2
---

5.2.0
*****

5.2.0 Includes several bugfixes and internal logic improvements.

- Produce better traceback when kernel is interrupted (:ghpull:`491`)
- Add ``InProcessKernelClient.control_channel`` for compatibility with jupyter-client v6.0.0 (:ghpull:`489`)
- Drop support for Python 3.4 (:ghpull:`483`)
- Work around issue related to Tornado with python3.8 on Windows (:ghpull:`480`, :ghpull:`481`)
- Prevent entering event loop if it is None (:ghpull:`464`)
- Use ``shell.input_transformer_manager`` when available (:ghpull:`411`)

5.1
---

5.1.4
*****

5.1.4 Includes a few bugfixes,
especially for compatibility with Python 3.8 on Windows.

- Fix pickle issues when using inline matplotlib backend (:ghpull:`476`)
- Fix an error during kernel shutdown (:ghpull:`463`)
- Fix compatibility issues with Python 3.8 (:ghpull:`456`, :ghpull:`461`)
- Remove some dead code (:ghpull:`474`, :ghpull:`467`)

5.1.3
*****

Expand Down
33 changes: 31 additions & 2 deletions examples/embedding/inprocess_qtconsole.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
from __future__ import print_function
import os
import sys

from IPython.qt.console.rich_ipython_widget import RichIPythonWidget
from IPython.qt.inprocess import QtInProcessKernelManager
from qtconsole.rich_ipython_widget import RichIPythonWidget
from qtconsole.inprocess import QtInProcessKernelManager
from IPython.lib import guisupport


def print_process_id():
print('Process ID is:', os.getpid())


def init_asyncio_patch():
"""set default asyncio policy to be compatible with tornado
Tornado 6 (at least) is not compatible with the default
asyncio implementation on Windows
Pick the older SelectorEventLoopPolicy on Windows
if the known-incompatible default policy is in use.
do this as early as possible to make it a low priority and overrideable
ref: https://github.com/tornadoweb/tornado/issues/2608
FIXME: if/when tornado supports the defaults in asyncio,
remove and bump tornado requirement for py38
"""
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
import asyncio
try:
from asyncio import (
WindowsProactorEventLoopPolicy,
WindowsSelectorEventLoopPolicy,
)
except ImportError:
pass
# not affected
else:
if type(asyncio.get_event_loop_policy()) is WindowsProactorEventLoopPolicy:
# WindowsProactorEventLoopPolicy is not compatible with tornado 6
# fallback to the pre-3.8 default of Selector
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())

def main():
# Print the ID of the main process
print_process_id()

init_asyncio_patch()
app = guisupport.get_app_qt4()

# Create an in-process kernel
Expand Down
34 changes: 32 additions & 2 deletions examples/embedding/inprocess_terminal.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,50 @@
from __future__ import print_function
import os
import sys

from IPython.kernel.inprocess import InProcessKernelManager
from IPython.terminal.console.interactiveshell import ZMQTerminalInteractiveShell
from ipykernel.inprocess import InProcessKernelManager
from jupyter_console.ptshell import ZMQTerminalInteractiveShell


def print_process_id():
print('Process ID is:', os.getpid())


def init_asyncio_patch():
"""set default asyncio policy to be compatible with tornado
Tornado 6 (at least) is not compatible with the default
asyncio implementation on Windows
Pick the older SelectorEventLoopPolicy on Windows
if the known-incompatible default policy is in use.
do this as early as possible to make it a low priority and overrideable
ref: https://github.com/tornadoweb/tornado/issues/2608
FIXME: if/when tornado supports the defaults in asyncio,
remove and bump tornado requirement for py38
"""
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
import asyncio
try:
from asyncio import (
WindowsProactorEventLoopPolicy,
WindowsSelectorEventLoopPolicy,
)
except ImportError:
pass
# not affected
else:
if type(asyncio.get_event_loop_policy()) is WindowsProactorEventLoopPolicy:
# WindowsProactorEventLoopPolicy is not compatible with tornado 6
# fallback to the pre-3.8 default of Selector
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())


def main():
print_process_id()

# Create an in-process kernel
# >>> print_process_id()
# will print the same process ID as the main process
init_asyncio_patch()
kernel_manager = InProcessKernelManager()
kernel_manager.start_kernel()
kernel = kernel_manager.kernel
Expand Down
2 changes: 1 addition & 1 deletion examples/embedding/internal_ipkernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys

from IPython.lib.kernel import connect_qtconsole
from IPython.kernel.zmq.kernelapp import IPKernelApp
from ipykernel.kernelapp import IPKernelApp

#-----------------------------------------------------------------------------
# Functions and classes
Expand Down
2 changes: 1 addition & 1 deletion ipykernel/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version_info = (5, 2, 0, 'dev')
version_info = (5, 3, 0, 'dev')
__version__ = '.'.join(map(str, version_info[:3]))

# pep440 is annoying, beta/alpha/rc should _not_ have dots or pip/setuptools
Expand Down
7 changes: 7 additions & 0 deletions ipykernel/inprocess/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class InProcessKernelClient(KernelClient):
shell_channel_class = Type(InProcessChannel)
iopub_channel_class = Type(InProcessChannel)
stdin_channel_class = Type(InProcessChannel)
control_channel_class = Type(InProcessChannel)
hb_channel_class = Type(InProcessHBChannel)

kernel = Instance('ipykernel.inprocess.ipkernel.InProcessKernel',
Expand Down Expand Up @@ -82,6 +83,12 @@ def stdin_channel(self):
self._stdin_channel = self.stdin_channel_class(self)
return self._stdin_channel

@property
def control_channel(self):
if self._control_channel is None:
self._control_channel = self.control_channel_class(self)
return self._control_channel

@property
def hb_channel(self):
if self._hb_channel is None:
Expand Down
34 changes: 34 additions & 0 deletions ipykernel/inprocess/tests/test_kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,43 @@
from StringIO import StringIO


def _init_asyncio_patch():
"""set default asyncio policy to be compatible with tornado
Tornado 6 (at least) is not compatible with the default
asyncio implementation on Windows
Pick the older SelectorEventLoopPolicy on Windows
if the known-incompatible default policy is in use.
do this as early as possible to make it a low priority and overrideable
ref: https://github.com/tornadoweb/tornado/issues/2608
FIXME: if/when tornado supports the defaults in asyncio,
remove and bump tornado requirement for py38
"""
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
import asyncio
try:
from asyncio import (
WindowsProactorEventLoopPolicy,
WindowsSelectorEventLoopPolicy,
)
except ImportError:
pass
# not affected
else:
if type(asyncio.get_event_loop_policy()) is WindowsProactorEventLoopPolicy:
# WindowsProactorEventLoopPolicy is not compatible with tornado 6
# fallback to the pre-3.8 default of Selector
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())


class InProcessKernelTestCase(unittest.TestCase):

def setUp(self):
_init_asyncio_patch()
self.km = InProcessKernelManager()
self.km.start_kernel()
self.kc = self.km.client()
Expand Down
6 changes: 5 additions & 1 deletion ipykernel/ipkernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,11 @@ def do_shutdown(self, restart):
return dict(status='ok', restart=restart)

def do_is_complete(self, code):
status, indent_spaces = self.shell.input_splitter.check_complete(code)
transformer_manager = getattr(self.shell, 'input_transformer_manager', None)
if transformer_manager is None:
# input_splitter attribute is deprecated
transformer_manager = self.shell.input_splitter
status, indent_spaces = transformer_manager.check_complete(code)
r = {'status': status}
if status == 'incomplete':
r['indent'] = ' ' * indent_spaces
Expand Down
12 changes: 0 additions & 12 deletions ipykernel/kernelapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,18 +488,6 @@ def init_shell(self):
if self.shell:
self.shell.configurables.append(self)

def init_extensions(self):
super(IPKernelApp, self).init_extensions()
# BEGIN HARDCODED WIDGETS HACK
# Ensure ipywidgets extension is loaded if available
extension_man = self.shell.extension_manager
if 'ipywidgets' not in extension_man.loaded:
try:
extension_man.load_extension('ipywidgets')
except ImportError as e:
self.log.debug('ipywidgets package not installed. Widgets will not be available.')
# END HARDCODED WIDGETS HACK

def configure_tornado_logger(self):
""" Configure the tornado logging.Logger.
Expand Down
18 changes: 15 additions & 3 deletions ipykernel/kernelbase.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ def enter_eventloop(self):
self.log.info("Entering eventloop %s", self.eventloop)
# record handle, so we can check when this changes
eventloop = self.eventloop
if eventloop is None:
self.log.info("Exiting as there is no eventloop")
return

def advance_eventloop():
# check if eventloop changed:
if self.eventloop is not eventloop:
Expand Down Expand Up @@ -617,7 +621,7 @@ def complete_request(self, stream, ident, parent):
content = parent['content']
code = content['code']
cursor_pos = content['cursor_pos']

matches = yield gen.maybe_future(self.do_complete(code, cursor_pos))
matches = json_clean(matches)
completion_msg = self.session.send(stream, 'complete_reply',
Expand Down Expand Up @@ -923,8 +927,16 @@ def _input_request(self, prompt, ident, parent, password=False):
self.session.send(self.stdin_socket, u'input_request',
content, parent, ident=ident)
# Await a response.
reply = self._wait_input_request_reply()

while True:
try:
ident, reply = self.session.recv(self.stdin_socket, 0)
except Exception:
self.log.warning("Invalid Message:", exc_info=True)
except KeyboardInterrupt:
# re-raise KeyboardInterrupt, to truncate traceback
raise KeyboardInterrupt("Interrupted by user") from None
else:
break
try:
value = py3compat.unicode_to_str(reply['content']['value'])
except:
Expand Down
6 changes: 5 additions & 1 deletion ipykernel/pylab/backend_inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
from __future__ import print_function

import matplotlib
from matplotlib.backends.backend_agg import new_figure_manager, FigureCanvasAgg # analysis: ignore
from matplotlib.backends.backend_agg import (
new_figure_manager,
FigureCanvasAgg,
new_figure_manager_given_figure,
) # analysis: ignore
from matplotlib import colors
from matplotlib._pylab_helpers import Gcf

Expand Down

0 comments on commit 37ecad1

Please sign in to comment.