diff --git a/CMake/cdat_modules/ipython_deps.cmake b/CMake/cdat_modules/ipython_deps.cmake
index 0828bdbd98f65163dbfb7d7daa09f61e4d95d9b2..e1c592f199051cbf95c21e59c951338082e213e7 100644
--- a/CMake/cdat_modules/ipython_deps.cmake
+++ b/CMake/cdat_modules/ipython_deps.cmake
@@ -1,5 +1,5 @@
 if (CDAT_BUILD_ALL)
-  set(IPYTHON_deps ${pip_pkg} ${tornado_pkg} ${numpy_pkg} ${numexpr_pkg})
+  set(IPYTHON_deps ${pip_pkg} ${numpy_pkg} ${pyexpect_pkg} ${traitlets_pkg} ${ipython_genutils_pkg} ${tornado_pkg} ${numexpr_pkg})
 else ()
-  set(IPYTHON_deps ${pip_pkg} ${numpy_pkg})
+  set(IPYTHON_deps ${pip_pkg} ${numpy_pkg} ${pyexpect_pkg} ${traitlets_pkg} ${ipython_genutils_pkg})
 endif()
diff --git a/CMake/cdat_modules/ipython_genutils_deps.cmake b/CMake/cdat_modules/ipython_genutils_deps.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..acd34ee5e20166468e37fb14b97af2a8f7260d38
--- /dev/null
+++ b/CMake/cdat_modules/ipython_genutils_deps.cmake
@@ -0,0 +1 @@
+set(Ipython_genutils_deps ${python_pkg} ${setuptools_pkg})
diff --git a/CMake/cdat_modules/ipython_genutils_external.cmake b/CMake/cdat_modules/ipython_genutils_external.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..20f60b9da29ced562ce159d2d1fe74cb58c33c43
--- /dev/null
+++ b/CMake/cdat_modules/ipython_genutils_external.cmake
@@ -0,0 +1,14 @@
+set(Ipython_genutils_source "${CMAKE_CURRENT_BINARY_DIR}/build/Ipython_genutils")
+
+ExternalProject_Add(IPYTHON_GENUTILS
+  DOWNLOAD_DIR ${CDAT_PACKAGE_CACHE_DIR}
+  SOURCE_DIR ${Ipython_genutils_source}
+  URL ${IPYTHON_GENUTILS_URL}/${IPYTHON_GENUTILS_GZ}
+  URL_MD5 ${IPYTHON_GENUTILS_MD5}
+  BUILD_IN_SOURCE 1
+  CONFIGURE_COMMAND ""
+  BUILD_COMMAND ${PYTHON_EXECUTABLE} setup.py build
+  INSTALL_COMMAND ${PYTHON_EXECUTABLE} setup.py install ${PYTHON_EXTRA_PREFIX}
+  DEPENDS ${Ipython_genutils_deps}
+  ${ep_log_options}
+)
diff --git a/CMake/cdat_modules/ipython_genutils_pkg.cmake b/CMake/cdat_modules/ipython_genutils_pkg.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..301aa39cb5c321439bdd4a66de3e9e9cb0b839bc
--- /dev/null
+++ b/CMake/cdat_modules/ipython_genutils_pkg.cmake
@@ -0,0 +1,10 @@
+set(IPYTHON_GENUTILS_MAJOR 0)
+set(IPYTHON_GENUTILS_MINOR 1)
+set(IPYTHON_GENUTILS_PATCH 0)
+set(IPYTHON_GENUTILS_VERSION ${IPYTHON_GENUTILS_MAJOR}.${IPYTHON_GENUTILS_MINOR}.${IPYTHON_GENUTILS_PATCH})
+set(IPYTHON_GENUTILS_URL ${LLNL_URL} )
+set(IPYTHON_GENUTILS_GZ ipython_genutils-${IPYTHON_GENUTILS_VERSION}.zip)
+set(IPYTHON_GENUTILS_MD5 9bd368e7294ab372b2f6394504a65653)
+set(IPYTHON_GENUTILS_SOURCE ${IPYTHON_GENUTILS_URL}/${IPYTHON_GENUTILS_GZ})
+
+add_cdat_package(IPYTHON_GENUTILS "" "" ON)
diff --git a/CMake/cdat_modules/ipython_pkg.cmake b/CMake/cdat_modules/ipython_pkg.cmake
index ce9193f5c04f77e2b60a11e62af536e17e885c71..fac56dacecb6570e32828614b21853dca386205d 100644
--- a/CMake/cdat_modules/ipython_pkg.cmake
+++ b/CMake/cdat_modules/ipython_pkg.cmake
@@ -1,10 +1,10 @@
-set(IPYTHON_MAJOR 3)
-set(IPYTHON_MINOR 0)
-set(IPYTHON_PATCH 0)
+set(IPYTHON_MAJOR 4)
+set(IPYTHON_MINOR 1)
+set(IPYTHON_PATCH 2)
 set(IPYTHON_VERSION ${IPYTHON_MAJOR}.${IPYTHON_MINOR}.${IPYTHON_PATCH})
 set(IPYTHON_URL ${LLNL_URL})
 set(IPYTHON_GZ ipython-${IPYTHON_VERSION}.tar.gz)
