Flake8 and pylama plugin that checks the ordering of import statements.
—
Collection of pre-implemented import ordering styles including cryptography (default), Google, PEP8, and others, with extensible base class for custom styles.
Abstract base class that defines the interface for import ordering styles and provides common error checking functionality.
class Style:
"""Base class for import ordering styles."""
accepts_application_package_names = False # Whether style supports app package names
def __init__(self, nodes):
"""
Initialize style with list of imports and newlines.
Args:
nodes: List of ClassifiedImport and NewLine objects in file order
"""
def check(self):
"""
Check import order according to style rules.
Yields:
Error objects for each style violation found
"""
def sorted_names(self, names):
"""
Return names in the order they should appear.
Args:
names: List of imported names
Returns:
Names sorted according to style rules
"""
def import_key(self, import_):
"""
Generate sort key for import statement.
Args:
import_: Import to generate key for
Returns:
Sort key tuple for ordering imports
"""
def same_section(self, previous, current):
"""
Check if two imports belong to the same section/group.
Args:
previous: Previous import
current: Current import
Returns:
True if imports are in same section
"""Pre-implemented styles covering common Python import ordering conventions.
class PEP8(Style):
"""PEP8 style - groups only, no internal ordering."""
pass
class Google(Style):
"""Google style guide import ordering."""
@staticmethod
def name_key(name):
"""Generate sort key for imported name (case-insensitive, then case-sensitive)."""
@staticmethod
def sorted_names(names):
"""Sort names case-insensitively, then case-sensitively."""
@staticmethod
def import_key(import_):
"""Enhanced sort key including module and name sorting."""
class Smarkets(Style):
"""Smarkets style - like Google but import before from-import."""
@staticmethod
def name_key(name):
"""Generate sort key for imported name."""
@staticmethod
def sorted_names(names):
"""Sort names case-insensitively."""
@staticmethod
def import_key(import_):
"""Sort key with is_from ordering."""
class AppNexus(Google):
"""AppNexus style - extends Google with application package support."""
accepts_application_package_names = True
class Edited(Smarkets):
"""Edited style - extends Smarkets with application package support and optional newlines."""
accepts_application_package_names = True
@staticmethod
def same_section(previous, current):
"""Same section check with stricter type matching."""
class PyCharm(Smarkets):
"""PyCharm style - like Smarkets with case-sensitive name sorting."""
@staticmethod
def sorted_names(names):
"""Sort names case-sensitively."""
@staticmethod
def import_key(import_):
"""Sort key with case-sensitive ordering."""
class ISort(PyCharm):
"""ISort-compatible style with CONSTANT, Class, func grouping."""
@staticmethod
def name_key(name):
"""Group by CONSTANT (0), Class (1), func (2), then alphabetically."""
@staticmethod
def sorted_names(names):
"""Sort with CONSTANT, Class, func precedence."""
class Cryptography(Style):
"""Cryptography style (default) - groups by package within third-party/application."""
@staticmethod
def sorted_names(names):
"""Sort names alphabetically."""
@staticmethod
def import_key(import_):
"""Sort key with package-based grouping for third-party/application imports."""
@staticmethod
def same_section(previous, current):
"""Same section with package-based grouping."""Functions for discovering and loading available import styles from entry points.
def list_entry_points():
"""
List all available import order style entry points.
Returns:
List of available style entry points
"""
def lookup_entry_point(name):
"""
Look up style entry point by name.
Args:
name: Style name (e.g., 'cryptography', 'google')
Returns:
Entry point for the specified style
Raises:
LookupError: If style name is not found
"""Error objects returned by style checking.
Error = namedtuple("Error", ["lineno", "code", "message"])from flake8_import_order.styles import lookup_entry_point, Cryptography
from flake8_import_order import ClassifiedImport, NewLine, ImportType
# Load style by name
style_entry = lookup_entry_point('google')
style_class = style_entry.load()
# Create style instance with imports
imports = [
ClassifiedImport(ImportType.STDLIB, False, ['os'], [], 1, 1, 0, 'os', False),
ClassifiedImport(ImportType.THIRD_PARTY, False, ['requests'], [], 2, 2, 0, 'requests', False),
]
style = style_class(imports)
# Check for errors
for error in style.check():
print(f"Line {error.lineno}: {error.code} - {error.message}")from flake8_import_order.styles import Style
class CustomStyle(Style):
"""Custom style with reverse alphabetical ordering."""
@staticmethod
def sorted_names(names):
"""Sort names in reverse alphabetical order."""
return sorted(names, reverse=True)
@staticmethod
def import_key(import_):
"""Custom sort key with reverse module ordering."""
return (import_.type, tuple(reversed(import_.modules)))
# Register custom style via entry points in setup.py:
# entry_points={
# 'flake8_import_order.styles': [
# 'custom = mypackage:CustomStyle',
# ]
# }Different styles handle import ordering differently:
# Sample imports
imports = [
"import json",
"import os",
"from mycompany.utils import helper",
"from requests import get"
]
# PEP8: Groups only, no internal ordering enforced
# Google: Case-insensitive alphabetical within groups
# Smarkets: Like Google, but 'import' statements before 'from' statements
# Cryptography: Package-based grouping within third-party/application imports
# AppNexus: Like Google with application package support
# PyCharm: Case-sensitive alphabetical ordering
# ISort: CONSTANTS, Classes, functions ordering within importsfrom flake8_import_order.styles import list_entry_points
# Get all available styles
styles = list_entry_points()
for style in styles:
print(f"Style: {style.name}")
style_class = style.load()
print(f" Accepts app packages: {style_class.accepts_application_package_names}")Some styles support the application_package_names configuration option:
Different styles sort imported names differently:
import A, a, B, b)import A, B, a, b)import CONST, Class, func)Styles differ in how they group imports into sections:
Install with Tessl CLI
npx tessl i tessl/pypi-flake8-import-order