Beispiel #1
0
 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()
Beispiel #2
0
 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()
Beispiel #3
0
    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()
Beispiel #4
0
    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()
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
    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.

        # 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
Beispiel #10
0
    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