def visit_func_def(self, func: FuncDef) -> None: sem = self.sem if sem.type is not None: # Don't process methods during pass 1. return func.is_conditional = sem.block_depth[-1] > 0 func._fullname = sem.qualified_name(func.name()) at_module = sem.is_module_scope() if at_module and func.name() in sem.globals: # Already defined in this module. original_sym = sem.globals[func.name()] if (original_sym.kind == UNBOUND_IMPORTED or isinstance(original_sym.node, ImportedName)): # Ah this is an imported name. We can't resolve them now, so we'll postpone # this until the main phase of semantic analysis. return if not sem.set_original_def(original_sym.node, func): # Report error. sem.check_no_global(func.name(), func) else: if at_module: sem.globals[func.name()] = SymbolTableNode(GDEF, func) # Also analyze the function body (needed in case there are unreachable # conditional imports). sem.function_stack.append(func) sem.scope.enter_function(func) sem.enter() func.body.accept(self) sem.leave() sem.scope.leave() sem.function_stack.pop()
def visit_func_def(self, func: FuncDef) -> None: sem = self.sem func.is_conditional = sem.block_depth[-1] > 0 func._fullname = sem.qualified_name(func.name()) at_module = sem.is_module_scope() if at_module and func.name() in sem.globals: # Already defined in this module. original_sym = sem.globals[func.name()] if original_sym.kind == UNBOUND_IMPORTED: # Ah this is an imported name. We can't resolve them now, so we'll postpone # this until the main phase of semantic analysis. return if not sem.set_original_def(original_sym.node, func): # Report error. sem.check_no_global(func.name(), func) else: if at_module: sem.globals[func.name()] = SymbolTableNode(GDEF, func) # Also analyze the function body (in case there are conditional imports). sem.function_stack.append(func) sem.errors.push_function(func.name()) sem.enter() func.body.accept(self) sem.leave() sem.errors.pop_function() sem.function_stack.pop()
def visit_func_def(self, func: FuncDef, decorated: bool = False) -> None: """Process a func def. decorated is true if we are processing a func def in a Decorator that needs a _fullname and to have its body analyzed but does not need to be added to the symbol table. """ sem = self.sem if sem.type is not None: # Don't process methods during pass 1. return func.is_conditional = sem.block_depth[-1] > 0 func._fullname = sem.qualified_name(func.name()) at_module = sem.is_module_scope() and not decorated if (at_module and func.name() == '__getattr__' and self.sem.cur_mod_node.is_package_init_file() and self.sem.cur_mod_node.is_stub): if isinstance(func.type, CallableType): ret = func.type.ret_type if isinstance(ret, UnboundType) and not ret.args: sym = self.sem.lookup_qualified(ret.name, func, suppress_errors=True) # We only interpret a package as partial if the __getattr__ return type # is either types.ModuleType of Any. if sym and sym.node and sym.node.fullname() in ( 'types.ModuleType', 'typing.Any'): self.sem.cur_mod_node.is_partial_stub_package = True if at_module and func.name() in sem.globals: # Already defined in this module. original_sym = sem.globals[func.name()] if (original_sym.kind == UNBOUND_IMPORTED or isinstance(original_sym.node, ImportedName)): # Ah this is an imported name. We can't resolve them now, so we'll postpone # this until the main phase of semantic analysis. return if not sem.set_original_def(original_sym.node, func): # Report error. sem.check_no_global(func.name(), func) else: if at_module: sem.globals[func.name()] = SymbolTableNode(GDEF, func) # Also analyze the function body (needed in case there are unreachable # conditional imports). sem.function_stack.append(func) sem.scope.enter_function(func) sem.enter() func.body.accept(self) sem.leave() sem.scope.leave() sem.function_stack.pop()
def visit_func_def(self, func: FuncDef, decorated: bool = False) -> None: """Process a func def. decorated is true if we are processing a func def in a Decorator that needs a _fullname and to have its body analyzed but does not need to be added to the symbol table. """ sem = self.sem if sem.type is not None: # Don't process methods during pass 1. return func.is_conditional = sem.block_depth[-1] > 0 func._fullname = sem.qualified_name(func.name()) at_module = sem.is_module_scope() and not decorated if (at_module and func.name() == '__getattr__' and self.sem.cur_mod_node.is_package_init_file() and self.sem.cur_mod_node.is_stub): if isinstance(func.type, CallableType): ret = func.type.ret_type if isinstance(ret, UnboundType) and not ret.args: sym = self.sem.lookup_qualified(ret.name, func, suppress_errors=True) # We only interpret a package as partial if the __getattr__ return type # is either types.ModuleType of Any. if sym and sym.node and sym.node.fullname() in ('types.ModuleType', 'typing.Any'): self.sem.cur_mod_node.is_partial_stub_package = True if at_module and func.name() in sem.globals: # Already defined in this module. original_sym = sem.globals[func.name()] if (original_sym.kind == UNBOUND_IMPORTED or isinstance(original_sym.node, ImportedName)): # Ah this is an imported name. We can't resolve them now, so we'll postpone # this until the main phase of semantic analysis. return if not sem.set_original_def(original_sym.node, func): # Report error. sem.check_no_global(func.name(), func) else: if at_module: sem.globals[func.name()] = SymbolTableNode(GDEF, func) # Also analyze the function body (needed in case there are unreachable # conditional imports). sem.function_stack.append(func) sem.scope.enter_function(func) sem.enter() func.body.accept(self) sem.leave() sem.scope.leave() sem.function_stack.pop()
def visit_func_def(self, node: FuncDef) -> FuncDef: # Note that a FuncDef must be transformed to a FuncDef. new = FuncDef(node.name(), [self.visit_var(var) for var in node.args], node.arg_kinds[:], [None] * len(node.init), self.block(node.body), self.optional_type(node.type)) self.copy_function_attributes(new, node) new._fullname = node._fullname new.is_decorated = node.is_decorated new.is_conditional = node.is_conditional new.is_abstract = node.is_abstract new.is_static = node.is_static new.is_property = node.is_property new.original_def = node.original_def return new
def visit_func_def(self, node: FuncDef) -> FuncDef: # Note that a FuncDef must be transformed to a FuncDef. new = FuncDef(node.name(), [self.copy_argument(arg) for arg in node.arguments], self.block(node.body), cast(FunctionLike, self.optional_type(node.type))) self.copy_function_attributes(new, node) new._fullname = node._fullname new.is_decorated = node.is_decorated new.is_conditional = node.is_conditional new.is_abstract = node.is_abstract new.is_static = node.is_static new.is_class = node.is_class new.is_property = node.is_property new.original_def = node.original_def return new
def visit_func_def(self, node: FuncDef) -> FuncDef: # Note that a FuncDef must be transformed to a FuncDef. # These contortions are needed to handle the case of recursive # references inside the function being transformed. # Set up placeholder nodes for references within this function # to other functions defined inside it. # Don't create an entry for this function itself though, # since we want self-references to point to the original # function if this is the top-level node we are transforming. init = FuncMapInitializer(self) for stmt in node.body.body: stmt.accept(init) new = FuncDef(node.name, [self.copy_argument(arg) for arg in node.arguments], self.block(node.body), cast(Optional[FunctionLike], self.optional_type(node.type))) self.copy_function_attributes(new, node) new._fullname = node._fullname new.is_decorated = node.is_decorated new.is_conditional = node.is_conditional new.is_abstract = node.is_abstract new.is_static = node.is_static new.is_class = node.is_class new.is_property = node.is_property new.is_final = node.is_final new.original_def = node.original_def if node in self.func_placeholder_map: # There is a placeholder definition for this function. Replace # the attributes of the placeholder with those form the transformed # function. We know that the classes will be identical (otherwise # this wouldn't work). result = self.func_placeholder_map[node] replace_object_state(result, new) return result else: return new
def visit_func_def(self, node: FuncDef) -> FuncDef: # Note that a FuncDef must be transformed to a FuncDef. # These contortions are needed to handle the case of recursive # references inside the function being transformed. # Set up placeholder nodes for references within this function # to other functions defined inside it. # Don't create an entry for this function itself though, # since we want self-references to point to the original # function if this is the top-level node we are transforming. init = FuncMapInitializer(self) for stmt in node.body.body: stmt.accept(init) new = FuncDef(node.name(), [self.copy_argument(arg) for arg in node.arguments], self.block(node.body), cast(Optional[FunctionLike], self.optional_type(node.type))) self.copy_function_attributes(new, node) new._fullname = node._fullname new.is_decorated = node.is_decorated new.is_conditional = node.is_conditional new.is_abstract = node.is_abstract new.is_static = node.is_static new.is_class = node.is_class new.is_property = node.is_property new.is_final = node.is_final new.original_def = node.original_def if node in self.func_placeholder_map: # There is a placeholder definition for this function. Replace # the attributes of the placeholder with those form the transformed # function. We know that the classes will be identical (otherwise # this wouldn't work). result = self.func_placeholder_map[node] replace_object_state(result, new) return result else: return new