Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
"""
# TODO allow for as's
tokens = line.split()
if not ("from" in tokens or "import" in tokens):
return None
matches = current_from_import_from_re.finditer(line)
for m in matches:
if (m.start(1) < cursor_offset and m.end(1) >= cursor_offset) or (
m.start(2) < cursor_offset and m.end(2) >= cursor_offset
):
return LinePart(m.start(1), m.end(1), m.group(1))
return None
current_from_import_import_re_1 = LazyReCompile(r"from\s([\w0-9_.]*)\s+import")
current_from_import_import_re_2 = LazyReCompile(r"([\w0-9_]+)")
current_from_import_import_re_3 = LazyReCompile(r"[,][ ]([\w0-9_]*)")
def current_from_import_import(cursor_offset, line):
"""If in from import completion, the word after import being completed
returns None if cursor not in or just after one of these words
"""
baseline = current_from_import_import_re_1.search(line)
if baseline is None:
return None
match1 = current_from_import_import_re_2.search(line[baseline.end() :])
if match1 is None:
return None
matches = current_from_import_import_re_3.finditer(line[baseline.end() :])
for m in chain((match1,), matches):
parts of an import: from (module) import (name1, name2)
"""
# TODO allow for as's
tokens = line.split()
if not ("from" in tokens or "import" in tokens):
return None
matches = current_from_import_from_re.finditer(line)
for m in matches:
if (m.start(1) < cursor_offset and m.end(1) >= cursor_offset) or (
m.start(2) < cursor_offset and m.end(2) >= cursor_offset
):
return LinePart(m.start(1), m.end(1), m.group(1))
return None
current_from_import_import_re_1 = LazyReCompile(r"from\s([\w0-9_.]*)\s+import")
current_from_import_import_re_2 = LazyReCompile(r"([\w0-9_]+)")
current_from_import_import_re_3 = LazyReCompile(r"[,][ ]([\w0-9_]*)")
def current_from_import_import(cursor_offset, line):
"""If in from import completion, the word after import being completed
returns None if cursor not in or just after one of these words
"""
baseline = current_from_import_import_re_1.search(line)
if baseline is None:
return None
match1 = current_from_import_import_re_2.search(line[baseline.end() :])
if match1 is None:
return None
matches = current_from_import_import_re_3.finditer(line[baseline.end() :])
# TODO allow for as's
tokens = line.split()
if not ("from" in tokens or "import" in tokens):
return None
matches = current_from_import_from_re.finditer(line)
for m in matches:
if (m.start(1) < cursor_offset and m.end(1) >= cursor_offset) or (
m.start(2) < cursor_offset and m.end(2) >= cursor_offset
):
return LinePart(m.start(1), m.end(1), m.group(1))
return None
current_from_import_import_re_1 = LazyReCompile(r"from\s([\w0-9_.]*)\s+import")
current_from_import_import_re_2 = LazyReCompile(r"([\w0-9_]+)")
current_from_import_import_re_3 = LazyReCompile(r"[,][ ]([\w0-9_]*)")
def current_from_import_import(cursor_offset, line):
"""If in from import completion, the word after import being completed
returns None if cursor not in or just after one of these words
"""
baseline = current_from_import_import_re_1.search(line)
if baseline is None:
return None
match1 = current_from_import_import_re_2.search(line[baseline.end() :])
if match1 is None:
return None
matches = current_from_import_import_re_3.finditer(line[baseline.end() :])
for m in chain((match1,), matches):
start = baseline.end() + m.start(1)
# encoding: utf-8
"""Tools for preparing code to be run in the REPL (removing blank lines,
etc)"""
from bpython.lazyre import LazyReCompile
# TODO specifically catch IndentationErrors instead of any syntax errors
indent_empty_lines_re = LazyReCompile(r"\s*")
tabs_to_spaces_re = LazyReCompile(r"^\t+")
def indent_empty_lines(s, compiler):
"""Indents blank lines that would otherwise cause early compilation
Only really works if starting on a new line"""
lines = s.split("\n")
ends_with_newline = False
if lines and not lines[-1]:
ends_with_newline = True
lines.pop()
result_lines = []
for p_line, line, n_line in zip([""] + lines[:-1], lines, lines[1:] + [""]):
if len(line) == 0:
p_indent = indent_empty_lines_re.match(p_line).group()
self.last_command = self.time() - self.start
self.running_time += self.last_command
return False
def reset_timer(self):
self.running_time = 0.0
self.last_command = 0.0
def estimate(self):
return self.running_time - self.last_command
class Interpreter(code.InteractiveInterpreter, object):
"""Source code interpreter for use in bpython."""
bpython_input_re = LazyReCompile(r"")
def __init__(self, locals=None, encoding=None):
"""Constructor.
The optional 'locals' argument specifies the dictionary in which code
will be executed; it defaults to a newly created dictionary with key
"__name__" set to "__main__".
The syntaxerror callback can be set at any time and will be called
on a caught syntax error. The purpose for this in bpython is so that
the repl can be instantiated after the interpreter (which it
necessarily must be with the current factoring) and then an exception
callback can be added to the Interpreter instance afterwards - more
specifically, this is so that autoindentation does not occur after a
traceback.
if not annotations:
annotations = None
return [
args,
varargs,
varkwargs,
defaults,
kwonly,
kwonly_defaults,
annotations,
]
get_encoding_line_re = LazyReCompile(r"^.*coding[:=]\s*([-\w.]+).*$")
def get_encoding(obj):
"""Try to obtain encoding information of the source of an object."""
for line in inspect.findsource(obj)[0][:2]:
m = get_encoding_line_re.search(line)
if m:
return m.group(1)
return "ascii"
def get_encoding_comment(source):
"""Returns encoding line without the newline, or None is not found"""
for line in source.splitlines()[:2]:
m = get_encoding_line_re.search(line)
if m:
# front_white = len(line[:cursor_offset]) - \
# len(line[:cursor_offset].lstrip())
to_delete = ((cursor_offset - 1) % INDENT) + 1
return (
cursor_offset - to_delete,
line[: cursor_offset - to_delete] + line[cursor_offset:],
)
return (cursor_offset - 1, line[: cursor_offset - 1] + line[cursor_offset:])
@edit_keys.on(config="clear_line_key")
def delete_from_cursor_back(cursor_offset, line):
return 0, line[cursor_offset:]
delete_rest_of_word_re = LazyReCompile(r"\w\b")
@edit_keys.on("") # option-d
@kills_ahead
def delete_rest_of_word(cursor_offset, line):
m = delete_rest_of_word_re.search(line[cursor_offset:])
if not m:
return cursor_offset, line, ""
return (
cursor_offset,
line[:cursor_offset] + line[m.start() + cursor_offset + 1 :],
line[cursor_offset : m.start() + cursor_offset + 1],
)
delete_word_to_cursor_re = LazyReCompile(r"\s\S")
if baseline is None:
return None
match1 = current_from_import_import_re_2.search(line[baseline.end() :])
if match1 is None:
return None
matches = current_from_import_import_re_3.finditer(line[baseline.end() :])
for m in chain((match1,), matches):
start = baseline.end() + m.start(1)
end = baseline.end() + m.end(1)
if start < cursor_offset and end >= cursor_offset:
return LinePart(start, end, m.group(1))
return None
current_import_re_1 = LazyReCompile(r"import")
current_import_re_2 = LazyReCompile(r"([\w0-9_.]+)")
current_import_re_3 = LazyReCompile(r"[,][ ]([\w0-9_.]*)")
def current_import(cursor_offset, line):
# TODO allow for multiple as's
baseline = current_import_re_1.search(line)
if baseline is None:
return None
match1 = current_import_re_2.search(line[baseline.end() :])
if match1 is None:
return None
matches = current_import_re_3.finditer(line[baseline.end() :])
for m in chain((match1,), matches):
start = baseline.end() + m.start(1)
end = baseline.end() + m.end(1)
if start < cursor_offset and end >= cursor_offset:
src = inspect.getsourcelines(f)
except (IOError, IndexError):
# IndexError is raised in inspect.findsource(), can happen in
# some situations. See issue #94.
return
signature = "".join(src[0])
kwparsed = parsekeywordpairs(signature)
for i, (key, value) in enumerate(zip(keys, values)):
if len(repr(value)) != len(kwparsed[key]):
values[i] = _Repr(kwparsed[key])
argspec[3] = values
getpydocspec_re = LazyReCompile(r"([a-zA-Z_][a-zA-Z0-9_]*?)\((.*?)\)")
def getpydocspec(f, func):
try:
argspec = pydoc.getdoc(f)
except NameError:
return None
s = getpydocspec_re.search(argspec)
if s is None:
return None
if not hasattr(f, "__name__") or s.groups()[0] != f.__name__:
return None
args = list()
if m.start(1) <= cursor_offset and m.end(1) >= cursor_offset:
return LinePart(m.start(1), m.end(1), m.group(1))
return None
def current_dotted_attribute(cursor_offset, line):
"""The dotted attribute-object pair before the cursor"""
match = current_word(cursor_offset, line)
if match is None:
return None
start, end, word = match
if "." in word[1:]:
return LinePart(start, end, word)
current_expression_attribute_re = LazyReCompile(
r"[.]\s*((?:[\w_][\w0-9_]*)|(?:))"
)
def current_expression_attribute(cursor_offset, line):
"""If after a dot, the attribute being completed"""
# TODO replace with more general current_expression_attribute
matches = current_expression_attribute_re.finditer(line)
for m in matches:
if m.start(1) <= cursor_offset and m.end(1) >= cursor_offset:
return LinePart(m.start(1), m.end(1), m.group(1))
return None