def get_return_values(self, check_yields=False): funcdef = self.tree_node if funcdef.type == 'lambdef': return self.eval_node(funcdef.children[-1]) if check_yields: context_set = NO_CONTEXTS returns = get_yield_exprs(self.evaluator, funcdef) else: returns = funcdef.iter_return_stmts() context_set = docstrings.infer_return_types(self.function_context) context_set |= pep0484.infer_return_types(self.function_context) for r in returns: check = flow_analysis.reachability_check(self, funcdef, r) if check is flow_analysis.UNREACHABLE: debug.dbg('Return unreachable: %s', r) else: if check_yields: context_set |= ContextSet.from_sets( lazy_context.infer() for lazy_context in self._get_yield_lazy_context(r) ) else: try: children = r.children except AttributeError: ctx = compiled.builtin_from_name(self.evaluator, u'None') context_set |= ContextSet(ctx) else: context_set |= self.eval_node(children[1]) if check is flow_analysis.REACHABLE: debug.dbg('Return reachable: %s', r) break return context_set
def get_filters(self, search_global, until_position=None, origin_scope=None): # `array.type` is a string with the type, e.g. 'list'. compiled_obj = compiled.builtin_from_name(self.evaluator, self.array_type) yield SpecialMethodFilter(self, self.builtin_methods, compiled_obj) for typ in compiled_obj.execute_evaluated(self): for filter in typ.get_filters(): yield filter
def _eval_element_not_cached(self, context, element): debug.dbg('eval_element %s@%s', element, element.start_pos) types = set() typ = element.type if typ in ('name', 'number', 'string', 'atom'): types = self.eval_atom(context, element) elif typ == 'keyword': # For False/True/None if element.value in ('False', 'True', 'None'): types.add(compiled.builtin_from_name(self, element.value)) # else: print e.g. could be evaluated like this in Python 2.7 elif typ == 'lambdef': types = set([er.FunctionContext(self, context, element)]) elif typ == 'expr_stmt': types = self.eval_statement(context, element) elif typ in ('power', 'atom_expr'): first_child = element.children[0] if not (first_child.type == 'keyword' and first_child.value == 'await'): types = self.eval_atom(context, first_child) for trailer in element.children[1:]: if trailer == '**': # has a power operation. right = self.eval_element(context, element.children[2]) types = set(precedence.calculate(self, context, types, trailer, right)) break types = self.eval_trailer(context, types, trailer) elif typ in ('testlist_star_expr', 'testlist',): # The implicit tuple in statements. types = set([iterable.SequenceLiteralContext(self, context, element)]) elif typ in ('not_test', 'factor'): types = self.eval_element(context, element.children[-1]) for operator in element.children[:-1]: types = set(precedence.factor_calculate(self, types, operator)) elif typ == 'test': # `x if foo else y` case. types = (self.eval_element(context, element.children[0]) | self.eval_element(context, 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 ('.', '...') types = set([compiled.create(self, Ellipsis)]) elif typ == 'dotted_name': types = self.eval_atom(context, element.children[0]) for next_name in element.children[2::2]: # TODO add search_global=True? types = unite( typ.py__getattribute__(next_name, name_context=context) for typ in types ) types = types elif typ == 'eval_input': types = self._eval_element_not_cached(context, element.children[0]) elif typ == 'annassign': types = pep0484._evaluate_for_annotation(context, element.children[1]) else: types = precedence.calculate_children(self, context, element.children) debug.dbg('eval_element result %s', types) return types
def names_dicts(self, search_global=False): # Always False. # `array.type` is a string with the type, e.g. 'list'. scope = compiled.builtin_from_name(self._evaluator, self.type) # builtins only have one class -> [0] scopes = self._evaluator.execute_evaluated(scope, self) names_dicts = list(scopes)[0].names_dicts(search_global) #yield names_dicts[0] yield self._get_names_dict(names_dicts[1])
def py__bases__(self): arglist = self.tree_node.get_super_arglist() if arglist: from jedi.evaluate import arguments args = arguments.TreeArguments(self.evaluator, self.parent_context, arglist) return [value for key, value in args.unpack() if key is None] else: return [LazyKnownContext(compiled.builtin_from_name(self.evaluator, u'object'))]
def _eval_element_not_cached(self, element): debug.dbg('eval_element %s@%s', element, element.start_pos) types = set() if isinstance(element, (tree.Name, tree.Literal)) or tree.is_node(element, 'atom'): types = self._eval_atom(element) elif isinstance(element, tree.Keyword): # For False/True/None if element.value in ('False', 'True', 'None'): types.add(compiled.builtin_from_name(self, element.value)) # else: print e.g. could be evaluated like this in Python 2.7 elif element.isinstance(tree.Lambda): types = set([er.LambdaWrapper(self, element)]) elif element.isinstance(er.LambdaWrapper): types = set([element]) # TODO this is no real evaluation. elif element.type == 'expr_stmt': types = self.eval_statement(element) elif element.type in ('power', 'atom_expr'): types = self._eval_atom(element.children[0]) for trailer in element.children[1:]: if trailer == '**': # has a power operation. right = self.eval_element(element.children[2]) types = set(precedence.calculate(self, types, trailer, right)) break types = self.eval_trailer(types, trailer) elif element.type in ('testlist_star_expr', 'testlist',): # The implicit tuple in statements. types = set([iterable.ImplicitTuple(self, element)]) elif element.type in ('not_test', 'factor'): types = self.eval_element(element.children[-1]) for operator in element.children[:-1]: types = set(precedence.factor_calculate(self, types, operator)) elif element.type == 'test': # `x if foo else y` case. types = (self.eval_element(element.children[0]) | self.eval_element(element.children[-1])) elif element.type == 'operator': # Must be an ellipsis, other operators are not evaluated. assert element.value == '...' types = set([compiled.create(self, Ellipsis)]) elif element.type == 'dotted_name': types = self._eval_atom(element.children[0]) for next_name in element.children[2::2]: types = set(chain.from_iterable(self.find_types(typ, next_name) for typ in types)) types = types elif element.type == 'eval_input': types = self._eval_element_not_cached(element.children[0]) elif element.type == 'annassign': types = self.eval_element(element.children[1]) else: types = precedence.calculate_children(self, element.children) debug.dbg('eval_element result %s', types) return types
def py__get__(self, obj): # Arguments in __get__ descriptors are obj, class. # `method` is the new parent of the array, don't know if that's good. names = self.get_function_slot_names(u'__get__') if names: if isinstance(obj, AbstractInstanceContext): return self.execute_function_slots(names, obj, obj.class_context) else: none_obj = compiled.builtin_from_name(self.evaluator, u'None') return self.execute_function_slots(names, none_obj, obj) else: return ContextSet(self)
def literals_to_types(evaluator, result): # Changes literals ('a', 1, 1.0, etc) to its type instances (str(), # int(), float(), etc). new_result = set() for typ in result: if is_literal(typ): # Literals are only valid as long as the operations are # correct. Otherwise add a value-free instance. cls = builtin_from_name(evaluator, typ.name.value) new_result |= evaluator.execute(cls) else: new_result.add(typ) return new_result
def _literals_to_types(evaluator, result): # Changes literals ('a', 1, 1.0, etc) to its type instances (str(), # int(), float(), etc). new_result = NO_CONTEXTS for typ in result: if is_literal(typ): # Literals are only valid as long as the operations are # correct. Otherwise add a value-free instance. cls = compiled.builtin_from_name(evaluator, typ.name.string_name) new_result |= cls.execute_evaluated() else: new_result |= ContextSet([typ]) return new_result
def py__get__(self, obj, class_context): """ obj may be None. """ # Arguments in __get__ descriptors are obj, class. # `method` is the new parent of the array, don't know if that's good. names = self.get_function_slot_names(u'__get__') if names: if obj is None: obj = compiled.builtin_from_name(self.evaluator, u'None') return self.execute_function_slots(names, obj, class_context) else: return ContextSet([self])
def _literals_to_types(evaluator, result): # Changes literals ('a', 1, 1.0, etc) to its type instances (str(), # int(), float(), etc). new_result = NO_CONTEXTS for typ in result: if is_literal(typ): # Literals are only valid as long as the operations are # correct. Otherwise add a value-free instance. cls = compiled.builtin_from_name(evaluator, typ.name.string_name) new_result |= cls.execute_evaluated() else: new_result |= ContextSet(typ) return new_result
def _get_yield_lazy_context(self, yield_expr): if yield_expr.type == 'keyword': # `yield` just yields None. ctx = compiled.builtin_from_name(self.evaluator, u'None') yield LazyKnownContext(ctx) return node = yield_expr.children[1] if node.type == 'yield_arg': # It must be a yield from. cn = ContextualizedNode(self, node.children[1]) for lazy_context in cn.infer().iterate(cn): yield lazy_context else: yield LazyTreeContext(self, node)
def values(self): from jedi.evaluate.compiled import builtin_from_name names = [] needs_type_completions, dir_infos = self._compiled_object.access_handle.get_dir_infos() for name in dir_infos: names += self._get( name, lambda: dir_infos[name], lambda: dir_infos.keys(), ) # ``dir`` doesn't include the type names. if not self.is_instance and needs_type_completions: for filter in builtin_from_name(self._evaluator, u'type').get_filters(): names += filter.values() return names
def values(self): from jedi.evaluate.compiled import builtin_from_name names = [] needs_type_completions, dir_infos = self._compiled_object.access_handle.get_dir_infos() for name in dir_infos: names += self._get( name, lambda: dir_infos[name], lambda: dir_infos.keys(), ) # ``dir`` doesn't include the type names. if not self._is_instance and needs_type_completions: for filter in builtin_from_name(self._evaluator, u'type').get_filters(): names += filter.values() return names
def _remap(self): name = self.string_name evaluator = self.parent_context.evaluator try: actual = _TYPE_ALIAS_TYPES[name] except KeyError: pass else: yield TypeAlias.create_cached(evaluator, self.parent_context, self.tree_name, actual) return if name in _PROXY_CLASS_TYPES: yield TypingClassContext.create_cached(evaluator, self.parent_context, self.tree_name) elif name in _PROXY_TYPES: yield TypingContext.create_cached(evaluator, self.parent_context, self.tree_name) elif name == 'runtime': # We don't want anything here, not sure what this function is # supposed to do, since it just appears in the stubs and shouldn't # have any effects there (because it's never executed). return elif name == 'TypeVar': yield TypeVarClass.create_cached(evaluator, self.parent_context, self.tree_name) elif name == 'Any': yield Any.create_cached(evaluator, self.parent_context, self.tree_name) elif name == 'TYPE_CHECKING': # This is needed for e.g. imports that are only available for type # checking or are in cycles. The user can then check this variable. yield builtin_from_name(evaluator, u'True') elif name == 'overload': yield OverloadFunction.create_cached(evaluator, self.parent_context, self.tree_name) elif name == 'NewType': yield NewTypeFunction.create_cached(evaluator, self.parent_context, self.tree_name) elif name == 'cast': # TODO implement cast yield CastFunction.create_cached(evaluator, self.parent_context, self.tree_name) elif name == 'TypedDict': # TODO doesn't even exist in typeshed/typing.py, yet. But will be # added soon. pass elif name in ('no_type_check', 'no_type_check_decorator'): # This is not necessary, as long as we are not doing type checking. for c in self._wrapped_name.infer(): # F**k my life Python 2 yield c else: # Everything else shouldn't be relevant for type checking. for c in self._wrapped_name.infer(): # F**k my life Python 2 yield c
def _execute_function(self, params): from jedi.evaluate import docstrings from jedi.evaluate.compiled import builtin_from_name if self.api_type != 'function': return for name in self._parse_function_doc()[1].split(): try: # TODO wtf is this? this is exactly the same as the thing # below. It uses getattr as well. self.evaluator.builtins_module.access_handle.getattr(name) except AttributeError: continue else: bltn_obj = builtin_from_name(self.evaluator, name) for result in bltn_obj.execute(params): yield result for type_ in docstrings.infer_return_types(self): yield type_
def get_return_values(self, check_yields=False): funcdef = self.tree_node if funcdef.type == 'lambdef': return self.eval_node(funcdef.children[-1]) if check_yields: context_set = NO_CONTEXTS returns = get_yield_exprs(self.evaluator, funcdef) else: returns = funcdef.iter_return_stmts() from jedi.evaluate.gradual.annotation import infer_return_types context_set = infer_return_types(self) if context_set: # If there are annotations, prefer them over anything else. # This will make it faster. return context_set context_set |= docstrings.infer_return_types(self.function_context) for r in returns: check = flow_analysis.reachability_check(self, funcdef, r) if check is flow_analysis.UNREACHABLE: debug.dbg('Return unreachable: %s', r) else: if check_yields: context_set |= ContextSet.from_sets( lazy_context.infer() for lazy_context in self._get_yield_lazy_context(r)) else: try: children = r.children except AttributeError: ctx = compiled.builtin_from_name( self.evaluator, u'None') context_set |= ContextSet([ctx]) else: context_set |= self.eval_node(children[1]) if check is flow_analysis.REACHABLE: debug.dbg('Return reachable: %s', r) break return context_set
def builtins_isinstance(evaluator, objects, types, arguments): bool_results = set() for o in objects: cls = o.py__class__() try: mro_func = cls.py__mro__ except AttributeError: # This is temporary. Everything should have a class attribute in # Python?! Maybe we'll leave it here, because some numpy objects or # whatever might not. bool_results = set([True, False]) break mro = mro_func() for cls_or_tup in types: if cls_or_tup.is_class(): bool_results.add(cls_or_tup in mro) elif cls_or_tup.name.string_name == 'tuple' \ and cls_or_tup.get_root_context() == evaluator.builtins_module: # Check for tuples. classes = ContextSet.from_sets( lazy_context.infer() for lazy_context in cls_or_tup.iterate() ) bool_results.add(any(cls in mro for cls in classes)) else: _, lazy_context = list(arguments.unpack())[1] if isinstance(lazy_context, LazyTreeContext): node = lazy_context.data message = 'TypeError: isinstance() arg 2 must be a ' \ 'class, type, or tuple of classes and types, ' \ 'not %s.' % cls_or_tup analysis.add(lazy_context._context, 'type-error-isinstance', node, message) return ContextSet.from_iterable( compiled.builtin_from_name(evaluator, force_unicode(str(b))) for b in bool_results )
def builtins_isinstance(objects, types, arguments, evaluator): bool_results = set() for o in objects: cls = o.py__class__() try: cls.py__bases__ except AttributeError: # This is temporary. Everything should have a class attribute in # Python?! Maybe we'll leave it here, because some numpy objects or # whatever might not. bool_results = set([True, False]) break mro = list(cls.py__mro__()) for cls_or_tup in types: if cls_or_tup.is_class(): bool_results.add(cls_or_tup in mro) elif cls_or_tup.name.string_name == 'tuple' \ and cls_or_tup.get_root_context() == evaluator.builtins_module: # Check for tuples. classes = ContextSet.from_sets( lazy_context.infer() for lazy_context in cls_or_tup.iterate() ) bool_results.add(any(cls in mro for cls in classes)) else: _, lazy_context = list(arguments.unpack())[1] if isinstance(lazy_context, LazyTreeContext): node = lazy_context.data message = 'TypeError: isinstance() arg 2 must be a ' \ 'class, type, or tuple of classes and types, ' \ 'not %s.' % cls_or_tup analysis.add(lazy_context.context, 'type-error-isinstance', node, message) return ContextSet( compiled.builtin_from_name(evaluator, force_unicode(str(b))) for b in bool_results )
def execute_annotation(self): string_name = self._tree_name.value if string_name == 'Union': # This is kind of a special case, because we have Unions (in Jedi # ContextSets). return self.gather_annotation_classes().execute_annotation() elif string_name == 'Optional': # Optional is basically just saying it's either None or the actual # type. return self.gather_annotation_classes().execute_annotation() \ | ContextSet([builtin_from_name(self.evaluator, u'None')]) elif string_name == 'Type': # The type is actually already given in the index_context return ContextSet([self._index_context]) elif string_name == 'ClassVar': # For now don't do anything here, ClassVars are always used. return self._index_context.execute_annotation() cls = globals()[string_name] return ContextSet([ cls(self.evaluator, self.parent_context, self._tree_name, self._index_context, self._context_of_index) ])
def _eval_element_not_cached(self, context, element): debug.dbg('eval_element %s@%s', element, element.start_pos) types = set() typ = element.type if typ in ('name', 'number', 'string', 'atom'): types = self.eval_atom(context, element) elif typ == 'keyword': # For False/True/None if element.value in ('False', 'True', 'None'): types.add(compiled.builtin_from_name(self, element.value)) # else: print e.g. could be evaluated like this in Python 2.7 elif typ == 'lambda': types = set([er.FunctionContext(self, context, element)]) elif typ == 'expr_stmt': types = self.eval_statement(context, element) elif typ in ('power', 'atom_expr'): first_child = element.children[0] if not (first_child.type == 'keyword' and first_child.value == 'await'): types = self.eval_atom(context, first_child) for trailer in element.children[1:]: if trailer == '**': # has a power operation. right = self.eval_element(context, element.children[2]) types = set( precedence.calculate(self, context, types, trailer, right)) break types = self.eval_trailer(context, types, trailer) elif typ in ( 'testlist_star_expr', 'testlist', ): # The implicit tuple in statements. types = set( [iterable.SequenceLiteralContext(self, context, element)]) elif typ in ('not_test', 'factor'): types = self.eval_element(context, element.children[-1]) for operator in element.children[:-1]: types = set(precedence.factor_calculate(self, types, operator)) elif typ == 'test': # `x if foo else y` case. types = (self.eval_element(context, element.children[0]) | self.eval_element(context, element.children[-1])) elif typ == 'operator': # Must be an ellipsis, other operators are not evaluated. assert element.value == '...' types = set([compiled.create(self, Ellipsis)]) elif typ == 'dotted_name': types = self.eval_atom(context, element.children[0]) for next_name in element.children[2::2]: # TODO add search_global=True? types = unite( typ.py__getattribute__(next_name, name_context=context) for typ in types) types = types elif typ == 'eval_input': types = self._eval_element_not_cached(context, element.children[0]) elif typ == 'annassign': types = pep0484._evaluate_for_annotation(context, element.children[1]) else: types = precedence.calculate_children(self, context, element.children) debug.dbg('eval_element result %s', types) return types
def eval_node(context, element): debug.dbg('eval_node %s@%s', element, element.start_pos) evaluator = context.evaluator typ = element.type if typ in ('name', 'number', 'string', 'atom', 'strings', 'keyword'): return eval_atom(context, element) 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] 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 = eval_atom(context, first_child) for trailer in children: if trailer == '**': # has a power operation. right = context.eval_node(children[1]) context_set = _eval_comparison( evaluator, context, context_set, trailer, right ) break context_set = eval_trailer(context, context_set, trailer) if had_await: await_context_set = context_set.py__getattribute__(u"__await__") if not await_context_set: debug.warning('Tried to run py__await__ on context %s', context) context_set = ContextSet() return _py__stop_iteration_returns(await_context_set.execute_evaluated()) 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 pep0484._evaluate_for_annotation(context, element.children[1]) 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) return _py__stop_iteration_returns(generators) # Generator.send() is not implemented. return NO_CONTEXTS else: return eval_or_test(context, element)
def _bool_to_context(evaluator, bool_): return compiled.builtin_from_name(evaluator, force_unicode(str(bool_)))
def get_object(self): compiled_obj = compiled.builtin_from_name(self.evaluator, self.array_type) only_obj, = compiled_obj.execute_evaluated(self) return only_obj
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__class__(self): return compiled.builtin_from_name(self.evaluator, self.array_type)
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? 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): ctx = compiled.builtin_from_name(self.parent_context.evaluator, u'str') return ctx.execute_evaluated()
def _get_wrapped_context(self): from jedi.evaluate.gradual.typing import GenericClass klass = compiled.builtin_from_name(self.evaluator, self.array_type) c, = GenericClass(klass, self._get_generics()).execute_annotation() return c
def __getattr__(self, name): if self._slice_object is None: context = compiled.builtin_from_name(self._context.evaluator, 'slice') self._slice_object, = context.execute_evaluated() return getattr(self._slice_object, name)
def py__stop_iteration_returns(self): return ContextSet(compiled.builtin_from_name(self.evaluator, u'None'))
def py__class__(self): # TODO this is obviously not correct, but at least gives us a class if # we have none. Some of these objects don't really have a base class in # typeshed. return builtin_from_name(self.evaluator, u'object')
def py__class__(self): return compiled.builtin_from_name(self.evaluator, u'type')
def test_next_docstr(evaluator): next_ = compiled.builtin_from_name(evaluator, u'next') assert next_.tree_node is not None assert next_.py__doc__() == '' # It's a stub for non_stub in stub_to_actual_context_set(next_): assert non_stub.py__doc__() == next.__doc__
def test_fake_docstr(evaluator): next_ = compiled.builtin_from_name(evaluator, u'next') assert next_.py__doc__() assert next_.tree_node is not None assert next_.py__doc__() == next.__doc__
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': if atom.value in ('True', 'False', 'None'): # Python 2... return ContextSet( [compiled.builtin_from_name(context.evaluator, atom.value)]) # This is the first global lookup. stmt = tree.search_ancestor(atom, 'expr_stmt', 'lambdef') or atom if stmt.type == 'lambdef': stmt = atom position = stmt.start_pos if _is_annotation_name(atom): # Since Python 3.7 (with from __future__ import annotations), # annotations are essentially strings and can reference objects # that are defined further down in code. Therefore just set the # position to None, so the finder will not try to stop at a certain # position in the module. position = None return context.py__getattribute__(name_or_str=atom, position=position, 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 elif atom.type == 'fstring': return compiled.get_string_context_set(context.evaluator) 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 in ('comp_for', 'sync_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 or '**' in array_node_c): context = iterable.DictLiteralContext(context.evaluator, context, atom) else: context = iterable.SequenceLiteralContext(context.evaluator, context, atom) return ContextSet([context])
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 elif typ == 'namedexpr_test': return eval_node(context, element.children[2]) else: return eval_or_test(context, element)
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] 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 = eval_atom(context, first_child) for trailer in children: if trailer == '**': # has a power operation. right = evaluator.eval_element(context, children[1]) context_set = _eval_comparison( evaluator, context, context_set, trailer, right ) break context_set = eval_trailer(context, context_set, trailer) if had_await: await_context_set = context_set.py__getattribute__(u"__await__") if not await_context_set: debug.warning('Tried to run py__await__ on context %s', context) context_set = ContextSet() return _py__stop_iteration_returns(await_context_set.execute_evaluated()) 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. assert element.value in ('.', '...'), "The unhandled operator %s" % repr(element.value) 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 pep0484._evaluate_for_annotation(context, element.children[1]) 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) return _py__stop_iteration_returns(generators) # Generator.send() is not implemented. return NO_CONTEXTS else: return eval_or_test(context, element)
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 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)) if atom.value == 'print': # print e.g. could be evaluated like this in Python 2.7 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)