mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-08 06:44:46 +08:00
tuple support
This commit is contained in:
67
evaluate.py
67
evaluate.py
@@ -44,7 +44,7 @@ def memoize(default=None):
|
|||||||
return memo[key]
|
return memo[key]
|
||||||
else:
|
else:
|
||||||
memo[key] = default
|
memo[key] = default
|
||||||
rv = function(*args)
|
rv = function(*args, **kwargs)
|
||||||
memo[key] = rv
|
memo[key] = rv
|
||||||
return rv
|
return rv
|
||||||
return wrapper
|
return wrapper
|
||||||
@@ -138,7 +138,7 @@ class Execution(Exec):
|
|||||||
result.append(param.get_name())
|
result.append(param.get_name())
|
||||||
else:
|
else:
|
||||||
new_param = copy.copy(param)
|
new_param = copy.copy(param)
|
||||||
calls = parsing.Array(parsing.Array.EMPTY,
|
calls = parsing.Array(parsing.Array.NOARRAY,
|
||||||
self.params.parent_stmt)
|
self.params.parent_stmt)
|
||||||
calls.values = [value]
|
calls.values = [value]
|
||||||
new_param._assignment_calls = calls
|
new_param._assignment_calls = calls
|
||||||
@@ -171,12 +171,17 @@ class Array(object):
|
|||||||
and iv[0][0].type == parsing.Call.NUMBER \
|
and iv[0][0].type == parsing.Call.NUMBER \
|
||||||
and self._array.type != parsing.Array.DICT:
|
and self._array.type != parsing.Array.DICT:
|
||||||
try:
|
try:
|
||||||
values = [self._array.values[int(iv[0][0].name)]]
|
values = [self._array[int(iv[0][0].name)]]
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
scope = self._array.parent_stmt.parent
|
scope = self._array.parent_stmt.parent
|
||||||
return follow_call_list(scope, values)
|
return follow_call_list(scope, values)
|
||||||
|
|
||||||
|
def get_exact_index_types(self, index):
|
||||||
|
values = [self._array[index]]
|
||||||
|
scope = self._array.parent_stmt.parent
|
||||||
|
return follow_call_list(scope, values)
|
||||||
|
|
||||||
def get_defined_names(self):
|
def get_defined_names(self):
|
||||||
""" This method generates all ArrayElements for one parsing.Array. """
|
""" This method generates all ArrayElements for one parsing.Array. """
|
||||||
# array.type is a string with the type, e.g. 'list'
|
# array.type is a string with the type, e.g. 'list'
|
||||||
@@ -185,7 +190,7 @@ class Array(object):
|
|||||||
return [ArrayElement(n) for n in names]
|
return [ArrayElement(n) for n in names]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s of %s>" % (self.__class__.__name__, self._array)
|
return "<p%s of %s>" % (self.__class__.__name__, self._array)
|
||||||
|
|
||||||
|
|
||||||
class ArrayElement(object):
|
class ArrayElement(object):
|
||||||
@@ -248,7 +253,7 @@ def get_scopes_for_name(scope, name, search_global=False):
|
|||||||
res_new = []
|
res_new = []
|
||||||
for r in result:
|
for r in result:
|
||||||
if isinstance(r, parsing.Statement):
|
if isinstance(r, parsing.Statement):
|
||||||
scopes = follow_statement(r)
|
scopes = follow_statement(r, seek_name=name)
|
||||||
res_new += remove_statements(scopes)
|
res_new += remove_statements(scopes)
|
||||||
else:
|
else:
|
||||||
res_new.append(r)
|
res_new.append(r)
|
||||||
@@ -312,9 +317,44 @@ def strip_imports(scopes):
|
|||||||
result.append(s)
|
result.append(s)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def assign_tuples(scope, tuples, results, seek_name):
|
||||||
|
"""
|
||||||
|
This is a normal assignment checker. In python functions and other things
|
||||||
|
can return tuples:
|
||||||
|
>>> a, b = 1, ""
|
||||||
|
>>> a, (b, c) = 1, ("", 1.0)
|
||||||
|
|
||||||
|
Here, if seek_name is "a", the number type will be returned.
|
||||||
|
The first part (before `=`) is the param tuples, the second one result.
|
||||||
|
"""
|
||||||
|
def eval_results(index):
|
||||||
|
types = []
|
||||||
|
for r in results:
|
||||||
|
types += r.get_exact_index_types(index)
|
||||||
|
return types
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for i, t in enumerate(tuples):
|
||||||
|
# used in an assignment, there is just one call and no other things,
|
||||||
|
# therefor we can just assume, that the first part is important.
|
||||||
|
t = t[0]
|
||||||
|
# check the left part, if it's still tuples in it or a Call
|
||||||
|
if isinstance(t, parsing.Array):
|
||||||
|
# these are "sub" tuples
|
||||||
|
print 'arr', t
|
||||||
|
result += assign_tuples(scope, t, eval_results(i), seek_name)
|
||||||
|
else:
|
||||||
|
if t.name.names[-1] == seek_name:
|
||||||
|
result += eval_results(i)
|
||||||
|
print 't', t, result
|
||||||
|
else:
|
||||||
|
print 'name not found'
|
||||||
|
#print follow_call_list(scope, result[i])
|
||||||
|
print seek_name, tuples, results
|
||||||
|
return result
|
||||||
|
|
||||||
@memoize(default=[])
|
@memoize(default=[])
|
||||||
def follow_statement(stmt, scope=None):
|
def follow_statement(stmt, scope=None, seek_name=None):
|
||||||
"""
|
"""
|
||||||
:param stmt: contains a statement
|
:param stmt: contains a statement
|
||||||
:param scope: contains a scope. If not given, takes the parent of stmt.
|
:param scope: contains a scope. If not given, takes the parent of stmt.
|
||||||
@@ -326,13 +366,18 @@ def follow_statement(stmt, scope=None):
|
|||||||
debug.dbg('calls', call_list, call_list)
|
debug.dbg('calls', call_list, call_list)
|
||||||
result = set(follow_call_list(scope, call_list))
|
result = set(follow_call_list(scope, call_list))
|
||||||
|
|
||||||
if stmt.assignment_details:
|
# assignment checking is only important if the statement defines multiple
|
||||||
|
# variables
|
||||||
|
if len(stmt.get_set_vars()) > 1 and seek_name and stmt.assignment_details:
|
||||||
|
print 'seek', seek_name
|
||||||
new_result = []
|
new_result = []
|
||||||
for op, set_vars in stmt.assignment_details:
|
for op, set_vars in stmt.assignment_details:
|
||||||
stmt.assignment_details[0]
|
print '\ntup'
|
||||||
#print '\n\nlala', op, set_vars.values, call_list.values
|
new_result += assign_tuples(scope, set_vars, result, seek_name)
|
||||||
#print stmt, scope
|
print new_result
|
||||||
#result = new_result
|
print '\n\nlala', op, set_vars.values, call_list.values
|
||||||
|
print stmt, scope
|
||||||
|
result = new_result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -147,4 +147,4 @@ c = b().c3(); abc = datetime; return [abc][0]. ;pylab.; add(1+2,2).; for fi in [
|
|||||||
1.0.fromhex(); import flask ; flsk = flask.Flask + flask.Request;
|
1.0.fromhex(); import flask ; flsk = flask.Flask + flask.Request;
|
||||||
abc = [1,2+3]; abc[0].
|
abc = [1,2+3]; abc[0].
|
||||||
import pylab; def add(a1,b1): nana = 1; return a1+b1
|
import pylab; def add(a1,b1): nana = 1; return a1+b1
|
||||||
flow_test.; a12, b12 = (1,""); a12.
|
flow_test.; a12, (b12, c12) = (1,("", "")); a12.
|
||||||
|
|||||||
18
parsing.py
18
parsing.py
@@ -555,7 +555,7 @@ class Statement(Simple):
|
|||||||
if self._assignment_calls:
|
if self._assignment_calls:
|
||||||
return self._assignment_calls
|
return self._assignment_calls
|
||||||
self._assignment_details = []
|
self._assignment_details = []
|
||||||
result = Array(Array.EMPTY, self)
|
result = Array(Array.NOARRAY, self)
|
||||||
top = result
|
top = result
|
||||||
level = 0
|
level = 0
|
||||||
is_chain = False
|
is_chain = False
|
||||||
@@ -578,15 +578,19 @@ class Statement(Simple):
|
|||||||
# TODO there may be multiple assignments: a = b = 1
|
# TODO there may be multiple assignments: a = b = 1
|
||||||
|
|
||||||
self._assignment_details.append((tok, top))
|
self._assignment_details.append((tok, top))
|
||||||
# initialize the first item
|
# All these calls wouldn't be important if nonlocal would
|
||||||
result = Array(Array.EMPTY, self)
|
# exist. -> Initialize the first item again.
|
||||||
|
result = Array(Array.NOARRAY, self)
|
||||||
top = result
|
top = result
|
||||||
|
level = 0
|
||||||
|
close_brackets = False
|
||||||
|
is_chain = False
|
||||||
continue
|
continue
|
||||||
elif tok == 'as':
|
elif tok == 'as':
|
||||||
next(tok_iter)
|
next(tok_iter)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
brackets = {'(': Array.EMPTY, '[': Array.LIST, '{': Array.SET}
|
brackets = {'(': Array.NOARRAY, '[': Array.LIST, '{': Array.SET}
|
||||||
is_call = lambda: result.__class__ == Call
|
is_call = lambda: result.__class__ == Call
|
||||||
is_call_or_close = lambda: is_call() or close_brackets
|
is_call_or_close = lambda: is_call() or close_brackets
|
||||||
|
|
||||||
@@ -638,7 +642,7 @@ class Statement(Simple):
|
|||||||
close_brackets = False
|
close_brackets = False
|
||||||
result.add_field()
|
result.add_field()
|
||||||
# important - it cannot be empty anymore
|
# important - it cannot be empty anymore
|
||||||
if result.type == Array.EMPTY:
|
if result.type == Array.NOARRAY:
|
||||||
result.type = Array.TUPLE
|
result.type = Array.TUPLE
|
||||||
elif tok in [')', '}', ']']:
|
elif tok in [')', '}', ']']:
|
||||||
while is_call_or_close():
|
while is_call_or_close():
|
||||||
@@ -755,7 +759,7 @@ class Array(Call):
|
|||||||
below.
|
below.
|
||||||
:type array_type: int
|
:type array_type: int
|
||||||
"""
|
"""
|
||||||
EMPTY = None
|
NOARRAY = None
|
||||||
TUPLE = 'tuple'
|
TUPLE = 'tuple'
|
||||||
LIST = 'list'
|
LIST = 'list'
|
||||||
DICT = 'dict'
|
DICT = 'dict'
|
||||||
@@ -808,7 +812,7 @@ class Array(Call):
|
|||||||
return self.values.__iter__()
|
return self.values.__iter__()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.type == self.EMPTY:
|
if self.type == self.NOARRAY:
|
||||||
temp = 'empty'
|
temp = 'empty'
|
||||||
elif self.type == self.TUPLE:
|
elif self.type == self.TUPLE:
|
||||||
temp = 'tuple'
|
temp = 'tuple'
|
||||||
|
|||||||
@@ -8,3 +8,10 @@ a = list()
|
|||||||
|
|
||||||
#? ['append']
|
#? ['append']
|
||||||
[[a]][0][100].append
|
[[a]][0][100].append
|
||||||
|
|
||||||
|
|
||||||
|
a1, b1 = (1, "")
|
||||||
|
#? ['real']
|
||||||
|
a1.real
|
||||||
|
#? ['lower']
|
||||||
|
b1.lower
|
||||||
|
|||||||
@@ -1,9 +1,3 @@
|
|||||||
a1, b1 = (1, "")
|
|
||||||
#? ['real']
|
|
||||||
a1.real
|
|
||||||
#? ['lower']
|
|
||||||
a1.lower
|
|
||||||
|
|
||||||
for a in [1,2]:
|
for a in [1,2]:
|
||||||
#? ['real']
|
#? ['real']
|
||||||
a.real
|
a.real
|
||||||
|
|||||||
Reference in New Issue
Block a user