1 """ 2 Utilities for end-users. 3 """ 4 5 import __main__ 6 from collections import namedtuple 7 import logging 8 import traceback 9 import re 10 import os 11 import sys 12 13 from jedi import Interpreter 14 15 16 READLINE_DEBUG = False 17 18 19 def setup_readline(namespace_module=__main__, fuzzy=False): 20 """ 21 This function sets up :mod:`readline` to use Jedi in a Python interactive 22 shell. 23 24 If you want to use a custom ``PYTHONSTARTUP`` file (typically 25 ``$HOME/.pythonrc.py``), you can add this piece of code:: 26 27 try: 28 from jedi.utils import setup_readline 29 except ImportError: 30 # Fallback to the stdlib readline completer if it is installed. 31 # Taken from http://docs.python.org/2/library/rlcompleter.html 32 print("Jedi is not installed, falling back to readline") 33 try: 34 import readline 35 import rlcompleter 36 readline.parse_and_bind("tab: complete") 37 except ImportError: 38 print("Readline is not installed either. No tab completion is enabled.") 39 else: 40 setup_readline() 41 42 This will fallback to the readline completer if Jedi is not installed. 43 The readline completer will only complete names in the global namespace, 44 so for example:: 45 46 ran<TAB> 47 48 will complete to ``range``. 49 50 With Jedi the following code:: 51 52 range(10).cou<TAB> 53 54 will complete to ``range(10).count``, this does not work with the default 55 cPython :mod:`readline` completer. 56 57 You will also need to add ``export PYTHONSTARTUP=$HOME/.pythonrc.py`` to 58 your shell profile (usually ``.bash_profile`` or ``.profile`` if you use 59 bash). 60 """ 61 if READLINE_DEBUG: 62 logging.basicConfig( 63 filename='/tmp/jedi.log', 64 filemode='a', 65 level=logging.DEBUG 66 ) 67 68 class JediRL: 69 def complete(self, text, state): 70 """ 71 This complete stuff is pretty weird, a generator would make 72 a lot more sense, but probably due to backwards compatibility 73 this is still the way how it works. 74 75 The only important part is stuff in the ``state == 0`` flow, 76 everything else has been copied from the ``rlcompleter`` std. 77 library module. 78 """ 79 if state == 0: 80 sys.path.insert(0, os.getcwd()) 81 # Calling python doesn't have a path, so add to sys.path. 82 try: 83 logging.debug("Start REPL completion: " + repr(text)) 84 interpreter = Interpreter(text, [namespace_module.__dict__]) 85 86 completions = interpreter.complete(fuzzy=fuzzy) 87 logging.debug("REPL completions: %s", completions) 88 89 self.matches = [ 90 text[:len(text) - c._like_name_length] + c.name_with_symbols 91 for c in completions 92 ] 93 except: 94 logging.error("REPL Completion error:\n" + traceback.format_exc()) 95 raise 96 finally: 97 sys.path.pop(0) 98 try: 99 return self.matches[state] 100 except IndexError: 101 return None 102 103 try: 104 # Need to import this one as well to make sure it's executed before 105 # this code. This didn't use to be an issue until 3.3. Starting with 106 # 3.4 this is different, it always overwrites the completer if it's not 107 # already imported here. 108 import rlcompleter # noqa: F401 109 import readline 110 except ImportError: 111 print("Jedi: Module readline not available.") 112 else: 113 readline.set_completer(JediRL().complete) 114 readline.parse_and_bind("tab: complete") 115 # jedi itself does the case matching 116 readline.parse_and_bind("set completion-ignore-case on") 117 # because it's easier to hit the tab just once 118 readline.parse_and_bind("set show-all-if-unmodified") 119 readline.parse_and_bind("set show-all-if-ambiguous on") 120 # don't repeat all the things written in the readline all the time 121 readline.parse_and_bind("set completion-prefix-display-length 2") 122 # No delimiters, Jedi handles that. 123 readline.set_completer_delims('') 124 125 126 def version_info(): 127 """ 128 Returns a namedtuple of Jedi's version, similar to Python's 129 ``sys.version_info``. 130 """ 131 Version = namedtuple('Version', 'major, minor, micro') 132 from jedi import __version__ 133 tupl = re.findall(r'[a-z]+|\d+', __version__) 134 return Version(*[x if i == 3 else int(x) for i, x in enumerate(tupl)]) 135