Skip to main content

A Python codemod that sorts and organizes code in your files.

Project description

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

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.yaml
repos:
  - repo: https://github.com/praw-dev/CodeSorter
    rev: v0.2.5
    hooks:
      - id: codesorter

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

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

Programmatic Usage

You can also use CodeSorter programmatically:

import libcst as cst
from codesorter.sort_code import SortCodeCommand
from libcst.codemod import CodemodContext

# Parse your code
code = """
def z_function():
    pass

def a_function():
    pass
"""

# Create context and command
context = CodemodContext()
command = SortCodeCommand(context)

# Transform the code
result = 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:

class MyClass:
    def z_method(self):
        pass

    @property
    def a_property(self):
        pass

    @staticmethod
    def b_static():
        pass

After:

class MyClass:
    @staticmethod
    def b_static():
        pass

    @property
    def a_property(self):
        pass

    def z_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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codesorter-0.2.8.tar.gz (105.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codesorter-0.2.8-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file codesorter-0.2.8.tar.gz.

File metadata

  • Download URL: codesorter-0.2.8.tar.gz
  • Upload date:
  • Size: 105.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for codesorter-0.2.8.tar.gz
Algorithm Hash digest
SHA256 b4a3af118a9959ce2a96e693673779e7561ddc14afd5581c11a86aa3285f2404
MD5 5fb24458e276fe1d2bf41657385518cd
BLAKE2b-256 6a74fd807c6fc9ef389e37dad3c45f2ea9e5105aefaf40db94daf44cf3af5d31

See more details on using hashes here.

Provenance

The following attestation bundles were made for codesorter-0.2.8.tar.gz:

Publisher: pypi.yml on praw-dev/CodeSorter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file codesorter-0.2.8-py3-none-any.whl.

File metadata

  • Download URL: codesorter-0.2.8-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for codesorter-0.2.8-py3-none-any.whl
Algorithm Hash digest
SHA256 211812abb9ab6456919ee6fb53e614acbddad67fc53533a3397e4a22fa1337b7
MD5 fe03b76565223fe0d5860034c218e44e
BLAKE2b-256 d4f100833b64f478c10ea9d6b5aba424c0c598109371c52acddb096b869175da

See more details on using hashes here.

Provenance

The following attestation bundles were made for codesorter-0.2.8-py3-none-any.whl:

Publisher: pypi.yml on praw-dev/CodeSorter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page