diff --git a/IPython/frontend/html/notebook/notebookapp.py b/IPython/frontend/html/notebook/notebookapp.py index 35a04485c..86d48fd41 100644 --- a/IPython/frontend/html/notebook/notebookapp.py +++ b/IPython/frontend/html/notebook/notebookapp.py @@ -40,6 +40,7 @@ from jinja2 import Environment, FileSystemLoader from zmq.eventloop import ioloop ioloop.install() +import tornado from tornado import httpserver from tornado import web @@ -522,6 +523,30 @@ class NotebookApp(BaseIPythonApplication): try: self.http_server.listen(port, self.ip) except socket.error as e: + # XXX: remove the e.errno == -9 block when we require + # tornado >= 3.0 + if e.errno == -9 and tornado.version_info[0] < 3: + # The flags passed to socket.getaddrinfo from + # tornado.netutils.bind_sockets can cause "gaierror: + # [Errno -9] Address family for hostname not supported" + # when the interface is not associated, for example. + # Changing the flags to exclude socket.AI_ADDRCONFIG does + # not cause this error, but the only way to do this is to + # monkeypatch socket to remove the AI_ADDRCONFIG attribute + saved_AI_ADDRCONFIG = socket.AI_ADDRCONFIG + self.log.warn('Monkeypatching socket to fix tornado bug') + del(socket.AI_ADDRCONFIG) + try: + # retry the tornado call without AI_ADDRCONFIG flags + self.http_server.listen(port, self.ip) + except socket.error as e2: + e = e2 + else: + self.port = port + success = True + break + # restore the monekypatch + socket.AI_ADDRCONFIG = saved_AI_ADDRCONFIG if e.errno != errno.EADDRINUSE: raise self.log.info('The port %i is already in use, trying another random port.' % port)