• Stars
    star
    719
  • Rank 61,540 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created over 9 years ago
  • Updated 14 days ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Rewrites source to reorder python imports

build status pre-commit.ci status

reorder-python-imports

Tool for automatically reordering python imports. Similar to isort but uses static analysis more.

Installation

pip install reorder-python-imports

Console scripts

Consult reorder-python-imports --help for the full set of options.

reorder-python-imports takes filenames as positional arguments

Common options:

  • --py##-plus: see below.
  • --add-import / --remove-import: see below.
  • --replace-import: see below.
  • --application-directories: by default, reorder-python-imports assumes your project is rooted at .. If this isn't true, tell it where your import roots live. For example, when using the popular ./src layout you'd use --application-directories=.:src (note: multiple paths are separated using a :).
  • --unclassifiable-application-module: (may be specified multiple times) modules names that are considered application modules. this setting is intended to be used for things like C modules which may not always appear on the filesystem.

As a pre-commit hook

See pre-commit for instructions

Sample .pre-commit-config.yaml

-   repo: https://github.com/asottile/reorder-python-imports
    rev: v3.10.0
    hooks:
    -   id: reorder-python-imports

What does it do?

Separates imports into three sections

import sys
import pyramid
import reorder_python_imports

becomes (stdlib, third party, first party)

import sys

import pyramid

import reorder_python_imports

import imports before from imports

from os import path
import sys

becomes

import sys
from os import path

Splits from imports

from os.path import abspath, exists

becomes

from os.path import abspath
from os.path import exists

Removes duplicate imports

import os
import os.path
import sys
import sys

becomes

import os.path
import sys

Using # noreorder

Lines containing and after lines which contain a # noreorder comment will be ignored. Additionally any imports that appear after non-whitespace non-comment lines will be ignored.

For instance, these will not be changed:

import sys

try:  # not import, not whitespace
    import foo
except ImportError:
    pass
import sys

import reorder_python_imports

import matplotlib  # noreorder
matplotlib.use('Agg')
import matplotlib.pyplot as plt
# noreorder
import sys
import pyramid
import reorder_python_imports

why this style?

The style chosen by reorder-python-imports has a single aim: reduce merge conflicts.

By having a single import per line, multiple contributors can add / remove imports from a single module without resulting in a conflict.

Consider the following example which causes a merge conflict:

# developer 1
-from typing import Dict, List
+from typing import Any, Dict, List
# developer 2
-from typing import Dict, List
+from typing import Dict, List, Tuple

no conflict with the style enforced by reorder-python-imports:

+from typing import Any
 from typing import Dict
 from typing import List
+from typing import Tuple

Adding / Removing Imports

Let's say I want to enforce absolute_import across my codebase. I can use: --add-import 'from __future__ import absolute_import'.

$ cat test.py
print('Hello world')
$ reorder-python-imports --add-import 'from __future__ import absolute_import' test.py
Reordering imports in test.py
$ cat test.py
from __future__ import absolute_import
print('Hello world')

Let's say I no longer care about supporting Python 2.5, I can remove from __future__ import with_statement with --remove-import 'from __future__ import with_statement'

$ cat test.py
from __future__ import with_statement
with open('foo.txt', 'w') as foo_f:
    foo_f.write('hello world')
$ reorder-python-imports --remove-import 'from __future__ import with_statement' test.py
Reordering imports in test.py
$ cat test.py
with open('foo.txt', 'w') as foo_f:
    foo_f.write('hello world')

Replacing imports

Imports can be replaced with others automatically (if they provide the same names). This can be useful for factoring out compatibility libraries such as six (see below for automated six rewriting).

This rewrite avoids NameErrors as such it only occurs when:

  • the imported symbol is the same before and after
  • the import is a from import

The argument is specified as orig.mod=new.mod or with an optional checked attribute orig.mod=new.mod:attr. The checked attribute is useful for renaming some imports from a module instead of a full module.

For example:

# full module move
--replace-import six.moves.queue=queue
# specific attribute move
--replace-import six.moves=io:StringIO

Removing obsolete __future__ imports

The cli provides a few options to help "burn the bridges" with old python versions by removing __future__ imports automatically. Each option implies all older versions.

  • --py22-plus: nested_scopes
  • --py23-plus: generators
  • --py26-plus: with_statement
  • --py3-plus: division, absolute_import, print_function, unicode_literals
  • --py37-plus: generator_stop

Removing / rewriting obsolete six imports

With --py3-plus, reorder-python-imports will also remove / rewrite imports from six. Rewrites follow the same rules as replacing imports above.

For example:

+import queue
+from io import StringIO
+from urllib.parse import quote_plus
+
 import six.moves.urllib.parse
