diff --git a/IPython/frontend/html/notebook/__init__.py b/IPython/frontend/html/notebook/__init__.py
index e69de29bb2d..35954cca400 100644
--- a/IPython/frontend/html/notebook/__init__.py
+++ b/IPython/frontend/html/notebook/__init__.py
@@ -0,0 +1,12 @@
+"""The IPython HTML Notebook"""
+
+# check for tornado 2.1.0
+msg = "The IPython Notebook requires tornado >= 2.1.0"
+try:
+ import tornado
+except ImportError:
+ raise ImportError(msg)
+else:
+ if tornado.version_info < (2,1,0):
+ raise ImportError(msg+", but you have %s"%tornado.version)
+del msg
diff --git a/IPython/testing/iptest.py b/IPython/testing/iptest.py
index 3f9dbdee927..97b7e5aa110 100644
--- a/IPython/testing/iptest.py
+++ b/IPython/testing/iptest.py
@@ -45,6 +45,7 @@
from nose.core import TestProgram
# Our own imports
+from IPython.utils.importstring import import_item
from IPython.utils.path import get_ipython_module_path
from IPython.utils.process import find_cmd, pycmd2argv
from IPython.utils.sysinfo import sys_info
@@ -81,18 +82,38 @@
#-----------------------------------------------------------------------------
# Logic for skipping doctests
#-----------------------------------------------------------------------------
+def extract_version(mod):
+ return mod.__version__
-def test_for(mod, min_version=None):
- """Test to see if mod is importable."""
+def test_for(item, min_version=None, callback=extract_version):
+ """Test to see if item is importable, and optionally check against a minimum
+ version.
+
+ If min_version is given, the default behavior is to check against the
+ `__version__` attribute of the item, but specifying `callback` allows you to
+ extract the value you are interested in. e.g::
+
+ In [1]: import sys
+
+ In [2]: from IPython.testing.iptest import test_for
+
+ In [3]: test_for('sys', (2,6), callback=lambda sys: sys.version_info)
+ Out[3]: True
+
+ """
try:
- __import__(mod)
+ check = import_item(item)
except (ImportError, RuntimeError):
- # GTK reports Runtime error if it can't be initialized even if it's
+ # GTK reports Runtime error if it can't be initialized even if it's
# importable.
return False
else:
if min_version:
- return sys.modules[mod].__version__ >= min_version
+ if callback:
+ # extra processing step to get version to compare
+ check = callback(check)
+
+ return check >= min_version
else:
return True
@@ -102,16 +123,27 @@ def test_for(mod, min_version=None):
have['curses'] = test_for('_curses')
have['matplotlib'] = test_for('matplotlib')
-have['pexpect'] = test_for('pexpect')
+have['pexpect'] = test_for('IPython.external.pexpect')
have['pymongo'] = test_for('pymongo')
have['wx'] = test_for('wx')
have['wx.aui'] = test_for('wx.aui')
+have['qt'] = test_for('IPython.external.qt')
+
+have['tornado'] = test_for('tornado.version_info', (2,1,0), callback=None)
+
if os.name == 'nt':
- have['zmq'] = test_for('zmq', '2.1.7')
+ min_zmq = (2,1,7)
else:
- have['zmq'] = test_for('zmq', '2.1.4')
-have['qt'] = test_for('IPython.external.qt')
-have['tornado'] = test_for('tornado')
+ min_zmq = (2,1,4)
+
+def version_tuple(mod):
+ "turn '2.1.9' into (2,1,9), and '2.1dev' into (2,1,999)"
+ # turn 'dev' into 999, because Python3 rejects str-int comparisons
+ vs = mod.__version__.replace('dev', '.999')
+ tup = tuple([int(v) for v in vs.split('.') ])
+ return tup
+
+have['zmq'] = test_for('zmq', min_zmq, version_tuple)
#-----------------------------------------------------------------------------
# Functions and classes
diff --git a/docs/source/install/install.txt b/docs/source/install/install.txt
index c5a7a938195..046f2b6ffbb 100644
--- a/docs/source/install/install.txt
+++ b/docs/source/install/install.txt
@@ -336,6 +336,7 @@ pygments
The syntax-highlighting in ``ipython qtconsole`` is done with the pygments_
project, which is easy_install-able.
+.. _installnotebook:
Dependencies for the IPython HTML notebook
==========================================
@@ -352,14 +353,11 @@ the HTML notebook requires ZeroMQ and PyZMQ.
Tornado
-------
-The IPython notebook uses the Tornado_ project for its HTTP server. As of this
-writing, we require a development version from github, as version 2.0 is *not
-sufficient*. You can either clone their git repository yourself and install it
-manually, or install directly from github with::
+The IPython notebook uses the Tornado_ project for its HTTP server. Tornado 2.1
+is required, in order to support current versions of browsers, due to an update
+to the websocket protocol.
- easy_install https://github.com/facebook/tornado/tarball/master
-
MathJax
-------
diff --git a/docs/source/interactive/htmlnotebook.txt b/docs/source/interactive/htmlnotebook.txt
index e7e102a0fbf..258c0d007a3 100644
--- a/docs/source/interactive/htmlnotebook.txt
+++ b/docs/source/interactive/htmlnotebook.txt
@@ -4,6 +4,10 @@
An HTML Notebook IPython
=========================
+.. seealso::
+
+ :ref:`Installation requirements ` for the Notebook.
+
The IPython Notebook consists of two related components:
* An JSON based Notebook document format for recording and distributing