Rewrites source to reorder python imports
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

Build Status Coverage Status


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


pip install reorder-python-imports

Console scripts

reorder-python-imports --help
usage: reorder-python-imports [-h] [--diff-only] [--add-import ADD_IMPORT]
                              [--remove-import REMOVE_IMPORT]
                              [--application-directories APPLICATION_DIRECTORIES]
                              [filenames [filenames ...]]

positional arguments:

optional arguments:
  -h, --help            show this help message and exit
  --diff-only           Show unified diff instead of applying reordering.
  --add-import ADD_IMPORT
                        Import to add to each file. Can be specified multiple
  --remove-import REMOVE_IMPORT
                        Import to remove from each file. Can be specified
                        multiple times.
  --application-directories APPLICATION_DIRECTORIES
                        Colon separated directories that are considered top-
                        level application directories. Defaults to `.`

As a pre-commit hook

See pre-commit for instructions

Sample .pre-commit-config.yaml

-   repo:
    rev: v1.1.0
    -   id: reorder-python-imports

What does it do?

Separates imports into three sections

import sys
import pyramid
import reorder_python_imports


import sys

import pyramid

import reorder_python_imports

import imports before from imports

from os import path
import sys


import sys
from os import path

Splits from imports (may be configurable in the future!)

from os.path import abspath, exists


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

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:
import sys

import reorder_python_imports

import matplotlib  # noreorder
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
print('Hello world')
$ reorder-python-imports --add-import 'from __future__ import absolute_import'
Reordering imports in
$ cat
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
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'
Reordering imports in
$ cat
with open('foo.txt', 'w') as foo_f:
    foo_f.write('hello world')

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