def _star_star_dict(evaluator, array, input_node, func): dct = defaultdict(lambda: []) from jedi.evaluate.representation import Instance if isinstance(array, Instance) and array.name.get_code() == 'dict': # For now ignore this case. In the future add proper iterators and just # make one call without crazy isinstance checks. return {} if isinstance(array, iterable.FakeDict): return array._dct elif isinstance(array, iterable.Array) and array.type == 'dict': # TODO bad call to non-public API for key_node, values in array._items(): for key in evaluator.eval_element(key_node): if precedence.is_string(key): dct[key.obj] += values else: if func is not None: m = "TypeError: %s argument after ** must be a mapping, not %s" \ % (func.name.value, array) analysis.add(evaluator, 'type-error-star-star', input_node, message=m) return dict(dct)
def _paths_from_assignment(evaluator, statement): """ Extracts the assigned strings from an assignment that looks as follows:: >>> sys.path[0:0] = ['module/path', 'another/module/path'] This function is in general pretty tolerant (and therefore 'buggy'). However, it's not a big issue usually to add more paths to Jedi's sys_path, because it will only affect Jedi in very random situations and by adding more paths than necessary, it usually benefits the general user. """ for exp_list, operator in statement.assignment_details: if len(exp_list) != 1 or not isinstance(exp_list[0], pr.Call): continue if exp_list[0].names() != ['sys', 'path']: continue # TODO at this point we ignore all ways what could be assigned to # sys.path or an execution of it. Here we could do way more # complicated checks. from jedi.evaluate.iterable import get_iterator_types from jedi.evaluate.precedence import is_string for val in get_iterator_types(evaluator.eval_statement(statement)): if is_string(val): yield val.obj
def exact_key_items(self): """ Returns a generator of tuples like dict.items(), where the key is resolved (as a string) and the values are still lazy contexts. """ for key_node, value in self._items(): for key in self._defining_context.eval_node(key_node): if precedence.is_string(key): yield key.obj, context.LazyTreeContext(self._defining_context, value)
def builtins_getattr(evaluator, objects, names, defaults=None): # follow the first param for obj in objects: for name in names: if precedence.is_string(name): return obj.py__getattribute__(name.obj) else: debug.warning('getattr called without str') continue return set()
def builtins_getattr(evaluator, objects, names, defaults=None): # follow the first param for obj in objects: if not isinstance(obj, (er.Instance, er.Class, tree.Module, compiled.CompiledObject)): debug.warning('getattr called without instance') continue for name in names: if precedence.is_string(name): return evaluator.find_types(obj, name.obj) else: debug.warning('getattr called without str') continue return set()
def _paths_from_assignment(module_context, expr_stmt): """ Extracts the assigned strings from an assignment that looks as follows:: >>> sys.path[0:0] = ['module/path', 'another/module/path'] This function is in general pretty tolerant (and therefore 'buggy'). However, it's not a big issue usually to add more paths to Jedi's sys_path, because it will only affect Jedi in very random situations and by adding more paths than necessary, it usually benefits the general user. """ for assignee, operator in zip(expr_stmt.children[::2], expr_stmt.children[1::2]): try: assert operator in ['=', '+='] assert assignee.type in ('power', 'atom_expr') and \ len(assignee.children) > 1 c = assignee.children assert c[0].type == 'name' and c[0].value == 'sys' trailer = c[1] assert trailer.children[0] == '.' and trailer.children[ 1].value == 'path' # TODO Essentially we're not checking details on sys.path # manipulation. Both assigment of the sys.path and changing/adding # parts of the sys.path are the same: They get added to the current # sys.path. """ execution = c[2] assert execution.children[0] == '[' subscript = execution.children[1] assert subscript.type == 'subscript' assert ':' in subscript.children """ except AssertionError: continue from jedi.evaluate.iterable import py__iter__ from jedi.evaluate.precedence import is_string cn = ContextualizedNode(module_context.create_context(expr_stmt), expr_stmt) for lazy_context in py__iter__(module_context.evaluator, cn.infer(), cn): for context in lazy_context.infer(): if is_string(context): yield context.obj
def _paths_from_assignment(evaluator, expr_stmt): """ Extracts the assigned strings from an assignment that looks as follows:: >>> sys.path[0:0] = ['module/path', 'another/module/path'] This function is in general pretty tolerant (and therefore 'buggy'). However, it's not a big issue usually to add more paths to Jedi's sys_path, because it will only affect Jedi in very random situations and by adding more paths than necessary, it usually benefits the general user. """ for assignee, operator in zip(expr_stmt.children[::2], expr_stmt.children[1::2]): try: assert operator in ['=', '+='] assert tree.is_node(assignee, 'power', 'atom_expr') and \ len(assignee.children) > 1 c = assignee.children assert c[0].type == 'name' and c[0].value == 'sys' trailer = c[1] assert trailer.children[0] == '.' and trailer.children[1].value == 'path' # TODO Essentially we're not checking details on sys.path # manipulation. Both assigment of the sys.path and changing/adding # parts of the sys.path are the same: They get added to the current # sys.path. """ execution = c[2] assert execution.children[0] == '[' subscript = execution.children[1] assert subscript.type == 'subscript' assert ':' in subscript.children """ except AssertionError: continue from jedi.evaluate.iterable import py__iter__ from jedi.evaluate.precedence import is_string types = evaluator.eval_element(expr_stmt) for types in py__iter__(evaluator, types, expr_stmt): for typ in types: if is_string(typ): yield typ.obj