Spaces:
Runtime error
Runtime error
| """ | |
| Simple utility for splitting user input. This is used by both inputsplitter and | |
| prefilter. | |
| """ | |
| # ----------------------------------------------------------------------------- | |
| # Imports | |
| # ----------------------------------------------------------------------------- | |
| import re | |
| import sys | |
| import warnings | |
| from IPython.core.oinspect import OInfo | |
| # ----------------------------------------------------------------------------- | |
| # Main function | |
| # ----------------------------------------------------------------------------- | |
| # RegExp for splitting line contents into pre-char//first word-method//rest. | |
| # For clarity, each group in on one line. | |
| # WARNING: update the regexp if the escapes in interactiveshell are changed, as | |
| # they are hardwired in. | |
| # 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. | |
| line_split = re.compile( | |
| r""" | |
| ^(\s*) # any leading space | |
| ([,;/%]|!!?|\?\??)? # escape character or characters | |
| \s*(%{0,2}[\w\.\*]*) # function/method, possibly with leading % | |
| # to correctly treat things like '?%magic' | |
| (.*?$|$) # rest of line | |
| """, | |
| re.VERBOSE, | |
| ) | |
| def split_user_input( | |
| line: str, pattern: re.Pattern[str] | None = None | |
| ) -> tuple[str, str, str, str]: | |
| """Split user input into initial whitespace, escape character, function part | |
| and the rest. | |
| """ | |
| assert isinstance(line, str) | |
| if pattern is None: | |
| pattern = line_split | |
| match = pattern.match(line) | |
| if not match: | |
| # print("match failed for line '%s'" % line) | |
| try: | |
| ifun, the_rest = line.split(None, 1) | |
| except ValueError: | |
| # print("split failed for line '%s'" % line) | |
| ifun, the_rest = line, "" | |
| pre = re.match(r"^(\s*)(.*)", line).groups()[0] | |
| esc = "" | |
| else: | |
| pre, esc, ifun, the_rest = match.groups() | |
| # print('line:<%s>' % line) # dbg | |
| # print('pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest)) # dbg | |
| return pre, esc or "", ifun.strip(), the_rest | |
| class LineInfo: | |
| """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. | |
| raw_the_rest | |
| the_rest without whitespace stripped. | |
| """ | |
| line: str | |
| continue_prompt: bool | |
| pre: str | |
| esc: str | |
| ifun: str | |
| raw_the_rest: str | |
| the_rest: str | |
| pre_char: str | |
| pre_whitespace: str | |
| def __init__(self, line: str, continue_prompt: bool = False) -> None: | |
| assert isinstance(line, str) | |
| self.line = line | |
| self.continue_prompt = continue_prompt | |
| self.pre, self.esc, self.ifun, self.raw_the_rest = split_user_input(line) | |
| self.the_rest = self.raw_the_rest.lstrip() | |
| self.pre_char = self.pre.strip() | |
| if self.pre_char: | |
| self.pre_whitespace = "" # No whitespace allowed before esc chars | |
| else: | |
| self.pre_whitespace = self.pre | |
| def ofind(self, ip) -> OInfo: | |
| """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. | |
| .. deprecated:: 9.8 | |
| Use ``shell._ofind(line_info.ifun)`` directly instead. | |
| """ | |
| warnings.warn( | |
| "LineInfo.ofind() is deprecated since IPython 9.9. " | |
| "Use shell._ofind(line_info.ifun) directly instead.", | |
| DeprecationWarning, | |
| stacklevel=2, | |
| ) | |
| return ip._ofind(self.ifun) | |
| def __str__(self) -> str: | |
| return "LineInfo [%s|%s|%s|%s]" % (self.pre, self.esc, self.ifun, self.the_rest) | |
| def __repr__(self) -> str: | |
| return "<" + str(self) + ">" | |