diff --git a/IPython/utils/tempdir.py b/IPython/utils/tempdir.py
new file mode 100644
index 0000000..57f02fc
--- /dev/null
+++ b/IPython/utils/tempdir.py
@@ -0,0 +1,76 @@
+"""TemporaryDirectory class, copied from Python 3.2.
+
+This is copied from the stdlib and will be standard in Python 3.2 and onwards.
+"""
+
+# This code should only be used in Python versions < 3.2, since after that we
+# can rely on the stdlib itself.
+try:
+    from tempfile import TemporaryDirectory
+
+except ImportError:
+    
+    import os as _os
+    from tempfile import mkdtemp, template
+
+    class TemporaryDirectory(object):
+        """Create and return a temporary directory.  This has the same
+        behavior as mkdtemp but can be used as a context manager.  For
+        example:
+
+            with TemporaryDirectory() as tmpdir:
+                ...
+
+        Upon exiting the context, the directory and everthing contained
+        in it are removed.
+        """
+
+        def __init__(self, suffix="", prefix=template, dir=None):
+            self.name = mkdtemp(suffix, prefix, dir)
+            self._closed = False
+
+        def __enter__(self):
+            return self.name
+
+        def cleanup(self):
+            if not self._closed:
+                self._rmtree(self.name)
+                self._closed = True
+
+        def __exit__(self, exc, value, tb):
+            self.cleanup()
+
+        __del__ = cleanup
+
+
+        # XXX (ncoghlan): The following code attempts to make
+        # this class tolerant of the module nulling out process
+        # that happens during CPython interpreter shutdown
+        # Alas, it doesn't actually manage it. See issue #10188
+        _listdir = staticmethod(_os.listdir)
+        _path_join = staticmethod(_os.path.join)
+        _isdir = staticmethod(_os.path.isdir)
+        _remove = staticmethod(_os.remove)
+        _rmdir = staticmethod(_os.rmdir)
+        _os_error = _os.error
+
+        def _rmtree(self, path):
+            # Essentially a stripped down version of shutil.rmtree.  We can't
+            # use globals because they may be None'ed out at shutdown.
+            for name in self._listdir(path):
+                fullname = self._path_join(path, name)
+                try:
+                    isdir = self._isdir(fullname)
+                except self._os_error:
+                    isdir = False
+                if isdir:
+                    self._rmtree(fullname)
+                else:
+                    try:
+                        self._remove(fullname)
+                    except self._os_error:
+                        pass
+            try:
+                self._rmdir(path)
+            except self._os_error:
+                pass