Beispiel #1
0
def remove_duplicated_imports(partitions):
    seen = set()
    seen_module_names = set()
    without_exact_duplicates = []

    for partition in partitions:
        if partition.code_type is CodeType.IMPORT:
            import_obj = import_obj_from_str(partition.src)
            if import_obj not in seen:
                seen.add(import_obj)
                if (isinstance(import_obj, ImportImport)
                        and not import_obj.import_statement.asname):
                    seen_module_names.update(
                        _module_to_base_modules(
                            import_obj.import_statement.module, ), )
                without_exact_duplicates.append(partition)
        else:
            without_exact_duplicates.append(partition)

    partitions = []
    for partition in without_exact_duplicates:
        if partition.code_type is CodeType.IMPORT:
            import_obj = import_obj_from_str(partition.src)
            if (isinstance(import_obj, ImportImport)
                    and not import_obj.import_statement.asname and
                    import_obj.import_statement.module in seen_module_names):
                continue
        partitions.append(partition)

    return partitions
Beispiel #2
0
def _validate_import(s: str) -> str:
    try:
        import_obj_from_str(s)
    except (SyntaxError, KeyError):
        raise argparse.ArgumentTypeError(f'expected import: {s!r}')
    else:
        return s
def remove_duplicated_imports(partitions):
    # type: (Iterable[CodePartition]) -> List[CodePartition]
    seen = set()  # type: Set[AbstractImportObj]
    seen_module_names = set()  # type: Set[str]
    without_exact_duplicates = []

    for partition in partitions:
        if partition.code_type is CodeType.IMPORT:
            import_obj = import_obj_from_str(partition.src)
            if import_obj not in seen:
                seen.add(import_obj)
                if (isinstance(import_obj, ImportImport)
                        and not import_obj.import_statement.asname):
                    seen_module_names.update(
                        _module_to_base_modules(
                            import_obj.import_statement.module, ), )
                without_exact_duplicates.append(partition)
        else:
            without_exact_duplicates.append(partition)

    out_partitions = []
    for partition in without_exact_duplicates:
        if partition.code_type is CodeType.IMPORT:
            import_obj = import_obj_from_str(partition.src)
            if (isinstance(import_obj, ImportImport)
                    and not import_obj.import_statement.asname and
                    import_obj.import_statement.module in seen_module_names):
                continue
        out_partitions.append(partition)

    return out_partitions
Beispiel #4
0
def _validate_import(s):
    try:
        import_obj_from_str(s)
    except (SyntaxError, KeyError):
        raise argparse.ArgumentTypeError('expected import: {!r}'.format(s))
    else:
        return s
 def _inner():
     # type: () -> Generator[CodePartition, None, None]
     for partition in partitions:
         if (partition.code_type is not CodeType.IMPORT
                 or import_obj_from_str(
                     partition.src) not in to_remove_imports):
             yield partition
Beispiel #6
0
    def _inner():
        for partition in partitions:
            if partition.code_type is CodeType.IMPORT:
                import_obj = import_obj_from_str(partition.src)

                # cannot rewrite import-imports: makes undefined names
                if isinstance(import_obj, ImportImport):
                    yield partition
                    continue

                mod_parts = import_obj.import_statement.module.split('.')
                symbol = import_obj.import_statement.symbol
                asname = import_obj.import_statement.asname

                for orig_mod, new_mod, attr in to_replace:
                    if ((attr == symbol and mod_parts == orig_mod) or
                        (not attr and _mod_startswith(mod_parts, orig_mod))):
                        mod_parts[:len(orig_mod)] = new_mod
                        import_obj.ast_obj.module = '.'.join(mod_parts)
                        new_src = import_obj.to_text()
                        yield partition._replace(src=new_src)
                        break
                    # from x.y import z => import z
                    elif (not attr and mod_parts + [symbol] == orig_mod
                          and len(new_mod) == 1):
                        mod_name, = new_mod
                        asname_src = ' as {}'.format(asname) if asname else ''
                        new_src = 'import {}{}\n'.format(mod_name, asname_src)
                        yield partition._replace(src=new_src)
                        break
                else:
                    yield partition
            else:
                yield partition
Beispiel #7
0
 def _inner():
     for partition in partitions:
         if (
                 partition.code_type is not CodeType.IMPORT or
                 import_obj_from_str(partition.src) not in to_remove_imports
         ):
             yield partition
