splitinput.py 4.9 KB

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