def to_stub(context): if context.is_stub(): return ContextSet([context]) was_instance = context.is_instance() if was_instance: context = context.py__class__() qualified_names = context.get_qualified_names() stub_module = _load_stub_module(context.get_root_context()) if stub_module is None or qualified_names is None: return NO_CONTEXTS was_bound_method = context.is_bound_method() if was_bound_method: # Infer the object first. We can infer the method later. method_name = qualified_names[-1] qualified_names = qualified_names[:-1] was_instance = True stub_contexts = ContextSet([stub_module]) for name in qualified_names: stub_contexts = stub_contexts.py__getattribute__(name) if was_instance: stub_contexts = ContextSet.from_sets(c.execute_evaluated() for c in stub_contexts if c.is_class()) if was_bound_method: # Now that the instance has been properly created, we can simply get # the method. stub_contexts = stub_contexts.py__getattribute__(method_name) return stub_contexts
def _python_to_stub_names(names, fallback_to_python=False): for name in names: module = name.get_root_context() if module.is_stub(): yield name continue name_list = name.get_qualified_names() stubs = NO_CONTEXTS if name_list is not None: stub_module = _load_stub_module(module) if stub_module is not None: stubs = ContextSet({stub_module}) for name in name_list[:-1]: stubs = stubs.py__getattribute__(name) if stubs and name_list: new_names = stubs.py__getattribute__(name_list[-1], is_goto=True) for new_name in new_names: yield new_name if new_names: continue elif stubs: for c in stubs: yield c.name continue if fallback_to_python: # This is the part where if we haven't found anything, just return # the stub name. yield name
def _to_stub(context): if context.is_stub(): return ContextSet([context]) was_instance = context.is_instance() if was_instance: context = context.py__class__() qualified_names = context.get_qualified_names() stub_module = _load_stub_module(context.get_root_context()) if stub_module is None or qualified_names is None: return NO_CONTEXTS stub_contexts = ContextSet([stub_module]) for name in qualified_names: stub_contexts = stub_contexts.py__getattribute__(name) if was_instance: stub_contexts = ContextSet.from_sets(c.execute_evaluated() for c in stub_contexts if c.is_class()) return stub_contexts
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 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.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 = 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)