Beispiel #8
0
 def _inner():
     seen = set()
     for partition in partitions:
         if partition.code_type is CodeType.IMPORT:
             import_obj = import_obj_from_str(partition.src)
             if import_obj not in seen:
                 seen.add(import_obj)
                 yield partition
         else:
             yield partition
Beispiel #9
0
 def _inner():
     seen = set()
     for partition in partitions:
         if partition.code_type is CodeType.IMPORT:
             import_obj = import_obj_from_str(partition.src)
             if import_obj not in seen:
                 seen.add(import_obj)
                 yield partition
         else:
             yield partition
Beispiel #10
0
def remove_imports(partitions, to_remove=()):
    to_remove_imports = set(
        import_obj_from_str(imp_statement) for imp_statement in to_remove)

    def _inner():
        for partition in partitions:
            if (partition.code_type is not CodeType.IMPORT
                    or import_obj_from_str(
                        partition.src) not in to_remove_imports):
                yield partition

    return list(_inner())
Beispiel #11
0
 def _inner():
     for partition in partitions:
         if partition.code_type is CodeType.IMPORT:
             import_obj = import_obj_from_str(partition.src)
             if import_obj.has_multiple_imports:
                 for new_import_obj in import_obj.split_imports():
                     yield CodePartition(CodeType.IMPORT,
                                         new_import_obj.to_text())
             else:
                 yield partition
         else:
             yield partition
Beispiel #12
0
 def _inner():
     for partition in partitions:
         if partition.code_type is CodeType.IMPORT:
             import_obj = import_obj_from_str(partition.src)
             if import_obj.has_multiple_imports:
                 for new_import_obj in import_obj.split_imports():
                     yield CodePartition(
                         CodeType.IMPORT, new_import_obj.to_text()
                     )
             else:
                 yield partition
         else:
             yield partition
Beispiel #13
0
def remove_imports(partitions, to_remove=()):
    to_remove_imports = set()
    for s in to_remove:
        to_remove_imports.update(import_obj_from_str(s).split_imports())

    def _inner():
        for partition in partitions:
            if (partition.code_type is not CodeType.IMPORT
                    or import_obj_from_str(
                        partition.src) not in to_remove_imports):
                yield partition

    return list(_inner())
Beispiel #14
0
def remove_imports(partitions, to_remove=()):
    to_remove_imports = set(
        import_obj_from_str(imp_statement) for imp_statement in to_remove
    )

    def _inner():
        for partition in partitions:
            if (
                    partition.code_type is not CodeType.IMPORT or
                    import_obj_from_str(partition.src) not in to_remove_imports
            ):
                yield partition

    return list(_inner())
Beispiel #15
0
def apply_import_sorting(partitions, **sort_kwargs):
    pre_import_code = []
    imports = []
    trash = []
    rest = []
    for partition in partitions:
        {
            CodeType.PRE_IMPORT_CODE: pre_import_code,
            CodeType.IMPORT: imports,
            CodeType.NON_CODE: trash,
            CodeType.CODE: rest,
        }[partition.code_type].append(partition)

    # Need to give an import a newline if it doesn't have one (needed for no
    # EOL)
    imports = [
        partition if partition.src.endswith('\n') else
        CodePartition(CodeType.IMPORT, partition.src + '\n')
        for partition in imports
    ]

    import_obj_to_partition = dict(
        (import_obj_from_str(partition.src), partition)
        for partition in imports
    )

    new_imports = []
    sorted_blocks = sort(import_obj_to_partition.keys(), **sort_kwargs)
    for block in sorted_blocks:
        for import_obj in block:
            new_imports.append(import_obj_to_partition[import_obj])
        new_imports.append(CodePartition(CodeType.NON_CODE, '\n'))
    # XXX: I want something like [x].join(...) (like str join) but for now
    # this works
    if new_imports:
        new_imports.pop()

    # There's the potential that we moved a bunch of whitespace onto the
    # beginning of the rest of the code.  To fix this, we're going to combine
    # all of that code, and then make sure there are two linebreaks to start
    restsrc = _partitions_to_src(rest)
    restsrc = restsrc.rstrip()
    if restsrc:
        rest = [
            CodePartition(CodeType.CODE, restsrc + '\n'),
        ]
    else:
        rest = []

    return pre_import_code + new_imports + rest
