Repository: ipython/ipython

Issue:
ipython_directive causing `OperationalError: attempt to write a readonly database`
I have a minimal sphinx project generated by `sphinx_quickstart` and with the `conf.py` edited only to add:

```
extensions = ['IPython.sphinxext.ipython_console_highlighting',
              'IPython.sphinxext.ipython_directive']
```

I added a file `ipy_eg.rst` containing:

```
.. ipython::

    In [1]: x = 1
```

Running `make html` builds a correct-looking html page, but always exits with this error:

```
build succeeded, 1 warning.
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/Users/mb312/.virtualenvs/regreg/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 3394, in atexit_operations
    self.history_manager.end_session()
  File "/Users/mb312/.virtualenvs/regreg/lib/python2.7/site-packages/IPython/core/history.py", line 547, in end_session
    len(self.input_hist_parsed)-1, self.session_number))
OperationalError: attempt to write a readonly database
Error in sys.exitfunc:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
    func(*targs, **kargs)
  File "/Users/mb312/.virtualenvs/regreg/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 3394, in atexit_operations
    self.history_manager.end_session()
  File "/Users/mb312/.virtualenvs/regreg/lib/python2.7/site-packages/IPython/core/history.py", line 547, in end_session
    len(self.input_hist_parsed)-1, self.session_number))
sqlite3.OperationalError: attempt to write a readonly database
```

I'm running ipython current master, and my history file is writeable.

```
$ ipython --version
4.1.0-dev
$ ls -al $(ipython locate)/profile_default/history.sqlite
-rw-r--r--  1 mb312  staff  15002624 Sep 29 21:57 /Users/mb312/.ipython/profile_default/history.sqlite
```



Discussion:
I have seen this too building the matplotlib docs. I believe it happened when upgrading to 4.0. Perhaps fixed by #8846? 

It's probable that the directive should be using `:memory:` by default, anyway. I doubt people really want sphinx builds to be populating their command history.

This wouldn't be fixed by #8846, since that only catches the creation of the session, whereas the reported traceback doesn't seem to fail until the last operation.


Resolving patch:
diff --git a/IPython/sphinxext/ipython_directive.py b/IPython/sphinxext/ipython_directive.py
--- a/IPython/sphinxext/ipython_directive.py
+++ b/IPython/sphinxext/ipython_directive.py
@@ -135,16 +135,9 @@
 import warnings
 import shutil
 
-# To keep compatibility with various python versions
-try:
-    from hashlib import md5
-except ImportError:
-    from md5 import md5
 
 # Third-party
-import sphinx
 from docutils.parsers.rst import directives
-from docutils import nodes
 from sphinx.util.compat import Directive
 
 # Our own
@@ -285,6 +278,7 @@ def __init__(self, exec_lines=None):
 
         # Create config object for IPython
         config = Config()
+        config.HistoryManager.hist_file = ':memory:'
         config.InteractiveShell.autocall = False
         config.InteractiveShell.autoindent = False
         config.InteractiveShell.colors = 'NoColor'
@@ -856,14 +850,14 @@ def get_config_options(self):
         config = self.state.document.settings.env.config
 
         # get config variables to set figure output directory
-        confdir = self.state.document.settings.env.app.confdir
+        outdir = self.state.document.settings.env.app.outdir
         savefig_dir = config.ipython_savefig_dir
         source_dir = os.path.dirname(self.state.document.current_source)
         if savefig_dir is None:
-            savefig_dir = config.html_static_path
+            savefig_dir = config.html_static_path or '_static'
         if isinstance(savefig_dir, list):
-            savefig_dir = savefig_dir[0] # safe to assume only one path?
-        savefig_dir = os.path.join(confdir, savefig_dir)
+            savefig_dir = os.path.join(*savefig_dir)
+        savefig_dir = os.path.join(outdir, savefig_dir)
 
         # get regex and prompt stuff
         rgxin      = config.ipython_rgxin


Test patch: