mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
Merge branch 'dev'
This commit is contained in:
28
jedi/api.py
28
jedi/api.py
@@ -70,9 +70,9 @@ class Script(object):
|
|||||||
api_classes._clear_caches()
|
api_classes._clear_caches()
|
||||||
debug.reset_time()
|
debug.reset_time()
|
||||||
self.source = modules.source_to_unicode(source, source_encoding)
|
self.source = modules.source_to_unicode(source, source_encoding)
|
||||||
self.pos = self._line, self._column
|
self._pos = self._line, self._column
|
||||||
self._module = modules.ModuleWithCursor(
|
self._module = modules.ModuleWithCursor(
|
||||||
path, source=self.source, position=self.pos)
|
path, source=self.source, position=self._pos)
|
||||||
self._source_path = path
|
self._source_path = path
|
||||||
self.path = None if path is None else os.path.abspath(path)
|
self.path = None if path is None else os.path.abspath(path)
|
||||||
debug.speed('init')
|
debug.speed('init')
|
||||||
@@ -165,7 +165,7 @@ class Script(object):
|
|||||||
except NotFoundError:
|
except NotFoundError:
|
||||||
scopes = []
|
scopes = []
|
||||||
scope_generator = evaluate.get_names_of_scope(
|
scope_generator = evaluate.get_names_of_scope(
|
||||||
self._parser.user_scope, self.pos)
|
self._parser.user_scope, self._pos)
|
||||||
completions = []
|
completions = []
|
||||||
for scope, name_list in scope_generator:
|
for scope, name_list in scope_generator:
|
||||||
for c in name_list:
|
for c in name_list:
|
||||||
@@ -184,7 +184,7 @@ class Script(object):
|
|||||||
if not current_line.endswith('import import'):
|
if not current_line.endswith('import import'):
|
||||||
continue
|
continue
|
||||||
a = s.import_stmt.alias
|
a = s.import_stmt.alias
|
||||||
if a and a.start_pos <= self.pos <= a.end_pos:
|
if a and a.start_pos <= self._pos <= a.end_pos:
|
||||||
continue
|
continue
|
||||||
names = s.get_defined_names(on_import_stmt=True)
|
names = s.get_defined_names(on_import_stmt=True)
|
||||||
else:
|
else:
|
||||||
@@ -230,7 +230,7 @@ class Script(object):
|
|||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
def _get_under_cursor_stmt(self, cursor_txt):
|
def _get_under_cursor_stmt(self, cursor_txt):
|
||||||
offset = self.pos[0] - 1, self.pos[1]
|
offset = self._line - 1, self._column
|
||||||
r = parsing.Parser(cursor_txt, no_docstr=True, offset=offset)
|
r = parsing.Parser(cursor_txt, no_docstr=True, offset=offset)
|
||||||
try:
|
try:
|
||||||
stmt = r.module.statements[0]
|
stmt = r.module.statements[0]
|
||||||
@@ -333,7 +333,7 @@ class Script(object):
|
|||||||
elif not goto_path:
|
elif not goto_path:
|
||||||
op = self._module.get_operator_under_cursor()
|
op = self._module.get_operator_under_cursor()
|
||||||
if op and op not in lower_priority_operators:
|
if op and op not in lower_priority_operators:
|
||||||
scopes = set([keywords.get_operator(op, self.pos)])
|
scopes = set([keywords.get_operator(op, self._pos)])
|
||||||
|
|
||||||
# Fetch definition of callee
|
# Fetch definition of callee
|
||||||
if not goto_path:
|
if not goto_path:
|
||||||
@@ -343,11 +343,11 @@ class Script(object):
|
|||||||
call = call.next
|
call = call.next
|
||||||
# reset cursor position:
|
# reset cursor position:
|
||||||
(row, col) = call.name.end_pos
|
(row, col) = call.name.end_pos
|
||||||
self.pos = (row, max(col - 1, 0))
|
_pos = (row, max(col - 1, 0))
|
||||||
self._module = modules.ModuleWithCursor(
|
self._module = modules.ModuleWithCursor(
|
||||||
self._source_path,
|
self._source_path,
|
||||||
source=self.source,
|
source=self.source,
|
||||||
position=self.pos)
|
position=_pos)
|
||||||
# then try to find the path again
|
# then try to find the path again
|
||||||
goto_path = self._module.get_path_under_cursor()
|
goto_path = self._module.get_path_under_cursor()
|
||||||
|
|
||||||
@@ -355,12 +355,12 @@ class Script(object):
|
|||||||
if goto_path:
|
if goto_path:
|
||||||
scopes = set(self._prepare_goto(goto_path))
|
scopes = set(self._prepare_goto(goto_path))
|
||||||
elif op in lower_priority_operators:
|
elif op in lower_priority_operators:
|
||||||
scopes = set([keywords.get_operator(op, self.pos)])
|
scopes = set([keywords.get_operator(op, self._pos)])
|
||||||
|
|
||||||
scopes = resolve_import_paths(scopes)
|
scopes = resolve_import_paths(scopes)
|
||||||
|
|
||||||
# add keywords
|
# add keywords
|
||||||
scopes |= keywords.keywords(string=goto_path, pos=self.pos)
|
scopes |= keywords.keywords(string=goto_path, pos=self._pos)
|
||||||
|
|
||||||
d = set([api_classes.Definition(s) for s in scopes
|
d = set([api_classes.Definition(s) for s in scopes
|
||||||
if not isinstance(s, imports.ImportPath._GlobalNamespace)])
|
if not isinstance(s, imports.ImportPath._GlobalNamespace)])
|
||||||
@@ -429,7 +429,7 @@ class Script(object):
|
|||||||
if isinstance(user_stmt, pr.Statement):
|
if isinstance(user_stmt, pr.Statement):
|
||||||
c = user_stmt.get_commands()
|
c = user_stmt.get_commands()
|
||||||
if c and not isinstance(c[0], (str, unicode)) and \
|
if c and not isinstance(c[0], (str, unicode)) and \
|
||||||
c[0].start_pos > self.pos:
|
c[0].start_pos > self._pos:
|
||||||
# The cursor must be after the start, otherwise the
|
# The cursor must be after the start, otherwise the
|
||||||
# statement is just an assignee.
|
# statement is just an assignee.
|
||||||
definitions = [user_stmt]
|
definitions = [user_stmt]
|
||||||
@@ -453,7 +453,7 @@ class Script(object):
|
|||||||
definitions, search_name = self._goto(add_import_name=True)
|
definitions, search_name = self._goto(add_import_name=True)
|
||||||
if isinstance(user_stmt, pr.Statement):
|
if isinstance(user_stmt, pr.Statement):
|
||||||
c = user_stmt.get_commands()[0]
|
c = user_stmt.get_commands()[0]
|
||||||
if not isinstance(c, unicode) and self.pos < c.start_pos:
|
if not isinstance(c, unicode) and self._pos < c.start_pos:
|
||||||
# the search_name might be before `=`
|
# the search_name might be before `=`
|
||||||
definitions = [v for v in user_stmt.set_vars
|
definitions = [v for v in user_stmt.set_vars
|
||||||
if unicode(v.names[-1]) == search_name]
|
if unicode(v.names[-1]) == search_name]
|
||||||
@@ -517,7 +517,7 @@ class Script(object):
|
|||||||
user_stmt = self._user_stmt()
|
user_stmt = self._user_stmt()
|
||||||
if user_stmt is not None and isinstance(user_stmt, pr.Statement):
|
if user_stmt is not None and isinstance(user_stmt, pr.Statement):
|
||||||
call, index, _ = helpers.search_function_definition(
|
call, index, _ = helpers.search_function_definition(
|
||||||
user_stmt, self.pos)
|
user_stmt, self._pos)
|
||||||
debug.speed('func_call parsed')
|
debug.speed('func_call parsed')
|
||||||
return call, index
|
return call, index
|
||||||
|
|
||||||
@@ -531,7 +531,7 @@ class Script(object):
|
|||||||
if user_stmt.alias == i:
|
if user_stmt.alias == i:
|
||||||
continue
|
continue
|
||||||
for name_part in i.names:
|
for name_part in i.names:
|
||||||
if name_part.end_pos >= self.pos:
|
if name_part.end_pos >= self._pos:
|
||||||
if not cur_name_part:
|
if not cur_name_part:
|
||||||
cur_name_part = name_part
|
cur_name_part = name_part
|
||||||
kill_count += 1
|
kill_count += 1
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ class Scope(Simple, IsScope):
|
|||||||
:return: True if there are no subscopes, imports and statements.
|
:return: True if there are no subscopes, imports and statements.
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
return not (self.imports or self.subscopes or self.statements)
|
return not (self.imports or self.subscopes or self.statements or self.returns)
|
||||||
|
|
||||||
@Python3Method
|
@Python3Method
|
||||||
def get_statement_for_position(self, pos, include_imports=False):
|
def get_statement_for_position(self, pos, include_imports=False):
|
||||||
@@ -423,6 +423,8 @@ class Class(Scope):
|
|||||||
string += ':\n'
|
string += ':\n'
|
||||||
string += super(Class, self).get_code(True, indention)
|
string += super(Class, self).get_code(True, indention)
|
||||||
if self.is_empty():
|
if self.is_empty():
|
||||||
|
if self.docstr:
|
||||||
|
string += indention
|
||||||
string += "pass\n"
|
string += "pass\n"
|
||||||
return string
|
return string
|
||||||
|
|
||||||
@@ -472,12 +474,11 @@ class Function(Scope):
|
|||||||
string += "def %s(%s):\n" % (self.name, params)
|
string += "def %s(%s):\n" % (self.name, params)
|
||||||
string += super(Function, self).get_code(True, indention)
|
string += super(Function, self).get_code(True, indention)
|
||||||
if self.is_empty():
|
if self.is_empty():
|
||||||
|
if self.docstr:
|
||||||
|
string += indention
|
||||||
string += 'pass\n'
|
string += 'pass\n'
|
||||||
return string
|
return string
|
||||||
|
|
||||||
def is_empty(self):
|
|
||||||
return super(Function, self).is_empty() and not self.returns
|
|
||||||
|
|
||||||
def get_set_vars(self):
|
def get_set_vars(self):
|
||||||
n = super(Function, self).get_set_vars()
|
n = super(Function, self).get_set_vars()
|
||||||
for p in self.params:
|
for p in self.params:
|
||||||
@@ -835,13 +836,6 @@ class Statement(Simple):
|
|||||||
# first keyword of the first token is global -> must be a global
|
# first keyword of the first token is global -> must be a global
|
||||||
return str(self.token_list[0]) == "global"
|
return str(self.token_list[0]) == "global"
|
||||||
|
|
||||||
def get_command(self, index):
|
|
||||||
commands = self.get_commands()
|
|
||||||
try:
|
|
||||||
return commands[index]
|
|
||||||
except IndexError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def assignment_details(self):
|
def assignment_details(self):
|
||||||
# parse statement which creates the assignment details.
|
# parse statement which creates the assignment details.
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ def extract(script, new_name):
|
|||||||
# TODO care for multiline extracts
|
# TODO care for multiline extracts
|
||||||
dct = {}
|
dct = {}
|
||||||
if user_stmt:
|
if user_stmt:
|
||||||
pos = script.pos
|
pos = script._pos
|
||||||
line_index = pos[0] - 1
|
line_index = pos[0] - 1
|
||||||
arr, index = helpers.array_for_pos(user_stmt, pos)
|
arr, index = helpers.array_for_pos(user_stmt, pos)
|
||||||
if arr is not None:
|
if arr is not None:
|
||||||
|
|||||||
9
test/test_debug.py
Normal file
9
test/test_debug.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import jedi
|
||||||
|
from jedi import debug
|
||||||
|
|
||||||
|
def test_simple():
|
||||||
|
jedi.set_debug_function()
|
||||||
|
debug.speed('foo')
|
||||||
|
debug.dbg('bar')
|
||||||
|
debug.warning('baz')
|
||||||
|
jedi.set_debug_function(None, False, False, False)
|
||||||
29
test/test_parsing_representation.py
Normal file
29
test/test_parsing_representation.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
from jedi.parsing import Parser
|
||||||
|
|
||||||
|
def test_get_code():
|
||||||
|
"""Use the same code that the parser also generates, to compare"""
|
||||||
|
s = \
|
||||||
|
'''"""a docstring"""
|
||||||
|
class SomeClass(object, mixin):
|
||||||
|
def __init__(self):
|
||||||
|
self.xy = 3.0
|
||||||
|
'statement docstr'
|
||||||
|
def some_method(self):
|
||||||
|
return 1
|
||||||
|
def yield_method(self):
|
||||||
|
while hasattr(self, 'xy'):
|
||||||
|
yield True
|
||||||
|
for x in [1, 2]:
|
||||||
|
yield x
|
||||||
|
def empty(self):
|
||||||
|
pass
|
||||||
|
class Empty:
|
||||||
|
pass
|
||||||
|
class WithDocstring:
|
||||||
|
"""class docstr"""
|
||||||
|
pass
|
||||||
|
def method_with_docstring():
|
||||||
|
"""class docstr"""
|
||||||
|
pass
|
||||||
|
'''
|
||||||
|
assert Parser(s).module.get_code() == s
|
||||||
Reference in New Issue
Block a user