CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-flake8-import-order

Flake8 and pylama plugin that checks the ordering of import statements.

Pending
Overview
Eval results
Files

styles.mddocs/

Built-in Import Styles

Collection of pre-implemented import ordering styles including cryptography (default), Google, PEP8, and others, with extensible base class for custom styles.

Capabilities

Base Style Class

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
        """

Built-in Style Classes

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."""

Style Discovery and Loading

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 Data Type

Error objects returned by style checking.

Error = namedtuple("Error", ["lineno", "code", "message"])

Usage Examples

Using Built-in Styles

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}")

Creating Custom Styles

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',
#     ]
# }

Style Comparison

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 imports

Listing Available Styles

from 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}")

Style-Specific Features

Application Package Names Support

Some styles support the application_package_names configuration option:

  • AppNexus: Company/organization packages come after third-party but before application imports
  • Edited: Like AppNexus with additional formatting flexibility

Name Sorting Variations

Different styles sort imported names differently:

  • Google/Smarkets: Case-insensitive alphabetical (import A, a, B, b)
  • PyCharm: Case-sensitive alphabetical (import A, B, a, b)
  • ISort: Groups by type - CONSTANTS, Classes, functions (import CONST, Class, func)
  • Cryptography: Simple alphabetical sorting

Section Grouping Rules

Styles differ in how they group imports into sections:

  • Standard: Groups by import type (future, stdlib, third-party, application, relative)
  • Cryptography: Additional sub-grouping by package within third-party/application
  • Edited: Stricter section boundaries, no mixing of import types

Install with Tessl CLI

npx tessl i tessl/pypi-flake8-import-order

docs

checker.md

core-types.md

index.md

integrations.md

styles.md

tile.json