##// END OF EJS Templates
Merge pull request #663 from takluyver/py3compat...
Merge pull request #663 from takluyver/py3compat Python 3 compatibility work. This doesn't fully get us to a single codebase supporting py2/3 at install time, but it does make significant progress in that direction.

File last commit:

r4746:76b84816
r4778:37dd091e merge
Show More
splitinput.py
138 lines | 4.8 KiB | text/x-python | PythonLexer
Brian Granger
More work on refactoring things into components....
r2244 # encoding: utf-8
"""
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 Simple utility for splitting user input. This is used by both inputsplitter and
prefilter.
Brian Granger
More work on refactoring things into components....
r2244
Authors:
* Brian Granger
* Fernando Perez
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2008-2009 The IPython Development Team
#
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
import re
Fernando Perez
Unicode fixes, basic input/printing of unicode works.
r3038 import sys
Brian Granger
More work on refactoring things into components....
r2244
Thomas Kluyver
Start using py3compat module.
r4731 from IPython.utils import py3compat
Brian Granger
More work on refactoring things into components....
r2244 #-----------------------------------------------------------------------------
# Main function
#-----------------------------------------------------------------------------
# RegExp for splitting line contents into pre-char//first word-method//rest.
# For clarity, each group in on one line.
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 # WARNING: update the regexp if the escapes in interactiveshell are changed, as
# they are hardwired in.
Brian Granger
More work on refactoring things into components....
r2244
# Although it's not solely driven by the regex, note that:
# ,;/% only trigger if they are the first character on the line
# ! and !! trigger if they are first char(s) *or* follow an indent
# ? triggers as first or last char.
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 line_split = re.compile("""
^(\s*) # any leading space
([,;/%]|!!?|\?\??)? # escape character or characters
\s*(%?[\w\.\*]*) # function/method, possibly with leading %
# to correctly treat things like '?%magic'
(.*?$|$) # rest of line
""", re.VERBOSE)
Brian Granger
More work on refactoring things into components....
r2244
def split_user_input(line, pattern=None):
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 """Split user input into initial whitespace, escape character, function part
and the rest.
Brian Granger
First go an implementing a=!ls and a=%who syntax....
r2256 """
Fernando Perez
Unicode fixes, basic input/printing of unicode works.
r3038 # We need to ensure that the rest of this routine deals only with unicode
Thomas Kluyver
Start using py3compat module.
r4731 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
Fernando Perez
Unicode fixes, basic input/printing of unicode works.
r3038
Brian Granger
More work on refactoring things into components....
r2244 if pattern is None:
pattern = line_split
match = pattern.match(line)
if not match:
Brian Granger
First go an implementing a=!ls and a=%who syntax....
r2256 # print "match failed for line '%s'" % line
Brian Granger
More work on refactoring things into components....
r2244 try:
ifun, the_rest = line.split(None,1)
except ValueError:
Brian Granger
First go an implementing a=!ls and a=%who syntax....
r2256 # print "split failed for line '%s'" % line
Fernando Perez
Unicode fixes, basic input/printing of unicode works.
r3038 ifun, the_rest = line, u''
Brian Granger
More work on refactoring things into components....
r2244 pre = re.match('^(\s*)(.*)',line).groups()[0]
Thomas Kluyver
Improvements in the code that breaks up user input.
r4744 esc = ""
Brian Granger
More work on refactoring things into components....
r2244 else:
Thomas Kluyver
Improvements in the code that breaks up user input.
r4744 pre, esc, ifun, the_rest = match.groups()
Brian Granger
More work on refactoring things into components....
r2244
#print 'line:<%s>' % line # dbg
#print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
Thomas Kluyver
Reuse common code for inputsplitter and prefilter.
r4746 return pre, esc or '', ifun.strip(), the_rest.lstrip()
class LineInfo(object):
"""A single line of input and associated info.
Includes the following as properties:
line
The original, raw line
continue_prompt
Is this line a continuation in a sequence of multiline input?
pre
Any leading whitespace.
esc
The escape character(s) in pre or the empty string if there isn't one.
Note that '!!' and '??' are possible values for esc. Otherwise it will
always be a single character.
ifun
The 'function part', which is basically the maximal initial sequence
of valid python identifiers and the '.' character. This is what is
checked for alias and magic transformations, used for auto-calling,
etc. In contrast to Python identifiers, it may start with "%" and contain
"*".
the_rest
Everything else on the line.
"""
def __init__(self, line, continue_prompt=False):
self.line = line
self.continue_prompt = continue_prompt
self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
self.pre_char = self.pre.strip()
if self.pre_char:
self.pre_whitespace = '' # No whitespace allowd before esc chars
else:
self.pre_whitespace = self.pre
self._oinfo = None
def ofind(self, ip):
"""Do a full, attribute-walking lookup of the ifun in the various
namespaces for the given IPython InteractiveShell instance.
Return a dict with keys: found,obj,ospace,ismagic
Note: can cause state changes because of calling getattr, but should
only be run if autocall is on and if the line hasn't matched any
other, less dangerous handlers.
Does cache the results of the call, so can be called multiple times
without worrying about *further* damaging state.
"""
if not self._oinfo:
# ip.shell._ofind is actually on the Magic class!
self._oinfo = ip.shell._ofind(self.ifun)
return self._oinfo
def __str__(self):
return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)