Change Log¶
codesorter follows semantic versioning.
Unreleased¶
0.2.8 (2026/06/15)¶
Fixed
Keep a module-level assignment that calls a local definition after the names that call needs at runtime.
APP = App()only referencesAppsyntactically, but instantiating it runsApp.__init__, which may read a module-level function defined later in the file. Such an assignment was previously hoisted above that function and raisedNameErrorat import. The runtime references reachable through a called class or function (transitively) are now treated as dependencies of the calling assignment.Do not sort the keyword arguments of an
OrderedDictcall.OrderedDict(b=2, a=1)iterates in argument order and is a distinct value fromOrderedDict(a=1, b=2), so reordering its keyword arguments changed the resulting object. Calls toOrderedDict(bare or dotted, such ascollections.OrderedDict) are now left untouched.
0.2.7 (2026/06/15)¶
Fixed
Do not treat a class’s own attribute as a dependency on a same-named outer definition. An enum member or class variable named like the module constant that aliases it (for example
CACHE_MISS = _Sentinel.CACHE_MISSbesideclass _Sentinel(Enum): CACHE_MISS = auto()) previously forged a falseclass->constantedge that closed a cycle with the realconstant->classedge, hoisting the constant above the class it references and raisingNameErrorat import. A name bound in a class’s own body is now recognized as belonging to that class’s namespace and imposes no ordering on outer definitions.
0.2.6 (2026/06/14)¶
Added
Documentation page describing how barriers limit sorting to segments between side-effecting statements, and how to relocate a statement that should not be a barrier.
Changed
Refresh the documentation: the installation instructions use uv-native commands, the class-method ordering reference and example now match the implementation, and the barrier relocation example is split into separate, color-tinted before and after blocks.
0.2.5 (2026/06/14)¶
Changed
Depend on
ruffdirectly so the formatter is always installed alongsidecodesorter. The CLI shells out toruff format, which previously only worked whenruffhappened to be onPATHfrom another source; it is now a runtime dependency, socodesorteris self-contained in a clean environment and in the isolated pre-commit hook.
0.2.4 (2026/06/14)¶
Fixed
Never reorder a definition across a side-effecting statement. A bare statement such as
sys.path.insert(0, str(REPO_ROOT))is now a barrier, and sorting happens only within each segment between barriers, so a constant the statement uses is no longer hoisted after it (which raisedNameError).
0.2.3 (2026/06/14)¶
Fixed
Keep an assignment that rebinds a name also bound by a sibling in its original position relative to that sibling. For example
ten = cachedproperty(ten, ...)followingdef tennow stays after the method it wraps instead of being hoisted ahead of it (which raisedNameErrorand changed which binding wins). Property getter/setter/deleter groups, which carry no assignment, are still ordered by their sort key.
0.2.2 (2026/06/14)¶
Changed
Format reordered files with
ruffby default instead ofblack, so a downstream project no longer needs a.libcst.codemod.yamlto use thecodesorterCLI or pre-commit hook.ruffmust be importable on thePATHwhen sorting.
0.2.1 (2026/06/14)¶
Fixed
Treat a name used inside a module- or class-level comprehension as a real dependency. Such a comprehension runs eagerly when the definition executes, so an assignment like
values = {key: build(key) for key in keys}now sorts after thebuildfunction it calls instead of ahead of it (which raisedNameError). A comprehension inside a function body stays deferred and still imposes no ordering.
0.2.0 (2026/06/14)¶
Added
Sort module- and class-level assignments. Within every scope the order is now assignments, then classes, then functions/methods, so methods always follow nested classes and assignments are grouped at the top. Assignments are split into uppercase
CONSTANTSfirst and then other variables; each group sorts with a leading underscore first (so__dunder__and_privateprecede public names), and dependencies are respected (B = A + 1stays afterA). As a result, module-level functions now sort after module-level classes. The attribute order of enums, dataclasses, andNamedTuple/TypedDictclasses is preserved; the base or decorator is resolved throughQualifiedNameProviderso aliased imports (from enum import IntEnum as IE) are recognized.Keep blank-line spacing with its position rather than the moved definition, so reordering no longer drags a blank line onto a different statement (for example the blank line after a class docstring stays at the top of the block). Comment lines that sit directly above a definition still travel with it.
Keep an augmented assignment anchored to the constant it augments, so
__all__ += extrastays directly after__all__ = [...]instead of being left behind as a fixed barrier when another assignment sorts between them.Sort keyword arguments in calls, keyword-only parameters in function definitions, and string keys in dict literals alphabetically. In a call, keyword arguments are sorted and
**unpackings moved to the end (positional arguments and*unpackings stay put), which is safe because a call raisesTypeErroron any duplicate keyword regardless of order. In a dict literal,**spreads and non-string keys act as barriers so last-wins merge semantics are preserved.
Changed
Sort
_-prefixed (private and dunder) names ahead of public names at every level rather than after capitalized names. A plain string sort placed_afterA-Zbecause of its higher code point; names are now ordered on a leading-underscore flag first so private definitions, methods, keyword arguments, and dict keys group together ahead of the public ones.
Fixed
Ignore a name used only in a lazy annotation (under
from __future__ import annotations) when ordering definitions, since the annotation is never evaluated at runtime and imposes no real dependency. A forward reference in an annotation (for examplenxt: list[Instr]whereInstris a type-alias union of classes defined later) previously forged a false dependency cycle that could hoist the runtime alias above the classes it unions and raiseNameError.Order definitions with a proper priority topological sort so a class or function is always placed after every sibling it depends on. The previous dependency heuristic compared per-node dependency vectors and could emit a dependent before its dependency (for example,
Subreddit’sSubredditFlairwas sorted ahead of the flair-template classes it instantiates).
0.1.0 (2026/06/14)¶
Added
Initial release of CodeSorter.
CLI interface with directory walking, sensible default excludes,
.gitignorehonoring, and-e/--exclude/--no-default-excludes/--no-gitignoreflags.Pre-commit hooks (
codesorterandcodesorter-check) for downstream consumers.Comprehensive test suite covering function, method, property, fixture, decorator, and inheritance sort behaviors.
Example before/after files in
examples/.