(self)
Parses a python file taking out and categorizing imports.
Parses a python file taking out and categorizing imports.
Parses a python file taking out and categorizing imports .
def _parse(self):
        """Parses a python file taking out and categorizing imports."""
        self._in_quote = False
        self._in_top_comment = False
        while not self._at_end():
            raw_line = line = self._get_line()
            line = line.replace("from.import ", "from . import ")
            line = line.replace("\t", " ").replace('import*', 'import *')
            line = line.replace(" .import ", " . import ")
            statement_index = self.index
            skip_line = self._skip_line(line)

            if line in self._section_comments and not skip_line:
                if self.import_index == -1:
                    self.import_index = self.index - 1
                continue

            if "isort:imports-" in line and line.startswith("#"):
                section = line.split("isort:imports-")[-1].split()[0].upper()
                self.place_imports[section] = []
                self.import_placements[line] = section

            if ";" in line:
                for part in (part.strip() for part in line.split(";")):
                    if part and not part.startswith("from ") and not part.startswith("import "):
                        skip_line = True

            import_type = self._import_type(line)
            if not import_type or skip_line:
                self.out_lines.append(raw_line)
                continue

            for line in (line.strip() for line in line.split(";")):
                import_type = self._import_type(line)
                if not import_type:
                    self.out_lines.append(line)
                    continue

                if self.import_index == -1:
                    self.import_index = self.index - 1

                nested_comments = {}
                import_string, comments, new_comments = self._strip_comments(line)
                stripped_line = [part for part in self._strip_syntax(import_string).strip().split(" ") if part]
                if import_type == "from" and len(stripped_line) == 2 and stripped_line[1] != "*" and new_comments:
                    nested_comments[stripped_line[-1]] = comments[0]

                if "(" in line.split("#")[0] and not self._at_end():
                    while not line.strip().endswith(")") and not self._at_end():
                        line, comments, new_comments = self._strip_comments(self._get_line(), comments)
                        stripped_line = self._strip_syntax(line).strip()
                        if import_type == "from" and stripped_line and " " not in stripped_line and new_comments:
                            nested_comments[stripped_line] = comments[-1]
                        import_string += self.line_separator + line
                else:
                    while line.strip().endswith("\\"):
                        line, comments, new_comments = self._strip_comments(self._get_line(), comments)

                        # Still need to check for parentheses after an escaped line
                        if "(" in line.split("#")[0] and not self._at_end():
                            stripped_line = self._strip_syntax(line).strip()
                            if import_type == "from" and stripped_line and " " not in stripped_line and new_comments:
                                nested_comments[stripped_line] = comments[-1]
                            import_string += self.line_separator + line

                            while not line.strip().endswith(")") and not self._at_end():
                                line, comments, new_comments = self._strip_comments(self._get_line(), comments)
                                stripped_line = self._strip_syntax(line).strip()
                                if import_type == "from" and stripped_line and " " not in stripped_line and new_comments:
                                    nested_comments[stripped_line] = comments[-1]
                                import_string += self.line_separator + line

                        stripped_line = self._strip_syntax(line).strip()
                        if import_type == "from" and stripped_line and " " not in stripped_line and new_comments:
                            nested_comments[stripped_line] = comments[-1]
                        if import_string.strip().endswith(" import") or line.strip().startswith("import "):
                            import_string += self.line_separator + line
                        else:
                            import_string = import_string.rstrip().rstrip("\\") + " " + line.lstrip()

                if import_type == "from":
                    import_string = import_string.replace("import(", "import (")
                    parts = import_string.split(" import ")
                    from_import = parts[0].split(" ")
                    import_string = " import ".join([from_import[0] + " " + "".join(from_import[1:])] + parts[1:])

                imports = [item.replace("{|", "{ ").replace("|}", " }") for item in
                           self._strip_syntax(import_string).split()]
                if "as" in imports and (imports.index('as') + 1) < len(imports):
                    while "as" in imports:
                        index = imports.index('as')
                        if import_type == "from":
                            module = imports[0] + "." + imports[index - 1]
                            self.as_map[module] = imports[index + 1]
                        else:
                            module = imports[index - 1]
                            self.as_map[module] = imports[index + 1]
                        if not self.config['combine_as_imports']:
                            self.comments['straight'][module] = comments
                            comments = []
                        del imports[index:index + 2]
                if import_type == "from":
                    import_from = imports.pop(0)
                    placed_module = self.place_module(import_from)
                    if self.config['verbose']:
                        print("from-type place_module for %s returned %s" % (import_from, placed_module))
                    if placed_module == '':
                        print(
                            "WARNING: could not place module {0} of line {1} --"
                            " Do you need to define a default section?".format(import_from, line)
                        )
                    root = self.imports[placed_module][import_type]
                    for import_name in imports:
                        associated_comment = nested_comments.get(import_name)
                        if associated_comment:
                            self.comments['nested'].setdefault(import_from, {})[import_name] = associated_comment
                            comments.pop(comments.index(associated_comment))
                    if comments:
                        self.comments['from'].setdefault(import_from, []).extend(comments)

                    if len(self.out_lines) > max(self.import_index, self._first_comment_index_end + 1, 1) - 1:
                        last = self.out_lines and self.out_lines[-1].rstrip() or ""
                        while (last.startswith("#") and not last.endswith('"""') and not last.endswith("'''") and
                               'isort:imports-' not in last):
                            self.comments['above']['from'].setdefault(import_from, []).insert(0, self.out_lines.pop(-1))
                            if len(self.out_lines) > max(self.import_index - 1, self._first_comment_index_end + 1, 1) - 1:
                                last = self.out_lines[-1].rstrip()
                            else:
                                last = ""
                        if statement_index - 1 == self.import_index:
                            self.import_index -= len(self.comments['above']['from'].get(import_from, []))

                    if root.get(import_from, False):
                        root[import_from].update(imports)
                    else:
                        root[import_from] = OrderedSet(imports)
                else:
                    for module in imports:
                        if comments:
                            self.comments['straight'][module] = comments
                            comments = None

                        if len(self.out_lines) > max(self.import_index, self._first_comment_index_end + 1, 1) - 1:

                            last = self.out_lines and self.out_lines[-1].rstrip() or ""
                            while (last.startswith("#") and not last.endswith('"""') and not last.endswith("'''") and
                                   'isort:imports-' not in last):
                                self.comments['above']['straight'].setdefault(module, []).insert(0,
                                                                                                 self.out_lines.pop(-1))
                                if len(self.out_lines) > 0:
                                    last = self.out_lines[-1].rstrip()
                                else:
                                    last = ""
                            if self.index - 1 == self.import_index:
                                self.import_index -= len(self.comments['above']['straight'].get(module, []))
                        placed_module = self.place_module(module)
                        if self.config['verbose']:
                            print("else-type place_module for %s returned %s" % (module, placed_module))
                        if placed_module == '':
                            print(
                                "WARNING: could not place module {0} of line {1} --"
                                " Do you need to define a default section?".format(import_from, line)
                            )
                        self.imports[placed_module][import_type].add(module)