-from six.moves import queue
-from six.moves import range
-from six.moves import StringIO
-from six.moves.urllib.parse import quote_plus

Rewriting mock imports

With --py3-plus, reorder-python-imports will also rewrite various mock imports:

-from mock import patch
+from unittest.mock import patch

Rewriting mypy_extensions and typing_extension imports

With --py36-plus and higher, reorder-python-imports will also rewrite mypy_extensions and typing_extensions imports ported to typing.

-from mypy_extensions import TypedDict
+from typing import TypedDict

Rewriting pep 585 typing imports

With --py39-plus and higher, reorder-python-imports will replace imports which were moved out of the typing module in pep 585.

-from typing import Sequence
+from collections.abc import Sequence

More Repositories

1

pyupgrade

A tool (and pre-commit hook) to automatically upgrade syntax for newer versions of the language.
Python
3,385
star
2

git-code-debt

A dashboard for monitoring code debt in a git repository.
Python
564
star
3

all-repos

Clone all your repositories and apply sweeping changes.
Python
523
star
4

babi

a text editor
Python
380
star
5

add-trailing-comma

A tool (and pre-commit hook) to automatically add trailing commas to calls and literals.
Python
332
star
6

dead

dead simple python dead code detection
Python
322
star
7

yesqa

Automatically remove unnecessary `# noqa` comments
Python
259
star
8

astpretty

Pretty print the output of python stdlib `ast.parse`.
Python
189
star
9

detect-test-pollution

a tool to detect test pollution
Python
168
star
10

setup-cfg-fmt

apply a consistent format to `setup.cfg` files
Python
151
star
11

setup-py-upgrade

upgrade a setup.py to declarative metadata
Python
146
star
12

scratch

Haphazard things.
Python
117
star
13

importtime-waterfall

Generate waterfalls from `-Ximporttime` tracing.
Python
105
star
14

setuptools-golang

A setuptools extension for building cpython extensions written in golang.
Python
98
star
15

dockerfile

Parse a dockerfile into a high-level representation using the official go parser
Go
95
star
16

re-assert

show where your regex match assertion failed!
Python
81
star
17

gh-perf-review

hackety tool to view github PRs for a period
Python
79
star
18

covdefaults

A coverage plugin to provide sensible default settings
Python
62
star
19

tokenize-rt

A wrapper around the stdlib `tokenize` which roundtrips.
Python
48
star
20

flake8-typing-imports

flake8 plugin which checks that typing imports are properly guarded
Python
48
star
21

cfgv

Validate configuration and produce human readable error messages
Python
44
star
22

recipes

One day IoT will catch up and then I can use CI
26
star
23

classify-imports

Utilities for refactoring imports in python-like syntax.
Python
23
star
24

awshelp

awshelp forwards arguments to `aws` unless `-h` or `--help` are present
Python
20
star
25

setuptools-golang-examples

Example extensions written for https://github.com/asottile/setuptools-golang
Go
19
star
26

nintendo-microcontrollers

control various nintendo consoles with arduino!
Python
18
star
27

watch-plz

Ensure all of your repositories are watched.
Python
17
star
28

workflows

reusable github workflows / actions
17
star
29

onigurumacffi

python cffi bindings for the oniguruma regex engine
Python
16
star
30

color-code

Encodes files as color
Python
16
star
31

ukkonen

Implementation of bounded Levenshtein distance (Ukkonen)
C++
15
star
32

wat

my brain is full of wat
Python
11
star
33

personal-puppet

serverless puppet to manage my machines
Puppet
11
star
34

shiny-pokemon-scraper

automatically detect tera raid events with guaranteed shiny pokemon
Python
10
star
35

set-delete-branch-on-merge

github does not provide a way to set the `delete_branch_on_merge` as a default
Python
8
star
36

babi-grammars

pip installable package to provide syntax grammars for babi
Python
8
star
37

rubyvenv

Create no-hassle ruby "virtualenvs". No .bashrc, no shims, no cd-magic.
Python
7
star
38

tessdata

pip installable versions of tesseract-ocr data
Python
6
star
39

pygments-pre-commit

A pygments lexer for pre-commit output.
Python
6
star
40

setuptools-download

setuptools plugin to download external files
Python
5
star
41

t

haphazard code snippets
Python
4
star
42

markdown-code-blocks

Generate html from markdown with code-block highlighting
Python
4
star
43

asottile.github.io

Python
4
star
44

hiera-eyaml-sshagent

A hiera-eyaml plugin which uses the ssh agent connected to `SSH_AUTH_SOCK` to encrypt / decrypt values.
Ruby
4
star
45

kensquared

Kotlin
2
star
46

.github

centralized github metadata for asottile
2
star
47

itl

Python
2
star
48

asottile

2
star
49

gnome-terminal-broken

rip
1
star