def execute(self, obj, params=(), evaluate_generator=False): if obj.isinstance(er.Function): obj = obj.get_decorated_func() debug.dbg('execute: %s %s', obj, params) try: return stdlib.execute(self, obj, params) except stdlib.NotInStdLib: pass if isinstance(obj, iterable.GeneratorMethod): return obj.execute() elif obj.isinstance(compiled.CompiledObject): if obj.is_executable_class(): return [er.Instance(self, obj, params)] else: return list(obj.execute_function(self, params)) elif obj.isinstance(er.Class): # There maybe executions of executions. return [er.Instance(self, obj, params)] else: stmts = [] if obj.isinstance(er.Function): stmts = er.FunctionExecution(self, obj, params).get_return_types(evaluate_generator) else: if hasattr(obj, 'execute_subscope_by_name'): try: stmts = obj.execute_subscope_by_name('__call__', params) except KeyError: debug.warning("no __call__ func available %s", obj) else: debug.warning("no execution possible %s", obj) debug.dbg('execute result: %s in %s', stmts, obj) return imports.follow_imports(self, stmts)
def eval_call_path(self, path, scope, position): """ Follows a path generated by `pr.StatementElement.generate_call_path()`. """ current = next(path) if isinstance(current, pr.Array): if current.type == pr.Array.NOARRAY: try: lst_cmp = current[0].expression_list()[0] if not isinstance(lst_cmp, pr.ListComprehension): raise IndexError except IndexError: types = list(chain.from_iterable(self.eval_statement(s) for s in current)) else: types = [iterable.GeneratorComprehension(self, lst_cmp)] else: types = [iterable.Array(self, current)] else: if isinstance(current, pr.Name): # This is the first global lookup. types = self.find_types(scope, current, position=position, search_global=True) else: # for pr.Literal types = [compiled.create(self, current.value)] types = imports.follow_imports(self, types) return self.follow_path(path, types, scope)
def execute(self, obj, params=(), evaluate_generator=False): if obj.isinstance(er.Function): obj = obj.get_decorated_func() debug.dbg('execute: %s %s', obj, params) try: return stdlib.execute(self, obj, params) except stdlib.NotInStdLib: pass if isinstance(obj, iterable.GeneratorMethod): return obj.execute() elif obj.isinstance(compiled.CompiledObject): if obj.is_executable_class(): return [er.Instance(self, obj, params)] else: return list(obj.execute_function(self, params)) elif obj.isinstance(er.Class): # There maybe executions of executions. return [er.Instance(self, obj, params)] else: stmts = [] if obj.isinstance(er.Function): stmts = er.FunctionExecution(self, obj, params).get_return_types(evaluate_generator) else: if hasattr(obj, 'execute_subscope_by_name'): try: stmts = obj.execute_subscope_by_name('__call__', params) except KeyError: debug.warning("no __call__ func available %s", obj) else: debug.warning("no execution possible %s", obj) debug.dbg('execute result: %s in %s', stmts, obj) return imports.follow_imports(self, stmts)
def _follow_statements_imports(self): """ Follow both statements and imports, as far as possible. """ if self._definition.isinstance(pr.ExprStmt): return self._evaluator.eval_statement(self._definition) elif self._definition.isinstance(pr.Import): return imports.follow_imports(self._evaluator, [self._definition]) else: return [self._definition]
def _follow_path(self, path, typ, scope): """ Uses a generator and tries to complete the path, e.g.:: foo.bar.baz `_follow_path` is only responsible for completing `.bar.baz`, the rest is done in the `follow_call` function. """ # current is either an Array or a Scope. try: current = next(path) except StopIteration: return None debug.dbg('_follow_path: %s in scope %s', current, typ) result = [] if isinstance(current, pr.Array): # This must be an execution, either () or []. if current.type == pr.Array.LIST: if hasattr(typ, 'get_index_types'): if isinstance(typ, compiled.CompiledObject): # CompiledObject doesn't contain an evaluator instance. result = typ.get_index_types(self, current) else: result = typ.get_index_types(current) elif current.type not in [pr.Array.DICT]: # Scope must be a class or func - make an instance or execution. result = self.execute(typ, current) else: # Curly braces are not allowed, because they make no sense. debug.warning('strange function call with {} %s %s', current, typ) else: # The function must not be decorated with something else. if typ.isinstance(er.Function): typ = typ.get_magic_function_scope() else: # This is the typical lookup while chaining things. if filter_private_variable(typ, scope, current): return [] types = self.find_types(typ, current) result = imports.follow_imports(self, types) return self.follow_path(path, result, scope)
def _follow_path(self, path, typ, scope): """ Uses a generator and tries to complete the path, e.g.:: foo.bar.baz `_follow_path` is only responsible for completing `.bar.baz`, the rest is done in the `follow_call` function. """ # current is either an Array or a Scope. try: current = next(path) except StopIteration: return None debug.dbg('_follow_path: %s in scope %s', current, typ) result = [] if isinstance(current, pr.Array): # This must be an execution, either () or []. if current.type == pr.Array.LIST: if hasattr(typ, 'get_index_types'): if isinstance(typ, compiled.CompiledObject): # CompiledObject doesn't contain an evaluator instance. result = typ.get_index_types(self, current) else: result = typ.get_index_types(current) elif current.type not in [pr.Array.DICT]: # Scope must be a class or func - make an instance or execution. result = self.execute(typ, current) else: # Curly braces are not allowed, because they make no sense. debug.warning('strange function call with {} %s %s', current, typ) else: # The function must not be decorated with something else. if typ.isinstance(er.Function): typ = typ.get_magic_function_scope() else: # This is the typical lookup while chaining things. if filter_private_variable(typ, scope, current): return [] types = self.find_types(typ, current) result = imports.follow_imports(self, types) return self.follow_path(path, result, scope)
def eval_call_path(self, path, scope, position): """ Follows a path generated by `pr.StatementElement.generate_call_path()`. """ current = next(path) if isinstance(current, pr.Array): types = [iterable.Array(self, current)] else: if isinstance(current, pr.NamePart): # This is the first global lookup. types = self.find_types(scope, current, position=position, search_global=True) else: # for pr.Literal types = [compiled.create(self, current.value)] types = imports.follow_imports(self, types) return self.follow_path(path, types, scope)
def eval_call_path(self, path, scope, position): """ Follows a path generated by `pr.StatementElement.generate_call_path()`. """ current = next(path) if isinstance(current, pr.Array): types = [iterable.Array(self, current)] else: if isinstance(current, pr.NamePart): # This is the first global lookup. types = self.find_types(scope, current, position=position, search_global=True) else: # for pr.Literal types = [compiled.create(self, current.value)] types = imports.follow_imports(self, types) return self.follow_path(path, types, scope)
def _follow_statements_imports(self): """ Follow both statements and imports, as far as possible. """ stripped = self._definition if isinstance(stripped, pr.Name): stripped = stripped.parent # We should probably work in `Finder._names_to_types` here. if isinstance(stripped, pr.Function): stripped = er.Function(self._evaluator, stripped) elif isinstance(stripped, pr.Class): stripped = er.Class(self._evaluator, stripped) if stripped.isinstance(pr.Statement): return self._evaluator.eval_statement(stripped) elif stripped.isinstance(pr.Import): return imports.follow_imports(self._evaluator, [stripped]) else: return [stripped]