From: Carlos Pita <[email-masked]>
Date: Mon, 2 Feb 2015 14:38:15 -0300

Just in case, here is the modified code for both completion setups
(I'm not listing the minor changes to
python-shell-completion-native-get-completions below):

(defcustom python-shell-completion-setup-code
  "def __PYTHON_EL_get_completions(text):
    try:
        import __builtin__
    except ImportError:  # Python 3
        import builtins as __builtin__
    builtins = dir(__builtin__)
    is_ipython = ('__IPYTHON__' in builtins or
                  '__IPYTHON__active' in builtins)
    completions = []
    try:
        if is_ipython:
            splits = text.split()
            is_module = splits and splits[0] in ('from', 'import')
            if is_module:
                from IPython.core.completerlib import module_completion
                completions = module_completion(text.strip())
            elif '__IP' in builtins:
                completions = __IP.complete(text)
            elif 'get_ipython' in builtins:
                completions = get_ipython().Completer.all_completions(text)
        else:  # Never do this in IPython as it overrides the completer!
            import readline, rlcompleter
            i = 0
            while True:
                res = readline.get_completer()(text, i)
                if not res:
                   break
                i += 1
                completions.append(res)
    except:
        pass
    return completions"
  "Code used to setup completion in inferior Python processes."
  :type 'string
  :group 'python)

(defun python-shell-completion-native-setup ()
  "Try to setup native completion, return non-nil on success."
  (let ((process (python-shell-get-process)))
    (python-shell-send-string
     (funcall
      'mapconcat
      #'identity
      (list
       "try:"
       "    import readline"
       "    def completer(text, state, c=readline.get_completer()):"
       "        completion = c(text, state)"
       "        if not completion and state == 1:"
       "            return text + '__dummy_completion__'"
       "        else:"
       "            return completion"
       "    readline.set_completer(completer)"
       "    if readline.__doc__ and 'libedit' in readline.__doc__:"
       "        readline.parse_and_bind('bind ^I rl_complete')"
       "    else:"
       "        readline.parse_and_bind('tab: complete')"
       "    print ('python.el: readline is available')"
       "    del completer, readline  # Some cleanup"
       "except:"
       "    print ('python.el: readline not available')")
      "\n")
     process)
    (python-shell-accept-process-output process)
    (when (save-excursion
            (re-search-backward
             (regexp-quote "python.el: readline is available") nil t 1))
      (python-shell-completion-native-try))))