def remove_imports(partitions, to_remove=()):
    # type: (Iterable[CodePartition], Tuple[str, ...]) -> List[CodePartition]
    to_remove_imports = set()  # type: Set[AbstractImportObj]
    for s in to_remove:
        to_remove_imports.update(import_obj_from_str(s).split_imports())

    def _inner():
        # type: () -> Generator[CodePartition, None, None]
        for partition in partitions:
            if (partition.code_type is not CodeType.IMPORT
                    or import_obj_from_str(
                        partition.src) not in to_remove_imports):
                yield partition

    return list(_inner())
Beispiel #17
0
def apply_import_sorting(partitions, **sort_kwargs):
    pre_import_code = []
    imports = []
    trash = []
    rest = []
    for partition in partitions:
        {
            CodeType.PRE_IMPORT_CODE: pre_import_code,
            CodeType.IMPORT: imports,
            CodeType.NON_CODE: trash,
            CodeType.CODE: rest,
        }[partition.code_type].append(partition)

    # Need to give an import a newline if it doesn't have one (needed for no
    # EOL)
    imports = [
        partition if partition.src.endswith('\n') else CodePartition(
            CodeType.IMPORT, partition.src + '\n') for partition in imports
    ]

    import_obj_to_partition = dict(
        (import_obj_from_str(partition.src), partition)
        for partition in imports)

    new_imports = []
    sorted_blocks = sort(import_obj_to_partition.keys(), **sort_kwargs)
    for block in sorted_blocks:
        for import_obj in block:
            new_imports.append(import_obj_to_partition[import_obj])
        new_imports.append(CodePartition(CodeType.NON_CODE, '\n'))
    # XXX: I want something like [x].join(...) (like str join) but for now
    # this works
    if new_imports:
        new_imports.pop()

    # There's the potential that we moved a bunch of whitespace onto the
    # beginning of the rest of the code.  To fix this, we're going to combine
    # all of that code, and then make sure there are two linebreaks to start
    restsrc = _partitions_to_src(rest)
    restsrc = restsrc.rstrip()
    if restsrc:
        rest = [
            CodePartition(CodeType.CODE, restsrc + '\n'),
        ]
    else:
        rest = []

    return pre_import_code + new_imports + rest
def apply_import_sorting(
        partitions,
        separate_relative=False,
        separate_from_import=False,
        **sort_kwargs
):
    pre_import_code = []
    imports = []
    trash = []
    rest = []
    for partition in partitions:
        {
            CodeType.PRE_IMPORT_CODE: pre_import_code,
            CodeType.IMPORT: imports,
            CodeType.NON_CODE: trash,
            CodeType.CODE: rest,
        }[partition.code_type].append(partition)

    # Need to give an import a newline if it doesn't have one (needed for no
    # EOL)
    imports = [
        partition if partition.src.endswith('\n') else
        CodePartition(CodeType.IMPORT, partition.src + '\n')
        for partition in imports
    ]

    import_obj_to_partition = dict(
        (import_obj_from_str(partition.src), partition)
        for partition in imports
    )

    new_imports = []
    relative_imports = []

    def _import_type_switches(last_import_obj, import_obj):
        """Returns True if separate_from_import is True and  `import_obj` is
        :class:`aspy.refactor_imports.import_obj.FromImport`
        and ``last_import_obj`` is
        :class:`aspy.refactor_imports.import_obj.ImportImport`
        """
        return (
            separate_from_import and
            last_import_obj is not None and
            type(last_import_obj) is not type(import_obj)
        )

    sorted_blocks = sort(import_obj_to_partition.keys(), **sort_kwargs)
    for block in sorted_blocks:
        last_import_obj = None

        for import_obj in block:
            if separate_relative and import_obj.is_explicit_relative:
                relative_imports.append(import_obj_to_partition[import_obj])
            else:
                if _import_type_switches(last_import_obj, import_obj):
                    new_imports.append(CodePartition(CodeType.NON_CODE, '\n'))

                last_import_obj = import_obj
                new_imports.append(import_obj_to_partition[import_obj])

        # There's an edge case if both --separate-relative and
        # --separate-from-import are passed where the first-party imports
        # will *all* be explicit relative imports and sorted into the special
        # block.  In this case, we don't want the first-party block to just
        # be a single newline.  See #23
        if last_import_obj is not None:
            new_imports.append(CodePartition(CodeType.NON_CODE, '\n'))

    if relative_imports:
        relative_imports.insert(0, CodePartition(CodeType.NON_CODE, '\n'))
    # XXX: I want something like [x].join(...) (like str join) but for now
    # this works
    if new_imports:
        new_imports.pop()

    # There's the potential that we moved a bunch of whitespace onto the
    # beginning of the rest of the code.  To fix this, we're going to combine
    # all of that code, and then make sure there are two linebreaks to start
    restsrc = _partitions_to_src(rest)
    restsrc = restsrc.rstrip()
    if restsrc:
        rest = [
            CodePartition(CodeType.CODE, restsrc + '\n'),
        ]
    else:
        rest = []

    return pre_import_code + new_imports + relative_imports + rest
