ipython startup config for spyder IDE
Question: Trying to add a few imports to my IPython profile so that when I open a kernel
in the Spyder IDE they're always loaded. Spyder has a Qt interface (I
think??), so I (a) checked to make sure I was in the right directory for the
profile using the `ipython locate` command in the terminal (OSX), and (b)
placing the following code in my `ipython_qtconsole_config.py` file:

    
    
    c.IPythonQtConsoleApp.exec_lines = ["import pandas as pd", 
                                    "pd.set_option('io.hdf.default_format', 'table')",
                                    "pd.set_option('mode.chained_assignment','raise')",
                                    "from __future__ import division, print_function"]
    

But when I open a new window and type `pd.__version__` I get the `NameError:
name 'pd' is not defined` error.

Edit: I don't have any problems if I run `ipython qtconsole` from the
Terminal.

Suggestions?

Thanks!


Answer: Whether Spyder uses a QT interface or not shouldn't be related to which of the
IPython config files you want to modify. The one you chose to modify,
`ipython_qtconsole_config.py` is the configuration file that is loaded when
you launch _IPython's_ QT console, such as with the command line command

    
    
    user@system:~$ ipython qtconsole
    

(I needed to update `pyzmq` for this to work.)

If _Spyder_ maintains a running IPython kernel and merely manages how to
display that for you, then Spyder is probably just maintaining a regular
IPython session, in which case you want your configuration settings to go into
the file `ipython_config.py` at the same directory where you found
`ipython_qtconsole_config.py`.

I manage this slightly differently than you do. Inside of `ipython_config.py`
the top few lines for me look like this:

    
    
    # Configuration file for ipython.
    from os.path import join as pjoin
    from IPython.utils.path import get_ipython_dir
    
    c = get_config()
    c.InteractiveShellApp.exec_files = [
        pjoin(get_ipython_dir(), "profile_default", "launch.py")
    ]
    

What this does is to obtain the IPython configuration directory for me, add on
the `profile_default` subdirectory, and then add on the name `launch.py` which
is a file that I created just to hold anything I want to be executed/loaded
upon startup.

For example, here's the first bit from my file `launch.py`:

    
    
    """
    IPython launch script
    Author: Ely M. Spears
    """
    
    import re
    import os
    import abc
    import sys
    import mock
    import time
    import types
    import pandas
    import inspect
    import cPickle
    import unittest
    import operator
    import warnings
    import datetime
    import dateutil
    import calendar
    import copy_reg
    import itertools
    import contextlib
    import collections
    import numpy as np
    import scipy as sp
    import scipy.stats as st
    import scipy.weave as weave
    import multiprocessing as mp
    from IPython.core.magic import (
        Magics,
        register_line_magic,
        register_cell_magic,
        register_line_cell_magic
    )
    from dateutil.relativedelta import relativedelta as drr
    
    
    ###########################
    # Pickle/Unpickle methods #
    ###########################
    
    # See explanation at:
    # < http://bytes.com/topic/python/answers/
    #   552476-why-cant-you-pickle-instancemethods >
    def _pickle_method(method):
        func_name = method.im_func.__name__
        obj = method.im_self
        cls = method.im_class
        return _unpickle_method, (func_name, obj, cls)
    
    def _unpickle_method(func_name, obj, cls):
        for cls in cls.mro():
            try:
                func = cls.__dict__[func_name]
            except KeyError:
                pass
            else:
                break
        return func.__get__(obj, cls)
    
    copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)
    
    #############
    # Utilities #
    #############
    def interface_methods(*methods):
        """
        Class decorator that can decorate an abstract base class with method names
        that must be checked in order for isinstance or issubclass to return True.
        """
        def decorator(Base):
            def __subclasshook__(Class, Subclass):
                if Class is Base:
                    all_ancestor_attrs = [ancestor_class.__dict__.keys()
                                          for ancestor_class in Subclass.__mro__]
                    if all(method in all_ancestor_attrs for method in methods):
                        return True
                return NotImplemented
            Base.__subclasshook__ = classmethod(__subclasshook__)
            return Base
    
    def interface(*attributes):
        """
        Class decorator checking for any kind of attributes, not just methods.
    
        Usage:
    
        @interface(('foo', 'bar', 'baz))
        class Blah
           pass
    
        Now, new classes will be treated as if they are subclasses of Blah, and 
        instances will be treated instances of Blah, provided they possess the
        attributes 'foo', 'bar', and 'baz'.
        """
        def decorator(Base):
            def checker(Other):
                return all(hasattr(Other, a) for a in attributes)
    
            def __subclasshook__(cls, Other):
                if checker(Other):
                    return True
                return NotImplemented
    
            def __instancecheck__(cls, Other):
                return checker(Other)
    
            Base.__metaclass__.__subclasshook__ = classmethod(__subclasshook__)
            Base.__metaclass__.__instancecheck__ = classmethod(__instancecheck__)
            return Base
        return decorator
    

There's a lot more, probably dozens of helper functions, snippets of code I've
thought are cool and just want to play with, etc. I also define some randomly
generated toy data sets, like NumPy arrays and Pandas DataFrames, so that when
I want to poke around with some one-off Pandas syntax or something, some toy
data is always right there.

The other upside is that this factors out the custom imports, function
definitions, etc. that I want loaded, so if I want the same things loaded for
the notebook and/or the qt console, I can just add the same bit of code to
exec the file `launch.py` and I can make changes in _only_ `launch.py` without
having to manually migrate them to each of the three configuration files.

I also uncomment a few of the different settings, especially for plain IPython
and for the notebook, so the config files are meaningfully different from each
other, just not based on what modules I want imported on start up.