-set(IPYTHON_MD5 b3f00f3c0be036fafef3b0b9d663f27e)
+set(IPYTHON_MD5 6a563c3eddc9a223c3243a38367d9483)
 set(IPYTHON_SOURCE ${IPYTHON_URL}/${IPYTHON_GZ})
 
 add_cdat_package(IPYTHON "" "" ON)
diff --git a/CMake/cdat_modules/pyexpect_deps.cmake b/CMake/cdat_modules/pyexpect_deps.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..766d794bf216bef081c7374f57b34ae7baf9d1e3
--- /dev/null
+++ b/CMake/cdat_modules/pyexpect_deps.cmake
@@ -0,0 +1 @@
+set(PYEXPECT_deps ${python_pkg} ${setuptools_pkg})
diff --git a/CMake/cdat_modules/pyexpect_external.cmake b/CMake/cdat_modules/pyexpect_external.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..1371aaecf9e4c9395532efa44b32fea0e90e5726
--- /dev/null
+++ b/CMake/cdat_modules/pyexpect_external.cmake
@@ -0,0 +1,14 @@
+set(Pyexpect_source "${CMAKE_CURRENT_BINARY_DIR}/build/Pyexpect")
+
+ExternalProject_Add(PYEXPECT
+  DOWNLOAD_DIR ${CDAT_PACKAGE_CACHE_DIR}
+  SOURCE_DIR ${Pyexpect_source}
+  URL ${PYEXPECT_URL}/${PYEXPECT_GZ}
+  URL_MD5 ${PYEXPECT_MD5}
+  BUILD_IN_SOURCE 1
+  CONFIGURE_COMMAND ""
+  BUILD_COMMAND ${PYTHON_EXECUTABLE} setup.py build
+  INSTALL_COMMAND ${PYTHON_EXECUTABLE} setup.py install ${PYTHON_EXTRA_PREFIX}
+  DEPENDS ${PYEXPECT_deps}
+  ${ep_log_options}
+)
diff --git a/CMake/cdat_modules/pyexpect_pkg.cmake b/CMake/cdat_modules/pyexpect_pkg.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0d010ea99d61b94cd1486d59ac03ff649175f46a
--- /dev/null
+++ b/CMake/cdat_modules/pyexpect_pkg.cmake
@@ -0,0 +1,10 @@
+set(PYEXPECT_MAJOR 4)
+set(PYEXPECT_MINOR 0)
+set(PYEXPECT_PATCH 1)
+set(PYEXPECT_VERSION ${PYEXPECT_MAJOR}.${PYEXPECT_MINOR}.${PYEXPECT_PATCH})
+set(PYEXPECT_URL ${LLNL_URL} )
+set(PYEXPECT_GZ pyexpect-${PYEXPECT_VERSION}.tar.gz)
+set(PYEXPECT_MD5 2bd260f7f2159f9bcab373721736d526)
+set(PYEXPECT_SOURCE ${PYEXPECT_URL}/${PYEXPECT_GZ})
+
+add_cdat_package(PYEXPECT "" "" ON)
diff --git a/CMake/cdat_modules/traitlets_deps.cmake b/CMake/cdat_modules/traitlets_deps.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..606d064ec8ba2ee9fe633cd93b293d03f08b93e8
--- /dev/null
+++ b/CMake/cdat_modules/traitlets_deps.cmake
@@ -0,0 +1 @@
+set(Traitlets_deps ${python_pkg} ${setuptools_pkg})
diff --git a/CMake/cdat_modules/traitlets_external.cmake b/CMake/cdat_modules/traitlets_external.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..55c45f152ec339147cd1690efe4d6a6fb58c00ea
--- /dev/null
+++ b/CMake/cdat_modules/traitlets_external.cmake
@@ -0,0 +1,14 @@
+set(Traitlets_source "${CMAKE_CURRENT_BINARY_DIR}/build/Traitlets")
+
+ExternalProject_Add(TRAITLETS
+  DOWNLOAD_DIR ${CDAT_PACKAGE_CACHE_DIR}
+  SOURCE_DIR ${Traitlets_source}
+  URL ${TRAITLETS_URL}/${TRAITLETS_GZ}
+  URL_MD5 ${TRAITLETS_MD5}
+  BUILD_IN_SOURCE 1
+  CONFIGURE_COMMAND ""
+  BUILD_COMMAND ${PYTHON_EXECUTABLE} setup.py build
+  INSTALL_COMMAND ${PYTHON_EXECUTABLE} setup.py install ${PYTHON_EXTRA_PREFIX}
+  DEPENDS ${Traitlets_deps}
+  ${ep_log_options}
+)
diff --git a/CMake/cdat_modules/traitlets_pkg.cmake b/CMake/cdat_modules/traitlets_pkg.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..58883d13f49489511dcac36b3421e46ed3f9097f
--- /dev/null
+++ b/CMake/cdat_modules/traitlets_pkg.cmake
@@ -0,0 +1,10 @@
+set(TRAITLETS_MAJOR 4)
+set(TRAITLETS_MINOR 0)
+set(TRAITLETS_PATCH 0)
+set(TRAITLETS_VERSION ${TRAITLETS_MAJOR}.${TRAITLETS_MINOR}.${TRAITLETS_PATCH})
+set(TRAITLETS_URL ${LLNL_URL} )
+set(TRAITLETS_GZ traitlets-${TRAITLETS_VERSION}.tar.gz)
+set(TRAITLETS_MD5 b5b95ea5941fd9619b4704dfd8201568)
+set(TRAITLETS_SOURCE ${TRAITLETS_URL}/${TRAITLETS_GZ})
+
+add_cdat_package(TRAITLETS "" "" ON)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 32b16d45335864e2cb2cd521e30267655879ff60..8747dc04f3b6d22ba91ce3d159e675f4fcdfbd08 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -491,6 +491,9 @@ include(zmq_pkg)
 include(pyzmq_pkg)
 include(tornado_pkg)
 include(ipython_pkg)
+include(ipython_genutils_pkg)
+include(pyexpect_pkg)
+include(traitlets_pkg)
 include(jasper_pkg)
 include(lapack_pkg)
 include(lepl_pkg)
diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt
index 2294881725e3a282cdab65242b6fe1d8ea31142f..1dcc2c362a110274fd564e64d412beec40c67a4e 100644
--- a/testing/CMakeLists.txt
+++ b/testing/CMakeLists.txt
@@ -63,6 +63,9 @@ if (CDAT_BUILD_PCMDI)
     add_subdirectory(pcmdi)
 endif()
 
+# Test ipython
+add_test(run_ipython ${CMAKE_INSTALL_PREFIX}/bin/ipython -V)
+
 # CMake module tests:
 # Test that out-of-source build detection is working:
 add_test(cmake_checkBuildOutOfSource