From ffb233eac17bb79664328d648930e1b24ff8451c Mon Sep 17 00:00:00 2001 From: David Halter Date: Fri, 25 May 2012 13:58:52 +0200 Subject: [PATCH] self redirection solved --- evaluate.py | 38 ++++++++++++++++++++++++++++-------- functions.py | 6 ++++-- parsetest.py | 36 +++++++++++++++++----------------- test/completion/classes.py | 1 + test/completion/functions.py | 4 +--- test/run.py | 3 ++- 6 files changed, 56 insertions(+), 32 deletions(-) diff --git a/evaluate.py b/evaluate.py index fadc7941..a9d63736 100644 --- a/evaluate.py +++ b/evaluate.py @@ -126,6 +126,7 @@ class Instance(Executable): if n.names[0] == self_name and len(n.names) == 2: add_self_name(n) + #print names, [n.parent for n in names], [n.parent.parent for n in names] for var in self.base.get_defined_names(as_instance=True): # functions are also instance elements if isinstance(var.parent, (parsing.Function)): @@ -161,6 +162,10 @@ class InstanceElement(object): def parent(self): return InstanceElement(self.instance, self.var.parent) + def get_parent_until(self, *classes): + scope = self.var.get_parent_until(*classes) + return InstanceElement(self.instance, scope) + def __getattr__(self, name): return getattr(self.var, name) @@ -504,6 +509,8 @@ class Execution(Executable): return objects def __getattr__(self, name): + if name not in ['indent', 'line_nr', 'imports']: + raise AttributeError('Tried to access %s. Why?' % name) return getattr(self.base, name) @property @@ -628,6 +635,18 @@ class Array(object): def get_contents(self): return self._array + @property + def parent(self): + """ + Return the builtin scope as parent, because the arrays are builtins + """ + return builtin.Builtin.scope + + def __getattr__(self, name): + if name not in ['type']: + raise AttributeError('Strange access: %s.' % name) + return getattr(self._array, name) + def __repr__(self): return "" % (self.__class__.__name__, self._array) @@ -639,10 +658,9 @@ class ArrayElement(object): def __getattr__(self, name): # set access rights: - if name in ['parent', 'names', 'line_nr', 'indent']: - return getattr(self.name, name) - else: - raise NotImplementedError("Strange access, shouldn't happen!") + if name not in ['parent', 'names', 'line_nr', 'indent']: + raise AttributeError('Strange access: %s.' % name) + return getattr(self.name, name) def __repr__(self): return "<%s of %s>" % (self.__class__.__name__, self.name) @@ -747,9 +765,13 @@ def get_scopes_for_name(scope, name_str, position=None, search_global=False): and par.position == 0: # this is where self gets added - this happens at another # place, if the var_args are clear. But some times the class is - # not known. Therefore set self. - result.append(Instance(Class(par.parent.parent))) - result.append(par) + # not known. Therefore add a new instance for self. Otherwise + # take the existing. + if isinstance(scope, InstanceElement): + inst = scope.instance + else: + inst = Instance(Class(par.parent.parent)) + result.append(inst) else: result.append(par) return result @@ -858,7 +880,7 @@ def follow_statement(stmt, scope=None, seek_name=None): scope = stmt.get_parent_until(parsing.Function, Function, Execution, parsing.Class, Instance, InstanceElement) - debug.dbg('follow_stmt', stmt, 'in', scope, seek_name) + debug.dbg('follow_stmt', stmt, stmt.parent, 'in', scope, seek_name) call_list = stmt.get_assignment_calls() debug.dbg('calls', call_list, call_list.values) diff --git a/functions.py b/functions.py index 494dee27..9516bc0e 100644 --- a/functions.py +++ b/functions.py @@ -73,12 +73,14 @@ class Definition(object): self.scope = scope def get_name(self): - return self.scope.name + try: + return self.scope.name + except AttributeError: + return self.scope.type def get_module(self): par = self.scope while True: - # TODO what to do with `evaluate.Array` ? if par.parent is not None: par = par.parent else: diff --git a/parsetest.py b/parsetest.py index ce53190d..239d3f67 100644 --- a/parsetest.py +++ b/parsetest.py @@ -158,23 +158,23 @@ a = 3; b = "" b,a=a,b a. -def decorator2(func): - def wrapper(*args): - return func(*args) - return wrapper -def decorator1(func): - def wrapper(*args): - return func(1, *args) - return wrapper -@decorator2 -@decorator1 -def decorated(a,b): - return a,b -exe = decorated(frozenset, '') -exe[1]. - -def rev(a=1, b=""): - return a, b -rev(b=list, a=set)[1]. +class Ar(): + def __init__(self, asd): + self.a = asd + + def rename(self): + self.a2 = self.a + return self.a2 + + + + + + + + + + +Ar(1).rename() diff --git a/test/completion/classes.py b/test/completion/classes.py index 43ad6125..eb3f5abf 100644 --- a/test/completion/classes.py +++ b/test/completion/classes.py @@ -10,6 +10,7 @@ class TestClass(object): self2.var_inst = first_param self2.second = second_param self2.first = first_param + a = 3 def var_func(self): return 1 diff --git a/test/completion/functions.py b/test/completion/functions.py index 7d64a11e..577b3b5f 100644 --- a/test/completion/functions.py +++ b/test/completion/functions.py @@ -136,10 +136,8 @@ def args_func(arg1, *args): exe = args_func(1, "", list) #? int() exe[0] - #? tuple() -exe[1].index - +exe[1] #? list() exe[1][1] diff --git a/test/run.py b/test/run.py index 191e3cba..f8a2ec0f 100755 --- a/test/run.py +++ b/test/run.py @@ -9,6 +9,7 @@ sys.path.append('.') import functions from _compatibility import unicode, BytesIO +only_line = int(sys.argv[2]) if len(sys.argv) > 2 else None #functions.set_debug_function(functions.debug.print_to_stdout) def run_completion_test(correct, source, line_nr, line): @@ -100,7 +101,7 @@ def completion_test(source): correct = None else: # reset the test, if only one specific test is wanted - if len(sys.argv) > 2 and line_nr != int(sys.argv[2]): + if only_line is not None and line_nr != only_line: correct = None import debug debug.debug_function = \