Skip to content

Commit ef3820b

Browse files
Merge pull request #43 from maartenbreddels/fix_tornado6
Fix for tornado6
2 parents 4180bc8 + 2e104da commit ef3820b

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

.travis.yml

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ before_install:
2727
fi
2828
2929
install:
30-
- pip install --pre .[test]
30+
- pip install --pre .[test] $EXTRA_PIP
3131
- wget https://github.com/jgm/pandoc/releases/download/1.19.1/pandoc-1.19.1-1-amd64.deb && sudo dpkg -i pandoc-1.19.1-1-amd64.deb
3232

3333

@@ -69,6 +69,10 @@ matrix:
6969
dist: xenial # required for Python >= 3.7 (travis-ci/travis-ci#9069)
7070
- python: 3.6
7171
env: GROUP=docs
72+
- python: 3.6 # extra test for older tornados
73+
env:
74+
- GROUP=python
75+
- EXTRA_PIP="tornado<5"
7276

7377
after_success:
7478
- codecov

jupyter_server/base/zmqhandlers.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ def open(self, *args, **kwargs):
172172

173173
def send_ping(self):
174174
"""send a ping to keep the websocket alive"""
175-
if self.stream.closed() and self.ping_callback is not None:
175+
if self.ws_connection is None and self.ping_callback is not None:
176176
self.ping_callback.stop()
177177
return
178178

@@ -237,7 +237,7 @@ def _reserialize_reply(self, msg_or_list, channel=None):
237237
def _on_zmq_reply(self, stream, msg_list):
238238
# Sometimes this gets triggered when the on_close method is scheduled in the
239239
# eventloop but hasn't been called.
240-
if self.stream.closed() or stream.closed():
240+
if self.ws_connection is None or stream.closed():
241241
self.log.warning("zmq message arrived on closed channel")
242242
self.close()
243243
return
@@ -281,7 +281,8 @@ def get(self, *args, **kwargs):
281281
# assign and yield in two step to avoid tornado 3 issues
282282
res = self.pre_get()
283283
yield gen.maybe_future(res)
284-
super(AuthenticatedZMQStreamHandler, self).get(*args, **kwargs)
284+
res = super(AuthenticatedZMQStreamHandler, self).get(*args, **kwargs)
285+
yield gen.maybe_future(res)
285286

286287
def initialize(self):
287288
self.log.debug("Initializing websocket connection %s", self.request.path)

jupyter_server/utils.py

+47
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,30 @@
1212
import sys
1313
from distutils.version import LooseVersion
1414

15+
try:
16+
from inspect import isawaitable
17+
except ImportError:
18+
def isawaitable(f):
19+
"""If isawaitable is undefined, nothing is awaitable"""
20+
return False
21+
22+
try:
23+
from concurrent.futures import Future as ConcurrentFuture
24+
except ImportError:
25+
class ConcurrentFuture:
26+
"""If concurrent.futures isn't importable, nothing will be a c.f.Future"""
27+
pass
28+
1529
try:
1630
from urllib.parse import quote, unquote, urlparse
1731
except ImportError:
1832
from urllib import quote, unquote
1933
from urlparse import urlparse
2034

35+
# tornado.concurrent.Future is asyncio.Future
36+
# in tornado >=5 with Python 3
37+
from tornado.concurrent import Future as TornadoFuture
38+
from tornado import gen
2139
from ipython_genutils import py3compat
2240

2341
# UF_HIDDEN is a stat flag not defined in the stat module.
@@ -305,3 +323,32 @@ def _check_pid_posix(pid):
305323
check_pid = _check_pid_win32
306324
else:
307325
check_pid = _check_pid_posix
326+
327+
328+
def maybe_future(obj):
329+
"""Like tornado's gen.maybe_future
330+
but more compatible with asyncio for recent versions
331+
of tornado
332+
"""
333+
if isinstance(obj, TornadoFuture):
334+
return obj
335+
elif isawaitable(obj):
336+
return asyncio.ensure_future(obj)
337+
elif isinstance(obj, ConcurrentFuture):
338+
return asyncio.wrap_future(obj)
339+
else:
340+
# not awaitable, wrap scalar in future
341+
f = TornadoFuture()
342+
f.set_result(obj)
343+
return f
344+
345+
# monkeypatch tornado gen.maybe_future
346+
# on Python 3
347+
# TODO: remove monkeypatch after backporting smaller fix to 5.x
348+
try:
349+
import asyncio
350+
except ImportError:
351+
pass
352+
else:
353+
import tornado.gen
354+
tornado.gen.maybe_future = maybe_future

0 commit comments

Comments
 (0)