From: Carlos Pita <[email-masked]>
Date: Mon, 2 Feb 2015 16:27:01 -0300

Patch updated against the current master.
From d3ceebd6ea08475b7f72090e0a219a51aaac21fd Mon Sep 17 00:00:00 2001
From: memeplex <[email-masked]>
Date: Mon, 2 Feb 2015 14:59:24 -0300
Subject: [PATCH] python.el: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19736

---
 .emacs.d/lisp/python.el | 79 ++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 40 deletions(-)

diff --git a/.emacs.d/lisp/python.el b/.emacs.d/lisp/python.el
index b959fc4..5f8a9e8 100644
--- a/.emacs.d/lisp/python.el
+++ b/.emacs.d/lisp/python.el
@@ -2950,43 +2950,38 @@ This function takes the list of setup code to send from the
 ;;; Shell completion
 
 (defcustom python-shell-completion-setup-code
-  "try:
-    import __builtin__
-except ImportError:
-    # Python 3
-    import builtins as __builtin__
-try:
-    import readline, rlcompleter
-except:
-    def __PYTHON_EL_get_completions(text):
-        return []
-else:
-    def __PYTHON_EL_get_completions(text):
-        builtins = dir(__builtin__)
-        completions = []
-        try:
+  "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')
-            is_ipython = ('__IPYTHON__' in builtins or
-                          '__IPYTHON__active' in builtins)
             if is_module:
                 from IPython.core.completerlib import module_completion
                 completions = module_completion(text.strip())
-            elif is_ipython and '__IP' in builtins:
+            elif '__IP' in builtins:
                 completions = __IP.complete(text)
-            elif is_ipython and 'get_ipython' in builtins:
+            elif 'get_ipython' in builtins:
                 completions = get_ipython().Completer.all_completions(text)
-            else:
-                i = 0
-                while True:
-                    res = readline.get_completer()(text, i)
-                    if not res:
-                        break
-                    i += 1
-                    completions.append(res)
-        except:
-            pass
-        return completions"
+        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)
@@ -3053,18 +3048,20 @@ When a match is found, native completion is disabled."
       #'identity
       (list
        "try:"
-       "    import readline, rlcompleter"
-       ;; Remove parens on callables as it breaks completion on
-       ;; arguments (e.g. str(Ari<tab>)).
-       "    class Completer(rlcompleter.Completer):"
-       "        def _callable_postfix(self, val, word):"
-       "            return word"
-       "    readline.set_completer(Completer().complete)"
+       "    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")
@@ -3146,7 +3143,7 @@ completion."
                              python-shell-completion-native-redirect-buffer))
            (separators (python-rx
                         (or whitespace open-paren close-paren)))
-           (trigger "\t\t\t")
+           (trigger "\t")
            (new-input (concat input trigger))
            (input-length
             (save-excursion
@@ -3192,11 +3189,13 @@ completion."
               (while (accept-process-output
                       process
                       python-shell-completion-native-output-timeout))
-              (cl-remove-duplicates
+              (cl-remove
+               (concat input "__dummy_completion__")
                (split-string
                 (buffer-substring-no-properties
                  (point-min) (point-max))
-                separators t))))
+                separators t)
+               :test #'string=)))
         (set-process-filter process original-filter-fn)))))
 
 (defun python-shell-completion-get-completions (process import input)
-- 
2.2.1