92

PEP8 suggests that:

Imports should be grouped in the following order:

  1. standard library imports
  2. related third party imports
  3. local application/library specific imports

You should put a blank line between each group of imports.

Is there a way to check if the standard is violated anywhere in the package using static code analysis tools, like pylint, pyflakes, pychecker, pep8?


Example of violation:

from my_package import my_module
from django.db import models
import os

Correct way to import:

import os

from django.db import models

from my_package import my_module
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • 1
    The `pep8` tool doesn't currently check this - it only checks for multiple imports on one line (E401) – DNA Mar 28 '14 at 23:12
  • [PyCharm](http://www.jetbrains.com/pycharm/) might do this but I'm not 100% sure. It costs moneys though. – Claudiu Mar 31 '14 at 01:33
  • @Claudiu turned on all python inspections - it doesn't find the problem in the import order. Thanks. – alecxe Mar 31 '14 at 01:36
  • 5
    @Claudiu - Pycharm has a community version too. – Amit Mar 31 '14 at 01:40
  • 3
    If you don't end up finding something, you could write your own pylint plugin to check this for you. Take a look at [pylint-plugin-utils](https://github.com/landscapeio/pylint-plugin-utils) and an example plugin [here](https://github.com/landscapeio/pylint-celery). (This might be better suited as a comment but I don't have the reputation to comment.) – mobeets Mar 31 '14 at 03:42
  • [PyCharm Community Edition](https://www.jetbrains.com/pycharm/) (free) can fully optimize and sort your imports: https://www.jetbrains.com/help/pycharm/creating-and-optimizing-imports.html You can even configure how the sorting happens under Settings | Editor | Code Style | Python | Imports – phoenix May 11 '18 at 18:26

6 Answers6

88

The current version of pylint now does this, and reports it as error class C0411.

sbywater
  • 1,281
  • 10
  • 7
  • 14
    This should be a higher-voted answer now. For more recent versions which don't display the error numbers anymore, it's error class `wrong-import-order`. – Soren Bjornstad Jul 11 '16 at 19:32
56

Update (2016): sbywater has the most recent answer.


Found it! (accidentally, while reading "Hacker's guide to python")

OpenStack Hacking Style Checks project named hacking introduces several unique flake8 extensions. There is hacking_import_groups among them (related commit).

Example:

  • requirements

    • tox
    • flake8
    • hacking (from the master branch):

      $ git clone https://github.com/openstack-dev/hacking.git
      $ cd hacking/
      $ python setup.py install
      
  • files used in the example

    • tox.ini (we need to tell flake8 that we want to use a custom check)

      [hacking]
      local-check = hacking.core.hacking_import_groups
      

      UPD: with the newest version of hacking the path to the check changed, now it is hacking.checks.imports.hacking_import_groups.

    • test.py (target of the check)

      import requests
      import sys
      from my_module import print_smth
      
      
      print_smth(requests.get('https://google.com'))
      print_smth(sys.version)
      
    • my_module.py (local import used by test.py)

      def print_smth(smth):
          print smth
      

Then, if I run flake8 against test.py:

$ flake8 test.py
test.py:2:1: H305  imports not grouped correctly (requests: third-party, sys: stdlib)
test.py:3:1: H305  imports not grouped correctly (sys: stdlib, my_module.print_smth: project)
test.py:3:1: H306  imports not in alphabetical order (sys, my_module.print_smth)

Then, if I group the imports in the correct order following PEP8:

import sys

import requests

from my_module import print_smth


print_smth(requests.get('https://google.com'))
print_smth(sys.version)

No warnings found:

$ flake8 test.py
$

Hope this will help somebody in the future.

yoozer8
  • 7,361
  • 7
  • 58
  • 93
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • 2
    They took out this check, citing that it was too error-prone and difficult: https://github.com/openstack-dev/hacking/commit/8f1fcbdb9aa4fc61349e5e879153c722195b1233#diff-d941f383e7dafcdea3d0ff128d92b497L500 – Job Evers Sep 21 '15 at 18:36
29

Have a look at https://pypi.python.org/pypi/isort or https://github.com/timothycrosley/isort

isort parses specified files for global level import lines (imports outside of try / excepts blocks, functions, etc..) and puts them all at the top of the file grouped together by the type of import:

  • Future
  • Python Standard Library
  • Third Party
  • Current Python Project
  • Explicitly Local (. before import, as in: from . import x)

Custom Separate Sections (Defined by forced_separate list in configuration file) Inside of each section the imports are sorted alphabetically. isort automatically removes duplicate python imports, and wraps long from imports to the specified line length (defaults to 80).

https://pypi.python.org/pypi/flake8-isort plugs this functionality into flake8

cleder
  • 1,637
  • 14
  • 15
  • 2
    Just note that if you run `isort script_name.py --check-only` - it would only check for unsorted imports and print out the results - this is what I needed. Thank you very much for the option. – alecxe Apr 01 '14 at 21:15
  • `isort -rc --check --diff` check all files recursively, only checking, display a diff – ptim Feb 16 '16 at 01:31
7

A flake8 plugin exists: flake8-import-order.

This package adds 3 new flake8 warnings

I100: Your import statements are in the wrong order.

I101: The names in your from import are in the wrong order.

I201: Missing newline between sections or imports.

Community
  • 1
  • 1
phoenix
  • 7,988
  • 6
  • 39
  • 45
2

Broadly, You need to structure your import statements to meet pep8 import standard.

I found isort library useful in ordering import statements to get rid of flake8 ordering issues.

pip install isort
isort <your_python_file>.py
Kunal
  • 196
  • 3
  • 8
1

The Flake8 plugin Alphabetize https://github.com/tlocke/flake8-alphabetize checks import sort order and is designed to work with the Black formatter. It follows the Black formatter approach of having a single style, with no configuration of the style possible. Alphabetize also checks the order of the __all__ attribute.

Tony Locke
  • 454
  • 3
  • 9