def import_module(evaluator, import_names, parent_module_context, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ if import_names[0] in settings.auto_import_modules: module = _load_builtin_module(evaluator, import_names, sys_path) if module is None: return NO_CONTEXTS return ContextSet([module]) module_name = '.'.join(import_names) if parent_module_context is None: # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. file_io_or_ns, is_pkg = evaluator.compiled_subprocess.get_module_info( string=import_names[-1], full_name=module_name, sys_path=sys_path, is_global_search=True, ) if is_pkg is None: return NO_CONTEXTS else: try: method = parent_module_context.py__path__ except AttributeError: # The module is not a package. return NO_CONTEXTS else: paths = method() for path in paths: # At the moment we are only using one path. So this is # not important to be correct. if not isinstance(path, list): path = [path] file_io_or_ns, is_pkg = evaluator.compiled_subprocess.get_module_info( string=import_names[-1], path=path, full_name=module_name, is_global_search=False, ) if is_pkg is not None: break else: return NO_CONTEXTS if isinstance(file_io_or_ns, ImplicitNSInfo): from jedi.evaluate.context.namespace import ImplicitNamespaceContext module = ImplicitNamespaceContext( evaluator, fullname=file_io_or_ns.name, paths=file_io_or_ns.paths, ) elif file_io_or_ns is None: module = _load_builtin_module(evaluator, import_names, sys_path) if module is None: return NO_CONTEXTS else: module = _load_python_module( evaluator, file_io_or_ns, sys_path, import_names=import_names, is_package=is_pkg, ) if parent_module_context is None: debug.dbg('global search_module %s: %s', import_names[-1], module) else: debug.dbg('search_module %s in paths %s: %s', module_name, paths, module) return ContextSet([module])
def infer(self): return ContextSet(self._instance)
def eval_node(context, element): debug.dbg('eval_node %s@%s in %s', element, element.start_pos, context) evaluator = context.evaluator typ = element.type if typ in ('name', 'number', 'string', 'atom', 'strings', 'keyword', 'fstring'): return eval_atom(context, element) elif typ == 'lambdef': return ContextSet([FunctionContext.from_context(context, element)]) elif typ == 'expr_stmt': return eval_expr_stmt(context, element) elif typ in ('power', 'atom_expr'): first_child = element.children[0] children = element.children[1:] had_await = False if first_child.type == 'keyword' and first_child.value == 'await': had_await = True first_child = children.pop(0) context_set = context.eval_node(first_child) for (i, trailer) in enumerate(children): if trailer == '**': # has a power operation. right = context.eval_node(children[i + 1]) context_set = _eval_comparison(evaluator, context, context_set, trailer, right) break context_set = eval_trailer(context, context_set, trailer) if had_await: return context_set.py__await__().py__stop_iteration_returns() return context_set elif typ in ( 'testlist_star_expr', 'testlist', ): # The implicit tuple in statements. return ContextSet( [iterable.SequenceLiteralContext(evaluator, context, element)]) elif typ in ('not_test', 'factor'): context_set = context.eval_node(element.children[-1]) for operator in element.children[:-1]: context_set = eval_factor(context_set, operator) return context_set elif typ == 'test': # `x if foo else y` case. return (context.eval_node(element.children[0]) | context.eval_node(element.children[-1])) elif typ == 'operator': # Must be an ellipsis, other operators are not evaluated. # In Python 2 ellipsis is coded as three single dot tokens, not # as one token 3 dot token. if element.value not in ('.', '...'): origin = element.parent raise AssertionError("unhandled operator %s in %s " % (repr(element.value), origin)) return ContextSet([compiled.builtin_from_name(evaluator, u'Ellipsis')]) elif typ == 'dotted_name': context_set = eval_atom(context, element.children[0]) for next_name in element.children[2::2]: # TODO add search_global=True? context_set = context_set.py__getattribute__(next_name, name_context=context) return context_set elif typ == 'eval_input': return eval_node(context, element.children[0]) elif typ == 'annassign': return annotation.eval_annotation(context, element.children[1]) \ .execute_annotation() elif typ == 'yield_expr': if len(element.children) and element.children[1].type == 'yield_arg': # Implies that it's a yield from. element = element.children[1].children[1] generators = context.eval_node(element) \ .py__getattribute__('__iter__').execute_evaluated() return generators.py__stop_iteration_returns() # Generator.send() is not implemented. return NO_CONTEXTS else: return eval_or_test(context, element)
def eval_atom(context, atom): """ Basically to process ``atom`` nodes. The parser sometimes doesn't generate the node (because it has just one child). In that case an atom might be a name or a literal as well. """ if atom.type == 'name': # This is the first global lookup. stmt = tree.search_ancestor(atom, 'expr_stmt', 'lambdef') or atom if stmt.type == 'lambdef': stmt = atom return context.py__getattribute__(name_or_str=atom, position=stmt.start_pos, search_global=True) elif isinstance(atom, tree.Literal): string = parser_utils.safe_literal_eval(atom.value) return ContextSet(compiled.create(context.evaluator, string)) else: c = atom.children if c[0].type == 'string': # Will be one string. context_set = eval_atom(context, c[0]) for string in c[1:]: right = eval_atom(context, string) context_set = _eval_comparison(context.evaluator, context, context_set, '+', right) return context_set # Parentheses without commas are not tuples. elif c[0] == '(' and not len(c) == 2 \ and not(c[1].type == 'testlist_comp' and len(c[1].children) > 1): return context.eval_node(c[1]) try: comp_for = c[1].children[1] except (IndexError, AttributeError): pass else: if comp_for == ':': # Dict comprehensions have a colon at the 3rd index. try: comp_for = c[1].children[3] except IndexError: pass if comp_for.type == 'comp_for': return ContextSet( iterable.Comprehension.from_atom(context.evaluator, context, atom)) # It's a dict/list/tuple literal. array_node = c[1] try: array_node_c = array_node.children except AttributeError: array_node_c = [] if c[0] == '{' and (array_node == '}' or ':' in array_node_c): context = iterable.DictLiteralContext(context.evaluator, context, atom) else: context = iterable.SequenceLiteralContext(context.evaluator, context, atom) return ContextSet(context)
def infer(self): return ContextSet([self._context])
def py__stop_iteration_returns(self): return ContextSet(compiled.builtin_from_name(self.evaluator, u'None'))
def _check_array_additions(context, sequence): """ Checks if a `Array` has "add" (append, insert, extend) statements: >>> a = [""] >>> a.append(1) """ from jedi.evaluate import arguments debug.dbg('Dynamic array search for %s' % sequence, color='MAGENTA') module_context = context.get_root_context() if not settings.dynamic_array_additions or isinstance( module_context, compiled.CompiledObject): debug.dbg('Dynamic array search aborted.', color='MAGENTA') return ContextSet() def find_additions(context, arglist, add_name): params = list( arguments.TreeArguments(context.evaluator, context, arglist).unpack()) result = set() if add_name in ['insert']: params = params[1:] if add_name in ['append', 'add', 'insert']: for key, whatever in params: result.add(whatever) elif add_name in ['extend', 'update']: for key, lazy_context in params: result |= set(lazy_context.infer().iterate()) return result temp_param_add, settings.dynamic_params_for_other_modules = \ settings.dynamic_params_for_other_modules, False is_list = sequence.name.string_name == 'list' search_names = (['append', 'extend', 'insert'] if is_list else ['add', 'update']) added_types = set() for add_name in search_names: try: possible_names = module_context.tree_node.get_used_names( )[add_name] except KeyError: continue else: for name in possible_names: context_node = context.tree_node if not (context_node.start_pos < name.start_pos < context_node.end_pos): continue trailer = name.parent power = trailer.parent trailer_pos = power.children.index(trailer) try: execution_trailer = power.children[trailer_pos + 1] except IndexError: continue else: if execution_trailer.type != 'trailer' \ or execution_trailer.children[0] != '(' \ or execution_trailer.children[1] == ')': continue random_context = context.create_context(name) with recursion.execution_allowed(context.evaluator, power) as allowed: if allowed: found = evaluate_call_of_leaf(random_context, name, cut_own_trailer=True) if sequence in found: # The arrays match. Now add the results added_types |= find_additions( random_context, execution_trailer.children[1], add_name) # reset settings settings.dynamic_params_for_other_modules = temp_param_add debug.dbg('Dynamic array result %s' % added_types, color='MAGENTA') return added_types
def _do_import(self, import_path, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ import_parts = [ force_unicode(i.value if isinstance(i, tree.Name) else i) for i in import_path ] # Handle "magic" Flask extension imports: # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``. if len(import_path) > 2 and import_parts[:2] == ['flask', 'ext']: # New style. ipath = ('flask_' + str(import_parts[2]), ) + import_path[3:] modules = self._do_import(ipath, sys_path) if modules: return modules else: # Old style return self._do_import(('flaskext', ) + import_path[2:], sys_path) module_name = '.'.join(import_parts) try: return ContextSet(self._evaluator.module_cache.get(module_name)) except KeyError: pass if len(import_path) > 1: # This is a recursive way of importing that works great with # the module cache. bases = self._do_import(import_path[:-1], sys_path) if not bases: return NO_CONTEXTS # We can take the first element, because only the os special # case yields multiple modules, which is not important for # further imports. parent_module = list(bases)[0] # This is a huge exception, we follow a nested import # ``os.path``, because it's a very important one in Python # that is being achieved by messing with ``sys.modules`` in # ``os``. if import_parts == ['os', 'path']: return parent_module.py__getattribute__('path') try: method = parent_module.py__path__ except AttributeError: # The module is not a package. _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS else: paths = method() debug.dbg('search_module %s in paths %s', module_name, paths) for path in paths: # At the moment we are only using one path. So this is # not important to be correct. if not isinstance(path, list): path = [path] code, module_path, is_pkg = self._evaluator.compiled_subprocess.get_module_info( string=import_parts[-1], path=path, full_name=module_name) if module_path is not None: break else: _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS else: debug.dbg('search_module %s in %s', import_parts[-1], self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. code, module_path, is_pkg = self._evaluator.compiled_subprocess.get_module_info( string=import_parts[-1], full_name=module_name, sys_path=sys_path, ) if module_path is None: # The module is not a package. _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS module = _load_module( self._evaluator, module_path, code, sys_path, module_name=module_name, safe_module_name=True, ) if module is None: # The file might raise an ImportError e.g. and therefore not be # importable. return NO_CONTEXTS return ContextSet(module)
def eval_element(self, context, element): if isinstance(context, CompForContext): return eval_node(context, element) if_stmt = element while if_stmt is not None: if_stmt = if_stmt.parent if if_stmt.type in ('if_stmt', 'for_stmt'): break if parser_utils.is_scope(if_stmt): if_stmt = None break predefined_if_name_dict = context.predefined_names.get(if_stmt) # TODO there's a lot of issues with this one. We actually should do # this in a different way. Caching should only be active in certain # cases and this all sucks. if predefined_if_name_dict is None and if_stmt \ and if_stmt.type == 'if_stmt' and self.is_analysis: if_stmt_test = if_stmt.children[1] name_dicts = [{}] # If we already did a check, we don't want to do it again -> If # context.predefined_names is filled, we stop. # We don't want to check the if stmt itself, it's just about # the content. if element.start_pos > if_stmt_test.end_pos: # Now we need to check if the names in the if_stmt match the # names in the suite. if_names = helpers.get_names_of_node(if_stmt_test) element_names = helpers.get_names_of_node(element) str_element_names = [e.value for e in element_names] if any(i.value in str_element_names for i in if_names): for if_name in if_names: definitions = self.goto_definitions(context, if_name) # Every name that has multiple different definitions # causes the complexity to rise. The complexity should # never fall below 1. if len(definitions) > 1: if len(name_dicts) * len(definitions) > 16: debug.dbg( 'Too many options for if branch evaluation %s.', if_stmt) # There's only a certain amount of branches # Jedi can evaluate, otherwise it will take to # long. name_dicts = [{}] break original_name_dicts = list(name_dicts) name_dicts = [] for definition in definitions: new_name_dicts = list(original_name_dicts) for i, name_dict in enumerate(new_name_dicts): new_name_dicts[i] = name_dict.copy() new_name_dicts[i][ if_name.value] = ContextSet(definition) name_dicts += new_name_dicts else: for name_dict in name_dicts: name_dict[if_name.value] = definitions if len(name_dicts) > 1: result = ContextSet() for name_dict in name_dicts: with helpers.predefine_names(context, if_stmt, name_dict): result |= eval_node(context, element) return result else: return self._eval_element_if_evaluated(context, element) else: if predefined_if_name_dict: return eval_node(context, element) else: return self._eval_element_if_evaluated(context, element)
def py__getitem__(self, index_context_set, contextualized_node): if self.array_type == 'dict': return self._dict_values() return iterate_contexts(ContextSet([self]))
def py__iter__(self, contextualized_node=None): return ContextSet([self])
def iterate(): if isinstance(maybe_tuple_context, SequenceLiteralContext): for lazy_context in maybe_tuple_context.py__iter__(contextualized_node=None): yield lazy_context.infer() else: yield ContextSet([maybe_tuple_context])
def infer(self): return ContextSet()
def infer(self): module = self.parent_context.get_root_context() return ContextSet( _create_from_name(self._evaluator, module, self.parent_context, self.string_name))
def py__getitem__(self, index): if isinstance(index, slice): return ContextSet(self) all_types = list(self.py__iter__()) return all_types[index].infer()
def get_dynamic_array_instance(instance, arguments): """Used for set() and list() instances.""" ai = _ArrayInstance(instance, arguments) from jedi.evaluate import arguments return arguments.ValuesArguments([ContextSet(ai)])
def _imitate_values(self): lazy_context = LazyKnownContexts(self.dict_values()) return ContextSet(FakeSequence(self.evaluator, u'list', [lazy_context]))
def tree_name_to_contexts(evaluator, context, tree_name): context_set = ContextSet() module_node = context.get_root_context().tree_node if module_node is not None: names = module_node.get_used_names().get(tree_name.value, []) for name in names: expr_stmt = name.parent correct_scope = parser_utils.get_parent_scope( name) == context.tree_node if expr_stmt.type == "expr_stmt" and expr_stmt.children[ 1].type == "annassign" and correct_scope: context_set |= _evaluate_for_annotation( context, expr_stmt.children[1].children[1]) if context_set: return context_set types = [] node = tree_name.get_definition(import_name_always=True) if node is None: node = tree_name.parent if node.type == 'global_stmt': context = evaluator.create_context(context, tree_name) finder = NameFinder(evaluator, context, context, tree_name.value) filters = finder.get_filters(search_global=True) # For global_stmt lookups, we only need the first possible scope, # which means the function itself. filters = [next(filters)] return finder.find(filters, attribute_lookup=False) elif node.type not in ('import_from', 'import_name'): raise ValueError("Should not happen. type: %s", node.type) typ = node.type if typ == 'for_stmt': types = pep0484.find_type_from_comment_hint_for( context, node, tree_name) if types: return types if typ == 'with_stmt': types = pep0484.find_type_from_comment_hint_with( context, node, tree_name) if types: return types if typ in ('for_stmt', 'comp_for'): try: types = context.predefined_names[node][tree_name.value] except KeyError: cn = ContextualizedNode(context, node.children[3]) for_types = iterate_contexts( cn.infer(), contextualized_node=cn, is_async=node.parent.type == 'async_stmt', ) c_node = ContextualizedName(context, tree_name) types = check_tuple_assignments(evaluator, c_node, for_types) elif typ == 'expr_stmt': types = _remove_statements(evaluator, context, node, tree_name) elif typ == 'with_stmt': context_managers = context.eval_node( node.get_test_node_from_name(tree_name)) enter_methods = context_managers.py__getattribute__(u'__enter__') return enter_methods.execute_evaluated() elif typ in ('import_from', 'import_name'): types = imports.infer_import(context, tree_name) elif typ in ('funcdef', 'classdef'): types = _apply_decorators(context, node) elif typ == 'try_stmt': # TODO an exception can also be a tuple. Check for those. # TODO check for types that are not classes and add it to # the static analysis report. exceptions = context.eval_node( tree_name.get_previous_sibling().get_previous_sibling()) types = exceptions.execute_evaluated() else: raise ValueError("Should not happen. type: %s" % typ) return types
def _values(self): return ContextSet( FakeSequence(self.evaluator, u'tuple', [LazyKnownContexts(self.dict_values())]))
def py__call__(self, arguments): instance, = super(AbstractAnnotatedClass, self).py__call__(arguments) return ContextSet([InstanceWrapper(instance)])
def _do_import(self, import_path, sys_path): """ This method is very similar to importlib's `_gcd_import`. """ import_parts = [ i.value if isinstance(i, tree.Name) else i for i in import_path ] # Handle "magic" Flask extension imports: # ``flask.ext.foo`` is really ``flask_foo`` or ``flaskext.foo``. if len(import_path) > 2 and import_parts[:2] == ['flask', 'ext']: # New style. ipath = ('flask_' + str(import_parts[2]), ) + import_path[3:] modules = self._do_import(ipath, sys_path) if modules: return modules else: # Old style return self._do_import(('flaskext', ) + import_path[2:], sys_path) module_name = '.'.join(import_parts) try: return ContextSet(self._evaluator.modules[module_name]) except KeyError: pass if len(import_path) > 1: # This is a recursive way of importing that works great with # the module cache. bases = self._do_import(import_path[:-1], sys_path) if not bases: return NO_CONTEXTS # We can take the first element, because only the os special # case yields multiple modules, which is not important for # further imports. parent_module = list(bases)[0] # This is a huge exception, we follow a nested import # ``os.path``, because it's a very important one in Python # that is being achieved by messing with ``sys.modules`` in # ``os``. if import_parts == ['os', 'path']: return parent_module.py__getattribute__('path') try: method = parent_module.py__path__ except AttributeError: # The module is not a package. _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS else: paths = method() debug.dbg('search_module %s in paths %s', module_name, paths) for path in paths: # At the moment we are only using one path. So this is # not important to be correct. try: if not isinstance(path, list): path = [path] module_file, module_path, is_pkg = \ find_module(import_parts[-1], path, fullname=module_name) break except ImportError: module_path = None if module_path is None: _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS else: parent_module = None try: debug.dbg('search_module %s in %s', import_parts[-1], self.file_path) # Override the sys.path. It works only good that way. # Injecting the path directly into `find_module` did not work. sys.path, temp = sys_path, sys.path try: module_file, module_path, is_pkg = \ find_module(import_parts[-1], fullname=module_name) finally: sys.path = temp except ImportError: # The module is not a package. _add_error(self.module_context, import_path[-1]) return NO_CONTEXTS code = None if is_pkg: # In this case, we don't have a file yet. Search for the # __init__ file. if module_path.endswith(('.zip', '.egg')): code = module_file.loader.get_source(module_name) else: module_path = get_init_path(module_path) elif module_file: code = module_file.read() module_file.close() if isinstance(module_path, ImplicitNSInfo): from jedi.evaluate.context.namespace import ImplicitNamespaceContext fullname, paths = module_path.name, module_path.paths module = ImplicitNamespaceContext(self._evaluator, fullname=fullname) module.paths = paths elif module_file is None and not module_path.endswith( ('.py', '.zip', '.egg')): module = compiled.load_module(self._evaluator, module_path) else: module = _load_module(self._evaluator, module_path, code, sys_path, parent_module) if module is None: # The file might raise an ImportError e.g. and therefore not be # importable. return NO_CONTEXTS self._evaluator.modules[module_name] = module return ContextSet(module)
def infer(self): return ContextSet(self._remap())
def eval_node(context, element): debug.dbg('eval_element %s@%s', element, element.start_pos) evaluator = context.evaluator typ = element.type if typ in ('name', 'number', 'string', 'atom'): return eval_atom(context, element) elif typ == 'keyword': # For False/True/None if element.value in ('False', 'True', 'None'): return ContextSet( compiled.builtin_from_name(evaluator, element.value)) # else: print e.g. could be evaluated like this in Python 2.7 return NO_CONTEXTS elif typ == 'lambdef': return ContextSet(FunctionContext(evaluator, context, element)) elif typ == 'expr_stmt': return eval_expr_stmt(context, element) elif typ in ('power', 'atom_expr'): first_child = element.children[0] if not (first_child.type == 'keyword' and first_child.value == 'await'): context_set = eval_atom(context, first_child) for trailer in element.children[1:]: if trailer == '**': # has a power operation. right = evaluator.eval_element(context, element.children[2]) context_set = _eval_comparison(evaluator, context, context_set, trailer, right) break context_set = eval_trailer(context, context_set, trailer) return context_set return NO_CONTEXTS elif typ in ( 'testlist_star_expr', 'testlist', ): # The implicit tuple in statements. return ContextSet( iterable.SequenceLiteralContext(evaluator, context, element)) elif typ in ('not_test', 'factor'): context_set = context.eval_node(element.children[-1]) for operator in element.children[:-1]: context_set = eval_factor(context_set, operator) return context_set elif typ == 'test': # `x if foo else y` case. return (context.eval_node(element.children[0]) | context.eval_node(element.children[-1])) elif typ == 'operator': # Must be an ellipsis, other operators are not evaluated. # In Python 2 ellipsis is coded as three single dot tokens, not # as one token 3 dot token. assert element.value in ('.', '...') return ContextSet(compiled.create(evaluator, Ellipsis)) elif typ == 'dotted_name': context_set = eval_atom(context, element.children[0]) for next_name in element.children[2::2]: # TODO add search_global=True? id:489 gh:490 context_set = context_set.py__getattribute__(next_name, name_context=context) return context_set elif typ == 'eval_input': return eval_node(context, element.children[0]) elif typ == 'annassign': return pep0484._evaluate_for_annotation(context, element.children[1]) else: return eval_or_test(context, element)
def infer(self): return ContextSet(self.parent_context)
def infer(self): return ContextSet(self.data)
def goto(self): return ContextSet([self._context.name])
def _eval_comparison_part(evaluator, context, left, operator, right): l_is_num = is_number(left) r_is_num = is_number(right) if isinstance(operator, unicode): str_operator = operator else: str_operator = force_unicode(str(operator.value)) if str_operator == '*': # for iterables, ignore * operations if isinstance(left, iterable.Sequence) or is_string(left): return ContextSet([left]) elif isinstance(right, iterable.Sequence) or is_string(right): return ContextSet([right]) elif str_operator == '+': if l_is_num and r_is_num or is_string(left) and is_string(right): return ContextSet([left.execute_operation(right, str_operator)]) elif _is_tuple(left) and _is_tuple(right) or _is_list( left) and _is_list(right): return ContextSet([iterable.MergedArray(evaluator, (left, right))]) elif str_operator == '-': if l_is_num and r_is_num: return ContextSet([left.execute_operation(right, str_operator)]) elif str_operator == '%': # With strings and numbers the left type typically remains. Except for # `int() % float()`. return ContextSet([left]) elif str_operator in COMPARISON_OPERATORS: if left.is_compiled() and right.is_compiled(): # Possible, because the return is not an option. Just compare. try: return ContextSet( [left.execute_operation(right, str_operator)]) except TypeError: # Could be True or False. pass else: if str_operator in ('is', '!=', '==', 'is not'): operation = COMPARISON_OPERATORS[str_operator] bool_ = operation(left, right) return ContextSet([_bool_to_context(evaluator, bool_)]) if isinstance(left, VersionInfo): version_info = _get_tuple_ints(right) if version_info is not None: bool_result = compiled.access.COMPARISON_OPERATORS[ operator](evaluator.environment.version_info, tuple(version_info)) return ContextSet( [_bool_to_context(evaluator, bool_result)]) return ContextSet([ _bool_to_context(evaluator, True), _bool_to_context(evaluator, False) ]) elif str_operator == 'in': return NO_CONTEXTS def check(obj): """Checks if a Jedi object is either a float or an int.""" return isinstance(obj, TreeInstance) and \ obj.name.string_name in ('int', 'float') # Static analysis, one is a number, the other one is not. if str_operator in ('+', '-') and l_is_num != r_is_num \ and not (check(left) or check(right)): message = "TypeError: unsupported operand type(s) for +: %s and %s" analysis.add(context, 'type-error-operation', operator, message % (left, right)) result = ContextSet([left, right]) debug.dbg('Used operator %s resulting in %s', operator, result) return result
def infer(self): return ContextSet([ _create_from_name(self._evaluator, self.parent_context, self.string_name) ])
def eval_atom(context, atom): """ Basically to process ``atom`` nodes. The parser sometimes doesn't generate the node (because it has just one child). In that case an atom might be a name or a literal as well. """ if atom.type == 'name': # This is the first global lookup. stmt = tree.search_ancestor(atom, 'expr_stmt', 'lambdef') or atom if stmt.type == 'lambdef': stmt = atom return context.py__getattribute__(name_or_str=atom, position=stmt.start_pos, search_global=True) elif atom.type == 'keyword': # For False/True/None if atom.value in ('False', 'True', 'None'): return ContextSet( compiled.builtin_from_name(context.evaluator, atom.value)) elif atom.value == 'print': # print e.g. could be evaluated like this in Python 2.7 return NO_CONTEXTS elif atom.value == 'yield': # Contrary to yield from, yield can just appear alone to return a # value when used with `.send()`. return NO_CONTEXTS assert False, 'Cannot evaluate the keyword %s' % atom elif isinstance(atom, tree.Literal): string = context.evaluator.compiled_subprocess.safe_literal_eval( atom.value) return ContextSet( compiled.create_simple_object(context.evaluator, string)) elif atom.type == 'strings': # Will be multiple string. context_set = eval_atom(context, atom.children[0]) for string in atom.children[1:]: right = eval_atom(context, string) context_set = _eval_comparison(context.evaluator, context, context_set, u'+', right) return context_set else: c = atom.children # Parentheses without commas are not tuples. if c[0] == '(' and not len(c) == 2 \ and not(c[1].type == 'testlist_comp' and len(c[1].children) > 1): return context.eval_node(c[1]) try: comp_for = c[1].children[1] except (IndexError, AttributeError): pass else: if comp_for == ':': # Dict comprehensions have a colon at the 3rd index. try: comp_for = c[1].children[3] except IndexError: pass if comp_for.type == 'comp_for': return ContextSet( iterable.comprehension_from_atom(context.evaluator, context, atom)) # It's a dict/list/tuple literal. array_node = c[1] try: array_node_c = array_node.children except AttributeError: array_node_c = [] if c[0] == '{' and (array_node == '}' or ':' in array_node_c): context = iterable.DictLiteralContext(context.evaluator, context, atom) else: context = iterable.SequenceLiteralContext(context.evaluator, context, atom) return ContextSet(context)
def py__call__(self, arguments): from jedi.evaluate.context import TreeInstance return ContextSet([ TreeInstance(self.evaluator, self.parent_context, self, arguments) ])