Package: reorder-python-imports
reorder-python-importsTool for automatically reordering python imports.  Similar toisortbut
uses static analysis more.Installationpipinstallreorder-python-importsConsole scriptsConsultreorder-python-imports --helpfor the full set of options.reorder-python-importstakes filenames as positional argumentsCommon options:--py##-plus:see below.--add-import/--remove-import:see below.--replace-import:see below.--application-directories: by default,reorder-python-importsassumes
your project is rooted at..  If this isn't true, tell it where your
import roots live.  For example, when using the popular./srclayout 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 hookSeepre-commitfor instructionsSample.pre-commit-config.yaml-repo:https://github.com/asottile/reorder-python-importsrev:v3.12.0hooks:-id:reorder-python-importsWhat does it do?Separates imports into three sectionsimportsysimportpyramidimportreorder_python_importsbecomes (stdlib, third party, first party)importsysimportpyramidimportreorder_python_importsimportimports beforefromimportsfromosimportpathimportsysbecomesimportsysfromosimportpathSplitsfromimportsfromos.pathimportabspath,existsbecomesfromos.pathimportabspathfromos.pathimportexistsRemoves duplicate importsimportosimportos.pathimportsysimportsysbecomesimportos.pathimportsysUsing# noreorderLines containing and after lines which contain a# noreordercomment will
be ignored.  Additionally any imports that appear after non-whitespace
non-comment lines will be ignored.For instance, these will not be changed:importsystry:# not import, not whitespaceimportfooexceptImportError:passimportsysimportreorder_python_importsimportmatplotlib# noreordermatplotlib.use('Agg')importmatplotlib.pyplotasplt# noreorderimportsysimportpyramidimportreorder_python_importswhy this style?The style chosen byreorder-python-importshas 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, Tupleno conflict with the style enforced byreorder-python-imports:+from typing import Anyfrom typing import Dictfrom typing import List+from typing import TupleAdding / Removing ImportsLet's say I want to enforceabsolute_importacross my codebase.  I can use:--add-import 'from __future__ import absolute_import'.$cattest.pyprint('Hello world')$reorder-python-imports--add-import'from __future__ import absolute_import'test.pyReordering imports in test.py$cattest.pyfrom __future__ import absolute_importprint('Hello world')Let's say I no longer care about supporting Python 2.5, I can removefrom __future__ import with_statementwith--remove-import 'from __future__ import with_statement'$cattest.pyfrom __future__ import with_statementwith open('foo.txt', 'w') as foo_f:foo_f.write('hello world')$reorder-python-imports--remove-import'from __future__ import with_statement'test.pyReordering imports in test.py$cattest.pywith open('foo.txt', 'w') as foo_f:foo_f.write('hello world')Replacing importsImports can be replaced with others automatically (if they provide the same
names).  This can be useful for factoring out compatibility libraries such
assix(see below for automatedsixrewriting).This rewrite avoidsNameErrors as such it only occurs when:the imported symbol is the same before and afterthe import is afromimportThe argument is specified asorig.mod=new.modor with an optional
checked attributeorig.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-importsix.moves.queue=queue# specific attribute move--replace-importsix.moves=io:StringIORemoving obsolete__future__importsThe 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_stopRemoving / rewriting obsoletesiximportsWith--py3-plus,reorder-python-importswill also remove / rewrite imports
fromsix.  Rewrites follow the same rules asreplacing importsabove.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_plusRewriting mock importsWith--py3-plus,reorder-python-importswill also rewrite variousmockimports:-from mock import patch+from unittest.mock import patchRewritingmypy_extensionsandtyping_extensionimportsWith--py36-plusand higher,reorder-python-importswill also rewritemypy_extensionsandtyping_extensionsimports ported totyping.-from mypy_extensions import TypedDict+from typing import TypedDictRewriting pep 585 typing importsWith--py39-plusand higher,reorder-python-importswill replace imports
which were moved out of the typing module inpep 585.-from typing import Sequence+from collections.abc import Sequence