Skip to content

Repository files navigation

CodeSorter

CodeSorter is a LibCST codemod that automatically sorts and organizes Python code.

Warning

Only apply CodeSorter to a code base you own or maintain. Reordering an entire file is a sweeping, opinionated change that conflicts with in-flight work and erases the history of carefully chosen ordering. Opening a pull request that runs CodeSorter across someone else's project is strongly discouraged — it is noisy, unsolicited, and burdensome to review. Adopt it as a pre-commit hook in your own repositories instead, where every contributor benefits from the consistent ordering.

Features

  • Smart Sorting: Automatically sorts functions, classes, and methods alphabetically
  • Decorator Awareness: Properly handles @property, @staticmethod, @classmethod, and @pytest.fixture decorators
  • Hierarchical Organization: Maintains logical grouping within classes and modules
  • Constant Grouping: Orders each scope as constants, then classes, then functions, sorting constants by dependency while preserving enum and dataclass field order
  • Keyword Sorting: Alphabetizes keyword arguments in calls, keyword-only parameters, and dict string keys, while preserving */** unpacking semantics and the keyword-argument order of order-sensitive callables such as OrderedDict
  • Pytest Integration: Special handling for pytest fixtures with proper scope ordering
  • CLI Interface: Simple command-line interface for easy integration
  • Pre-commit Hook: Ready-to-use pre-commit hook for automated code organization

Installation

From PyPI:

# install the codesorter CLI as a standalone tool
uv tool install codesorter
# or add it to a project's lint dependency group
uv add --group lint codesorter

From Source:

git clone https://github.com/praw-dev/CodeSorter.git
cd CodeSorter
uv tool install .

Development Installation:

git clone https://github.com/praw-dev/CodeSorter.git
cd CodeSorter
uv sync

Usage

Command Line Interface

The simplest way to use CodeSorter is through the command-line interface:

# Sort a single file
codesorter my_file.py
# Sort all Python files in a directory
codesorter my_project/
# Sort with additional options
codesorter --help

Pre-commit Hook

Add CodeSorter to your pre-commit configuration to automatically sort code on every commit:

# .pre-commit-config.yamlrepos:
- repo: https://github.com/praw-dev/CodeSorterrev: v0.2.5hooks:
- id: codesorter

Or use the check-only variant, which fails the hook without modifying files:

repos:
- repo: https://github.com/praw-dev/CodeSorterrev: v0.2.5hooks:
- id: codesorter-check

Programmatic Usage

You can also use CodeSorter programmatically:

importlibcstascstfromcodesorter.sort_codeimportSortCodeCommandfromlibcst.codemodimportCodemodContext# Parse your codecode="""def z_function(): passdef a_function(): pass"""# Create context and commandcontext=CodemodContext()
command=SortCodeCommand(context)
# Transform the coderesult=command.transform_module(cst.parse_module(code))
print(result.code)

How It Works

CodeSorter uses LibCST (Concrete Syntax Tree) to parse and transform Python code. It applies sophisticated sorting rules:

Function Sorting

  • Functions are sorted alphabetically by name
  • Global functions are sorted separately from class methods

Class Method Sorting

  • Methods are grouped by kind, in this order:
    • @abstractmethod methods
    • pytest fixtures (autouse fixtures first)
    • @staticmethod methods
    • @classmethod methods
    • cached properties and @property methods (getter, then setter, then deleter)
    • @contextmanager methods
    • regular instance methods
  • Within each group, methods are sorted alphabetically, with leading-underscore (_private and __dunder__) names ahead of public ones

Pytest Fixture Sorting

  • Fixtures are sorted by scope (session, package, module, class, function)
  • Within each scope, fixtures are sorted alphabetically
  • autouse fixtures are handled specially

Example Transformation

Before:

classMyClass:
defz_method(self):
pass@propertydefa_property(self):
pass@staticmethoddefb_static():
pass

After:

classMyClass:
@staticmethoddefb_static():
pass@propertydefa_property(self):
passdefz_method(self):
pass

Development

Setting Up Development Environment

# Clone the repository
git clone https://github.com/praw-dev/CodeSorter.git
cd CodeSorter
# Install with development dependencies
uv sync
# Install pre-commit hooks
uv run pre-commit install

Running Tests

# Run all tests
uv run pytest
# Run a specific test file
uv run pytest tests/test_sort_code.py
# Run the full tox matrix (tests, type, pre-commit)
uv run tox

Code Quality

The project uses several tools to maintain code quality:

  • Ruff: Fast linting and formatting
  • Pyright: Type checking
  • Pre-commit: Automated quality checks

Run all quality checks:

uv run pre-commit run --all-files

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Make your changes and add tests
  4. Run the test suite: uv run pytest
  5. Run pre-commit hooks: pre-commit run --all-files
  6. Commit your changes: git commit -m "Add feature"
  7. Push to your fork: git push origin feature-name
  8. Create a Pull Request

Examples

See the examples/ directory for before and after examples of CodeSorter in action:

  • examples/before_example.py: Unsorted code
  • examples/after_example.py: Same code after sorting

License

This project is licensed under the MIT License - see the LICENSE.txt file for details.

Changelog

See the change log for the full list of changes.

About

CodeSorter is a LibCST codemod that automatically sorts and organizes Python code.

Resources

Code of conduct

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages