Format: text/x-python
⬇ Download File (4.9 KB)
   1  # encoding: utf-8
   2  """
   3  Simple utility for splitting user input. This is used by both inputsplitter and
   4  prefilter.
   5  
   6  Authors:
   7  
   8  * Brian Granger
   9  * Fernando Perez
  10  """
  11  
  12  #-----------------------------------------------------------------------------
  13  #  Copyright (C) 2008-2011  The IPython Development Team
  14  #
  15  #  Distributed under the terms of the BSD License.  The full license is in
  16  #  the file COPYING, distributed as part of this software.
  17  #-----------------------------------------------------------------------------
  18  
  19  #-----------------------------------------------------------------------------
  20  # Imports
  21  #-----------------------------------------------------------------------------
  22  
  23  import re
  24  import sys
  25  
  26  from IPython.utils import py3compat
  27  from IPython.utils.encoding import get_stream_enc
  28  from IPython.core.oinspect import OInfo
  29  
  30  #-----------------------------------------------------------------------------
  31  # Main function
  32  #-----------------------------------------------------------------------------
  33  
  34  # RegExp for splitting line contents into pre-char//first word-method//rest.
  35  # For clarity, each group in on one line.
  36  
  37  # WARNING: update the regexp if the escapes in interactiveshell are changed, as
  38  # they are hardwired in.
  39  
  40  # Although it's not solely driven by the regex, note that:
  41  # ,;/% only trigger if they are the first character on the line
  42  # ! and !! trigger if they are first char(s) *or* follow an indent
  43  # ? triggers as first or last char.
  44  
  45  line_split = re.compile(r"""
  46               ^(\s*)               # any leading space
  47               ([,;/%]|!!?|\?\??)?  # escape character or characters
  48               \s*(%{0,2}[\w\.\*]*)     # function/method, possibly with leading %
  49                                    # to correctly treat things like '?%magic'
  50               (.*?$|$)             # rest of line
  51               """, re.VERBOSE)
  52  
  53  
  54  def split_user_input(line, pattern=None):
  55      """Split user input into initial whitespace, escape character, function part
  56      and the rest.
  57      """
  58      # We need to ensure that the rest of this routine deals only with unicode
  59      encoding = get_stream_enc(sys.stdin, 'utf-8')
  60      line = py3compat.cast_unicode(line, encoding)
  61  
  62      if pattern is None:
  63          pattern = line_split
  64      match = pattern.match(line)
  65      if not match:
  66          # print("match failed for line '%s'" % line)
  67          try:
  68              ifun, the_rest = line.split(None,1)
  69          except ValueError:
  70              # print("split failed for line '%s'" % line)
  71              ifun, the_rest = line, u''
  72          pre = re.match(r'^(\s*)(.*)',line).groups()[0]
  73          esc = ""
  74      else:
  75          pre, esc, ifun, the_rest = match.groups()
  76  
  77      # print('line:<%s>' % line)  # dbg
  78      # print('pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest))  # dbg
  79      return pre, esc or "", ifun.strip(), the_rest
  80  
  81  
  82  class LineInfo(object):
  83      """A single line of input and associated info.
  84  
  85      Includes the following as properties:
  86  
  87      line
  88        The original, raw line
  89  
  90      continue_prompt
  91        Is this line a continuation in a sequence of multiline input?
  92  
  93      pre
  94        Any leading whitespace.
  95  
  96      esc
  97        The escape character(s) in pre or the empty string if there isn't one.
  98        Note that '!!' and '??' are possible values for esc. Otherwise it will
  99        always be a single character.
 100  
 101      ifun
 102        The 'function part', which is basically the maximal initial sequence
 103        of valid python identifiers and the '.' character. This is what is
 104        checked for alias and magic transformations, used for auto-calling,
 105        etc. In contrast to Python identifiers, it may start with "%" and contain
 106        "*".
 107  
 108      the_rest
 109        Everything else on the line.
 110  
 111      raw_the_rest
 112        the_rest without whitespace stripped.
 113      """
 114      def __init__(self, line, continue_prompt=False):
 115          self.line            = line
 116          self.continue_prompt = continue_prompt
 117          self.pre, self.esc, self.ifun, self.raw_the_rest = split_user_input(line)
 118          self.the_rest = self.raw_the_rest.lstrip()
 119  
 120          self.pre_char       = self.pre.strip()
 121          if self.pre_char:
 122              self.pre_whitespace = '' # No whitespace allowed before esc chars
 123          else:
 124              self.pre_whitespace = self.pre
 125  
 126      def ofind(self, ip) -> OInfo:
 127          """Do a full, attribute-walking lookup of the ifun in the various
 128          namespaces for the given IPython InteractiveShell instance.
 129  
 130          Return a dict with keys: {found, obj, ospace, ismagic}
 131  
 132          Note: can cause state changes because of calling getattr, but should
 133          only be run if autocall is on and if the line hasn't matched any
 134          other, less dangerous handlers.
 135  
 136          Does cache the results of the call, so can be called multiple times
 137          without worrying about *further* damaging state.
 138          """
 139          return ip._ofind(self.ifun)
 140  
 141      def __str__(self):
 142          return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
 143  
 144      def __repr__(self):
 145          return "<" + str(self) + ">"
 146