dynamic arrays are now working pretty good

This commit is contained in:
David Halter
2012-08-09 16:03:28 +02:00
parent c6f76a15ff
commit ae60bce836
6 changed files with 70 additions and 25 deletions

View File

@@ -84,7 +84,7 @@ def search_params(param):
@evaluate.memoize_default([])
def check_array_additions(array, is_list=True):
def check_array_additions(array):
"""
Checks if a `parsing.Array` has "add" statements:
>>> a = [""]
@@ -115,19 +115,29 @@ def check_array_additions(array, is_list=True):
position = c.parent_stmt.start_pos
scope = c.parent_stmt.parent
print 'd', call_path
e = evaluate.follow_call_path(backtrack_path, scope, position)
print 'e', e
if not array in e:
# the `append`, etc. belong to other arrays
continue
params = call_path[separate_index + 1]
if not params.values:
continue # no params: just ignore it
if add_name in ['append', 'add']:
result += evaluate.follow_call_list(call_path[separate_index + 1])
result += evaluate.follow_call_list(params)
elif add_name in ['insert']:
try:
second_param = params[1]
except IndexError:
continue
else:
result += evaluate.follow_call_list([second_param])
elif add_name in ['extend', 'update']:
result += evaluate.follow_call_list(call_path[separate_index + 1])
# TODO needs extensive work, because this are iterables
result += evaluate.follow_call_list(params)
return result
is_list = array._array.type == 'list'
stmt = array._array.parent_stmt
current_module = stmt.get_parent_until()
search_names = ['append', 'extend', 'insert'] if is_list else \

View File

@@ -752,7 +752,10 @@ class Array(parsing.Base):
return self.get_exact_index_types(i)
except (IndexError, KeyError):
pass
return self.follow_values(self._array.values)
result = list(self.follow_values(self._array.values))
result += dynamic.check_array_additions(self)
return set(result)
def get_exact_index_types(self, index):
""" Here the index is an int. Raises IndexError/KeyError """
@@ -1244,9 +1247,7 @@ def follow_path(path, scope, position=None):
if isinstance(current, parsing.Array):
# This must be an execution, either () or [].
if current.type == parsing.Array.LIST:
result = list(scope.get_index_types(current))
if isinstance(scope, Array):
result += dynamic.check_array_additions(scope)
result = scope.get_index_types(current)
elif current.type not in [parsing.Array.DICT]:
# Scope must be a class or func - make an instance or execution.
debug.dbg('exe', scope)
@@ -1264,4 +1265,4 @@ def follow_path(path, scope, position=None):
# This is the typical lookup while chaining things.
result = imports.strip_imports(get_scopes_for_name(scope, current,
position=position))
return follow_paths(path, result, position=position)
return follow_paths(path, set(result), position=position)

View File

@@ -91,7 +91,7 @@ class ImportPath(object):
if len(rest) > 1 or rest and self.is_like_search:
scopes = []
elif rest:
scopes = evaluate.follow_path(iter(rest), scope)
scopes = list(evaluate.follow_path(iter(rest), scope))
else:
scopes = [scope]

View File

@@ -21,6 +21,7 @@ def iter(collection, sentinel=None):
for c in collection:
yield c
def range(start, stop=None, step=1):
return [0]
@@ -94,6 +95,7 @@ class list():
def pop(self):
return self.__iterable[-1]
class tuple():
def __init__(self, iterable=[]):
self.__iterable = []
@@ -107,6 +109,12 @@ class tuple():
def __getitem__(self, y):
return self.__iterable[y]
def index(self):
return 1
def count(self):
return 1
class set():
def __init__(self, iterable=[]):
@@ -137,12 +145,6 @@ class frozenset():
def copy(self):
return self
class tuple():
def index(self):
return 1
def count(self):
return 1
#--------------------------------------------------------
# basic types

View File

@@ -162,13 +162,6 @@ dic2 = {'asdf': 3, 'b': 'str'}
#? int()
dic2[index]
# -----------------
# chaining
# -----------------
#? int()
[tuple()].index()
# -----------------
# __getitem__
# -----------------

View File

@@ -95,6 +95,7 @@ for a in [1,2]:
arr.append(a);
arr.append # should not cause an exception
arr.append() # should not cause an exception
#? int()
arr[10]
@@ -110,10 +111,48 @@ arr[10].index()
arr = [""]
arr.insert(0, 1.0)
# on exception due to this, please!
arr.insert(0)
arr.insert()
#? float() str()
arr[10]
for a in arr:
#? float() str()
a
for a in list(arr):
#? float() str()
a
for a in set(arr):
#? float() str()
a
# -----------------
# set.append
# set.add
# -----------------
st = {1.0}
for a in [1,2]:
st.add(a);
st.add # should not cause an exception
st.add()
for s in st:
#? float() int()
s
# -----------------
# list.extend / set.update
# -----------------
arr = [1.0]
arr.extend([1,2,3])
arr.extend([])
arr.extend("") # should ignore
##? float() int()
arr[0]