Beispiel #19
0
def apply_import_sorting(partitions,
                         separate_relative=False,
                         separate_from_import=False,
                         **sort_kwargs):
    pre_import_code = []
    imports = []
    trash = []
    rest = []
    for partition in partitions:
        {
            CodeType.PRE_IMPORT_CODE: pre_import_code,
            CodeType.IMPORT: imports,
            CodeType.NON_CODE: trash,
            CodeType.CODE: rest,
        }[partition.code_type].append(partition)

    # Need to give an import a newline if it doesn't have one (needed for no
    # EOL)
    imports = [
        partition if partition.src.endswith('\n') else CodePartition(
            CodeType.IMPORT, partition.src + '\n') for partition in imports
    ]

    import_obj_to_partition = {
        import_obj_from_str(partition.src): partition
        for partition in imports
    }

    new_imports = []
    relative_imports = []

    def _import_type_switches(last_import_obj, import_obj):
        """Returns True if separate_from_import is True and  `import_obj` is
        :class:`aspy.refactor_imports.import_obj.FromImport`
        and ``last_import_obj`` is
        :class:`aspy.refactor_imports.import_obj.ImportImport`
        """
        return (separate_from_import and last_import_obj is not None
                and type(last_import_obj) is not type(import_obj))

    sorted_blocks = sort(import_obj_to_partition.keys(), **sort_kwargs)
    for block in sorted_blocks:
        last_import_obj = None

        for import_obj in block:
            if separate_relative and import_obj.is_explicit_relative:
                relative_imports.append(import_obj_to_partition[import_obj])
            else:
                if _import_type_switches(last_import_obj, import_obj):
                    new_imports.append(CodePartition(CodeType.NON_CODE, '\n'))

                last_import_obj = import_obj
                new_imports.append(import_obj_to_partition[import_obj])

        # There's an edge case if both --separate-relative and
        # --separate-from-import are passed where the first-party imports
        # will *all* be explicit relative imports and sorted into the special
        # block.  In this case, we don't want the first-party block to just
        # be a single newline.  See #23
        if last_import_obj is not None:
            new_imports.append(CodePartition(CodeType.NON_CODE, '\n'))

    if relative_imports:
        relative_imports.insert(0, CodePartition(CodeType.NON_CODE, '\n'))
    # XXX: I want something like [x].join(...) (like str join) but for now
    # this works
    if new_imports:
        new_imports.pop()

    # There's the potential that we moved a bunch of whitespace onto the
    # beginning of the rest of the code.  To fix this, we're going to combine
    # all of that code, and then make sure there are two linebreaks to start
    restsrc = _partitions_to_src(rest)
    restsrc = restsrc.rstrip()
    if restsrc:
        rest = [CodePartition(CodeType.CODE, restsrc + '\n')]
    else:
        rest = []

    return pre_import_code + new_imports + relative_imports + rest
def test_import_obj_from_str(input_str, expected):
    assert import_obj_from_str(input_str) == expected
def test_is_explicit_relative(input_str, expected):
    assert import_obj_from_str(input_str).is_explicit_relative is expected
Beispiel #22
0
 def _inner():
     for partition in partitions:
         if (partition.code_type is not CodeType.IMPORT
                 or import_obj_from_str(
                     partition.src) not in to_remove_imports):
             yield partition
Beispiel #23
0
def test_is_explicit_relative(input_str, expected):
    assert import_obj_from_str(input_str).is_explicit_relative is expected
Beispiel #24
0
def test_import_obj_from_str(input_str, expected):
    assert import_obj_from_str(input_str) == expected