def _parse ( self ) : self . _in_quote = False self . _in_top_comment = False while not self . _at_end ( ) : raw_line = line = self . _get_line ( ) line = line . replace ( "from.import " , "from . import " ) line = line . replace ( "\t" , " " ) . replace ( 'import*' , 'import *' ) line = line . replace ( " .import " , " . import " ) statement_index = self . index skip_line = self . _skip_line ( line ) if line in self . _section_comments and not skip_line : if self . import_index == - 1 : self . import_index = self . index - 1 continue if "isort:imports-" in line and line . startswith ( "#" ) : section = line . split ( "isort:imports-" ) [ - 1 ] . split ( ) [ 0 ] . upper ( ) self . place_imports [ section ] = [ ] self . import_placements [ line ] = section if ";" in line : for part in ( part . strip ( ) for part in line . split ( ";" ) ) : if part and not part . startswith ( "from " ) and not part . startswith ( "import " ) : skip_line = True import_type = self . _import_type ( line ) if not import_type or skip_line : self . out_lines . append ( raw_line ) continue for line in ( line . strip ( ) for line in line . split ( ";" ) ) : import_type = self . _import_type ( line ) if not import_type : self . out_lines . append ( line ) continue if self . import_index == - 1 : self . import_index = self . index - 1 nested_comments = { } import_string , comments , new_comments = self . _strip_comments ( line ) stripped_line = [ part for part in self . _strip_syntax ( import_string ) . strip ( ) . split ( " " ) if part ] if import_type == "from" and len ( stripped_line ) == 2 and stripped_line [ 1 ] != "*" and new_comments : nested_comments [ stripped_line [ - 1 ] ] = comments [ 0 ] if "(" in line . split ( "#" ) [ 0 ] and not self . _at_end ( ) : while not line . strip ( ) . endswith ( ")" ) and not self . _at_end ( ) : line , comments , new_comments = self . _strip_comments ( self . _get_line ( ) , comments ) stripped_line = self . _strip_syntax ( line ) . strip ( ) if import_type == "from" and stripped_line and " " not in stripped_line and new_comments : nested_comments [ stripped_line ] = comments [ - 1 ] import_string += self . line_separator + line else : while line . strip ( ) . endswith ( "\\" ) : line , comments , new_comments = self . _strip_comments ( self . _get_line ( ) , comments ) # Still need to check for parentheses after an escaped line if "(" in line . split ( "#" ) [ 0 ] and not self . _at_end ( ) : stripped_line = self . _strip_syntax ( line ) . strip ( ) if import_type == "from" and stripped_line and " " not in stripped_line and new_comments : nested_comments [ stripped_line ] = comments [ - 1 ] import_string += self . line_separator + line while not line . strip ( ) . endswith ( ")" ) and not self . _at_end ( ) : line , comments , new_comments = self . _strip_comments ( self . _get_line ( ) , comments ) stripped_line = self . _strip_syntax ( line ) . strip ( ) if import_type == "from" and stripped_line and " " not in stripped_line and new_comments : nested_comments [ stripped_line ] = comments [ - 1 ] import_string += self . line_separator + line stripped_line = self . _strip_syntax ( line ) . strip ( ) if import_type == "from" and stripped_line and " " not in stripped_line and new_comments : nested_comments [ stripped_line ] = comments [ - 1 ] if import_string . strip ( ) . endswith ( " import" ) or line . strip ( ) . startswith ( "import " ) : import_string += self . line_separator + line else : import_string = import_string . rstrip ( ) . rstrip ( "\\" ) + " " + line . lstrip ( ) if import_type == "from" : import_string = import_string . replace ( "import(" , "import (" ) parts = import_string . split ( " import " ) from_import = parts [ 0 ] . split ( " " ) import_string = " import " . join ( [ from_import [ 0 ] + " " + "" . join ( from_import [ 1 : ] ) ] + parts [ 1 : ] ) imports = [ item . replace ( "{|" , "{ " ) . replace ( "|}" , " }" ) for item in self . _strip_syntax ( import_string ) . split ( ) ] if "as" in imports and ( imports . index ( 'as' ) + 1 ) < len ( imports ) : while "as" in imports : index = imports . index ( 'as' ) if import_type == "from" : module = imports [ 0 ] + "." + imports [ index - 1 ] self . as_map [ module ] = imports [ index + 1 ] else : module = imports [ index - 1 ] self . as_map [ module ] = imports [ index + 1 ] if not self . config [ 'combine_as_imports' ] : self . comments [ 'straight' ] [ module ] = comments comments = [ ] del imports [ index : index + 2 ] if import_type == "from" : import_from = imports . pop ( 0 ) placed_module = self . place_module ( import_from ) if self . config [ 'verbose' ] : print ( "from-type place_module for %s returned %s" % ( import_from , placed_module ) ) if placed_module == '' : print ( "WARNING: could not place module {0} of line {1} --" " Do you need to define a default section?" . format ( import_from , line ) ) root = self . imports [ placed_module ] [ import_type ] for import_name in imports : associated_comment = nested_comments . get ( import_name ) if associated_comment : self . comments [ 'nested' ] . setdefault ( import_from , { } ) [ import_name ] = associated_comment comments . pop ( comments . index ( associated_comment ) ) if comments : self . comments [ 'from' ] . setdefault ( import_from , [ ] ) . extend ( comments ) if len ( self . out_lines ) > max ( self . import_index , self . _first_comment_index_end + 1 , 1 ) - 1 : last = self . out_lines and self . out_lines [ - 1 ] . rstrip ( ) or "" while ( last . startswith ( "#" ) and not last . endswith ( '"""' ) and not last . endswith ( "'''" ) and 'isort:imports-' not in last ) : self . comments [ 'above' ] [ 'from' ] . setdefault ( import_from , [ ] ) . insert ( 0 , self . out_lines . pop ( - 1 ) ) if len ( self . out_lines ) > max ( self . import_index - 1 , self . _first_comment_index_end + 1 , 1 ) - 1 : last = self . out_lines [ - 1 ] . rstrip ( ) else : last = "" if statement_index - 1 == self . import_index : self . import_index -= len ( self . comments [ 'above' ] [ 'from' ] . get ( import_from , [ ] ) ) if root . get ( import_from , False ) : root [ import_from ] . update ( imports ) else : root [ import_from ] = OrderedSet ( imports ) else : for module in imports : if comments : self . comments [ 'straight' ] [ module ] = comments comments = None if len ( self . out_lines ) > max ( self . import_index , self . _first_comment_index_end + 1 , 1 ) - 1 : last = self . out_lines and self . out_lines [ - 1 ] . rstrip ( ) or "" while ( last . startswith ( "#" ) and not last . endswith ( '"""' ) and not last . endswith ( "'''" ) and 'isort:imports-' not in last ) : self . comments [ 'above' ] [ 'straight' ] . setdefault ( module , [ ] ) . insert ( 0 , self . out_lines . pop ( - 1 ) ) if len ( self . out_lines ) > 0 : last = self . out_lines [ - 1 ] . rstrip ( ) else : last = "" if self . index - 1 == self . import_index : self . import_index -= len ( self . comments [ 'above' ] [ 'straight' ] . get ( module , [ ] ) ) placed_module = self . place_module ( module ) if self . config [ 'verbose' ] : print ( "else-type place_module for %s returned %s" % ( module , placed_module ) ) if placed_module == '' : print ( "WARNING: could not place module {0} of line {1} --" " Do you need to define a default section?" . format ( import_from , line ) ) self . imports [ placed_module ] [ import_type ] . add ( module )