Skip to content

Releases

Towel 1.949

Choose a tag to compare

@ericeallen ericeallen released this 13 Nov 00:31

Towel 1.949 improves the product experience and tightens which refactorings it proposes:

  • Extractions are selected using the complete helper and every rendered caller, including ownership boxes and deletions. Larger bodies and control flow no longer bypass the usefulness check. Small safe transformations remain available through the existing Python API opt-out; semantic verification is unchanged.
  • Complete preview shows one concise summary and diff. New --summary, --diff, --inventory, versioned preview/dry --json results, and --explain for source-located decline reasons. Human-readable output has changed; scripts should use the documented JSON schema.
  • Declined confirmation or closed interactive input now returns failure, human errors go consistently to stderr, and interruption returns 130.
  • --time-limit SECONDS for preview and dry: an expired run exits 124 before publishing output, and structured errors distinguish unknown dry publication state from a confirmed absence of output.
  • Installation and a complete copy, extract, rename, test and adopt tutorial come first in the guides; CLI, JSON and library compatibility commitments are documented, with supported library entry points in towel.api. Towel warns on interpreters outside the validated 3.11–3.13 range.

Validation. The runtime was validated on campaign source ae2e946d3030f985b872ea6b9fba0f25b2ce3dd4; the release commit 14dc1641b79e76cde8828c370eabad955a6b09f4 changes only nine prose files.

Python Passed Skipped Coverage
3.11 11,277 335 93%
3.12 11,479 203 94%
3.13 11,466 223 94%

Each suite also passed 45 subtests. Quality checks, the dependency audit, diagrams and installed-wheel integration passed, and self-dogfood passed strict typing and the full suite on Towel's own refactored source. Linux differential fuzzing from fresh seeds completed 10,340 runs with zero failures. All 141 corpus projects completed under the default typing policy: 75 passes, 61 no-change results and five explicit no-write import refusals, with three explicit typing fallbacks and twenty failing baselines reviewed. A pass means the selected suite's outcome was preserved, not that every consumer baseline was green. Fewer projects change than under 1.948 because of the new usefulness check.

The release archives were rebuilt from the release commit with the same pinned tools and rechecked: artifact contents, strict Twine, the dependency audit, diagrams, six clean-wheel checks across Python 3.11–3.13 and 133 documentation tests from the exact sdist. Exact-commit GitHub CI (all five jobs) and the live default-branch release gate passed before tagging and upload.

Artifacts (SHA-256):

a008bc93a2b9aa938b5dec5c8cc9b30d6cb221a6ca21e6c641cc6ca333372b10  code_towel-1.949-py3-none-any.whl
b9065b8d7bdbbeff1b7595254557c72569a7ac808671c5ed11e3ee5388aa85e9  code_towel-1.949.tar.gz

Changelog · Known limitations

Towel 1.948

Choose a tag to compare

@ericeallen ericeallen released this 07 Nov 22:19

Towel 1.948 repairs four silent towel dry miscompilations present in 1.947:

  • Method reads and nonlocal declarations resolve past the class body to the enclosing function, preserving variables rebound through other functions.
  • Later reads after semicolons are recognized, and the orphan check follows the method containing each block even when methods share a name.
  • Extraction declines thunks whose captured cells could be emptied by inlined comprehensions in nested definition defaults, decorators, annotations or class bases.
  • A name bound in a while test and deleted by the body or else is no longer treated as bound afterward, preserving the name reported by UnboundLocalError.

CLI corrections include a valid rename-helpers example; cost notes that name available checkers and count only included files; an inline apply-progress fallback when tqdm is absent; and per-pass detail output for single-file dry and complete preview. The guides clarify when confirmation cost notes appear and document the API's exact method-kind values, separate insert_into_function attribute and StaleSource exception. The release procedure also checks that GitHub's default branch contains the validated source and current documentation before publication.

Validation on the released source, 31c6a79fc3dfe71f58a5d5ba80bb58eeb8e8b512:

Python Passed Skipped Coverage
3.11 11,096 337 93.32%
3.12 11,299 205 93.69%
3.13 11,282 225 93.69%

Each suite also passed 45 subtests. Quality checks, the dependency audit, the build, diagrams, strict Twine checks and the source/artifact comparison all passed. Six clean-wheel checks cover bare and optional-tool installations across Python 3.11–3.13, and the exact sdist passed 129 documentation tests. Differential fuzzing completed 9,400 runs with zero failures and 44 inconclusive cases. Linux self-dogfood passed strict typing and the full Python 3.13 suite on Towel's own refactored source.

All 141 corpus projects completed: 90 passes, 44 no-change results, five explicit no-write import refusals, and two pinned warning-location limitations (Pluggy and Beautiful Soup). Twenty failing baselines and three explicit typing fallbacks were reviewed. A pass means the selected suite's outcome was preserved, not that every consumer baseline was green. Exact-commit GitHub CI and the live default-branch release gate passed before tagging and upload.

Artifacts (SHA-256):

980da6fc5fce3c4470651c7d0a1908a0a9b65b8f5129e0eeec51bacc37afa394  code_towel-1.948-py3-none-any.whl
352fc5fabb2b66fd20ea1873cfc344aed02d768703311aa814e5e1028af0e9b2  code_towel-1.948.tar.gz

Changelog · Known limitations

Towel 1.947

Choose a tag to compare

@ericeallen ericeallen released this 26 Oct 12:39

Towel 1.947 repairs binding, renaming, formatting, and resource-use defects after 1.946. It retains the beta designation and the documented limits on reflection and self-instrumentation.

Changes

  • Preserve class-private and Unicode binding identity when renaming helpers and parameters; refuse incomplete edits to consumers outside the selected target.
  • Handle replaced builtin mappings conservatively, including definition-time lookups and excluded runnable files.
  • Apply each file's formatter configuration, including nested Ruff import-sorting rules, while sharing Black/isort workers instead of retaining workers for every modified file.
  • Preserve incremental candidate pairing across local refreshes, skip enumeration without structural partners, and reuse parsing facts for proven warning-free raw strings and raw formatted-string literals.
  • Harden fuzz resource containment and oracle controls, distinguish corpus timeouts from signal kills, and default corpus execution to one project worker.

See the release overview and changelog.

Validation

Frozen commit: 8a853126f5499eb11dfa04fbe304dc332dc5ef73.

  • Local Linux suites passed on Python 3.11, 3.12 and 3.13: 11,034, 11,237 and 11,220 tests respectively, with coverage of 93–94%.
  • Native quality and strict typing, distribution checks, six clean-wheel installation checks, 126 packaged-documentation tests, diagrams and dependency audits passed.
  • Differential fuzzing completed 9,400 runs with zero failures and 30 inconclusive cases.
  • Self-dogfood applied 28 refactorings across 19 files; generated code passed strict typing and the Python 3.13 suite.
  • All 141 corpus projects completed without a phase timeout or signal termination: 89 PASS, 45 NO_CHANGE, five conservative import-ambiguity refusals and two known warning-location limitations. The five refusal logs match the prior 1.946 gate. The three Towel corpus entries therefore do not establish successful self-refactoring; the separate self-dogfood run does. Nineteen projects had pre-existing failing baselines, and three explicit typing fallbacks are recorded separately from type-verified transformations.

The completed local campaign used the exact attached distributions. GitHub CI passed all four jobs on the same source commit: quality, Python 3.11 (11,036 passed, 93% coverage), Python 3.12 (11,239 passed, 94% coverage), and Python 3.13 (11,222 passed, 94% coverage).

Performance scope

A controlled full-CLI comparison with published 1.946 used two samples per version in release/candidate/candidate/release order, identical Python/tool versions within each project, fresh project copies, sequential execution and a shared host. Mean times were:

Project 1.946 1.947 Observed change
Click 76.945 s 78.928 s +2.58%
Rich 144.560 s 157.344 s +8.84%
Voluptuous 123.122 s 124.656 s +1.25%

All distinct generated outputs matched their original consumer test outcomes. These small samples do not establish statistical significance or a general speed improvement.

Distribution SHA-256

11c0a735b9730db6d0b635d3440a22891d79e881bb4dd7682c99210b367a2bd4  code_towel-1.947-py3-none-any.whl
1feed54607c7fcb108e7664eb7e193fdd22a0d9a5b5763f79b36c50115efe45b  code_towel-1.947.tar.gz

Install from PyPI: pip install "code-towel[format,types]==1.947".

Towel 1.946

Choose a tag to compare

@ericeallen ericeallen released this 19 Oct 14:50

Towel 1.946 adds extraction of fresh outputs from supported conditional blocks, exact constant-occurrence matching, fewer unnecessary thunk lambdas, stronger typing and lifetime checks, and candidate-pair statistics through --stats.

This release also reuses successful source-correspondence proofs for explicitly owned immutable trees within one analysis. Caller-owned trees and materialization retain fresh proofs, and mutation protections remain in place. Cache enabled/disabled comparisons produced identical Python output across 28 example files, including 23 transformed files.

Source: a1355abe04e250355812b1b31a25f3be7a749064.

Exact-commit CI passed all four jobs: quality and the full Python 3.11 / 3.12 / 3.13 suites. Those suites passed 10,587 / 10,771 / 10,754 tests, plus 45 subtests each, with 93% / 94% / 94% coverage. The watchdog test passed in hosted CI. Fresh local checks also passed strict typing, formatting, lint, security and dependency auditing, documentation checks, and six clean-wheel installations with real transformations and behavior comparisons (bare and with extras on each supported Python).

No full-command performance improvement is claimed for the new memo. Historical timings and their source identities remain documented.

Changes and evidence · Known limitations

Distribution SHA-256:

090c158f8dbd6795dbbe7e18d0bcffbbb884141f16d04100663c8d4ccc45c0cd  code_towel-1.946-py3-none-any.whl
103a272f9def89e84f198a1007947fd45a9302132dc9158d69a47b30c9f6d52c  code_towel-1.946.tar.gz

Towel 1.792

Choose a tag to compare

@ericeallen ericeallen released this 08 Oct 12:19

Towel 1.792 strengthens extraction correctness and adds a scoped escape hatch for reflection-sensitive code.

  • Add # towel: no-extract immediately after a function signature colon to protect that definition and nested bodies.
  • Preserve class-alias lookup and argument lifetimes; document why these can require helper parameters or suppliers.
  • Decline tiny straight-line extractions whose interface and call wrappers outweigh the shared work.
  • Tighten checker-context handling and reuse immutable analysis facts within bounded lifetimes.

The frozen candidate passed local Python 3.11–3.13 gates, clean-wheel smokes, full self-refactoring tests and two 2,000-seed fuzz families. Corpus results: 88 matching PASS, 46 NO_CHANGE, two documented warning-location regressions and five controlled zero-write refusals among 141 pinned projects. PASS means matching selected-context outcomes; 19 projects had baseline failures and three used explicit typing fallbacks. Six scoped markers resolved all 12 warning-location failures in separate full-suite controls.

Complete default CLI performance on Packaging 26.3: four runs per version; 1.772 averaged 39.36 seconds and 1.792 averaged 39.71 seconds (0.9% slower, with about 2.8% variation within each version). No material speed difference was demonstrated on this workload.

Exact-commit CI passed all four jobs, including tests on Python 3.11, 3.12 and 3.13 with 93% coverage: https://github.com/ericeallen/towel/actions/runs/37717067794

code-towel 1.772

Choose a tag to compare

@ericeallen ericeallen released this 27 Sep 03:16

code-towel 1.772

Validated September 26, 2026, at the end of audit rounds three and four.

Tests at 2b399ef and, as CI runs them (coverage, Linux link mode), at c3d062a:
3.11 7,751 passed; 3.12 7,882 passed; 3.13 7,899 passed; just check passes.
src/towel differs since 2b399ef only in one corrected docstring, and GitHub
CI passed the full suite on this commit.

Distributions built from a clean clone of this commit:
code_towel-1.772-py3-none-any.whl
sha256 4af0f6067d830e396aecf82320d69cb82343a848f24b7d1f3e2a152018605683
code_towel-1.772.tar.gz
sha256 69735c69497a6d2395bbb952ddedf5c050936fa8622499726cc3748a8a525a58
Wheel, sdist and src/towel agree file for file; twine check --strict
passes; the wheel imports on 3.11, 3.12 and 3.13, bare and with extras.

Corpus, 141 projects, typed and --cross-module, Python 3.12:
90 PASS, 45 NO_CHANGE, 6 import-problem refusals.

No fifth audit round was run; see docs/DECISIONS.md, "1.772 ships
without a clean audit round".

Towel 1.732.post1

Choose a tag to compare

@ericeallen ericeallen released this 19 Sep 20:52

Documentation-only follow-up to Towel 1.732.

  • Correct all 22 repository-relative README links with absolute GitHub URLs pinned to this release, so documentation links work from PyPI.
  • Add regression checks that reject relative file links, stale release tags, and missing documentation targets.
  • Record the publication order: GitHub commit/tag, CI and documentation verification before PyPI upload, followed by remote artifact and installation checks.

The Python implementation and dependency pins are byte-for-byte unchanged from 1.732. The package remains beta, supporting Python 3.11–3.13 on macOS and Linux.

pip install --upgrade code-towel==1.732.post1

The exact wheel passed six fresh installations across Python 3.11–3.13, with and without formatting/typing extras. The wheel's description was checked with PyPI's Markdown renderer; its 22 documentation links and anchors were verified against the published GitHub tag.

Full changelog · Known limitations

Towel 1.732

Choose a tag to compare

@ericeallen ericeallen released this 19 Sep 20:41

Towel 1.732 is a beta release for Python 3.11–3.13 on macOS and Linux.

Since 1.618:

  • Reuse existing functions when their bodies match repeated code.
  • Format generated code with your project's optional formatting tools, and infer and verify helper annotations with mypy or Pyright.
  • Check the complete original project before typed refactoring, then verify prospective changes together with unchanged consumers. Existing type errors abort the run; fix them or explicitly use --no-types.
  • Strengthen binding, import, renaming, process-isolation, recovery, and type-checking safety.
  • Add controls for large projects and regression coverage for the corrected ecosystem test harness.

Install or upgrade:

pip install --upgrade code-towel==1.732
# Optional formatting and typing tools:
pip install --upgrade "code-towel[format,types]==1.732"

The command is towel; the PyPI package named towel is unrelated.

Validation: the full suite passes on Python 3.11–3.13, with approximately 93% coverage. Six fresh wheel installations passed CLI and actual refactoring checks, with and without optional tools. The 141-project behavioral corpus, explicitly using --no-types, combines a complete run and three corrected-environment reruns: 119 PASS, 19 NO_CHANGE, and three documented incompatibilities involving frame, traceback, or source inspection. Matching upstream failures remain visible; the typed path has separate integration coverage.

Review generated changes and run your project's tests before adopting them. Type-parameter inference remains future work.

The PyPI README contains repository-relative documentation links that do not resolve there. Use the direct GitHub documentation links below. The package contents and README text are unaffected.

Full changelog · Known limitations · Validation scope

Towel 1.618

Choose a tag to compare

@ericeallen ericeallen released this 17 Sep 04:15

Towel 1.618 — the follow-up to 1.414.

Changed

  • Relative-by-default cross-file imports. A cross-file helper is imported relatively (from .module import helper), which stays valid when an out-of-place refactor is adopted back into its real location. An absolute import is used only when a packaging marker (pyproject.toml / setup.*) anchors the module name, preserving the previous behavior for in-place refactoring of a packaged project.
  • Cycle-avoiding cross-file helper placement. When a shared block spans modules, the helper is hosted in a module the others already import rather than adding a back-edge that would close an import cycle. The extraction is declined only when no placement is safe (a genuine pre-existing cycle), instead of always hosting the helper in the first module and giving up whenever that would cycle.
  • Trivial forwarding helpers are no longer proposed. A block whose helper body would be a single raise, a return of one call, or a bare call adds indirection without sharing logic. Construct the engine with skip_trivial_helpers=False to restore the old behavior.

Fixed

  • The rename tool no longer refuses a module merely because it contains a local variable or parameter named vars, globals, locals, eval, or exec; it flags only a genuine reference to the builtin.

Verification

Full test suite on Python 3.11, 3.12, and 3.13. The standing 91-project ecosystem check passes identically before and after transformation: 75 pass, 13 produce no proposal, 3 documented frame-sensitive cases, 0 broken.


Install: pip install code-towel==1.618 · PyPI · Full changelog

1.414 (Beta)

Choose a tag to compare

@ericeallen ericeallen released this 15 Sep 22:12
pip install code-towel==1.414

First release prepared under the open-source audit. Beta: the engineering and
evidence are strong, but Towel rewrites source code and has documented
limitations it cannot always detect, so preview, review the diff, and run the
affected project's own tests.

Added

  • Cross-file refactoring with import-root inference for setuptools, Hatch,
    Flit, Poetry, and pdm project layouts.
  • towel rename-helpers: a JSON inventory of extracted helpers and an atomic,
    checked rename batch, intended to be driven by a coding assistant.
  • towel dry --exclude DIR to leave a directory out of directory mode.
  • A pre-run scan that warns, before refactoring a directory, about modules that
    inspect frames or tracebacks, attribute warnings by stacklevel, or read
    source through inspect.getsource.
  • A standing ecosystem check over 91 public projects
    (scripts/ecosystem_check.py, just ecosystem), run weekly in CI.
  • Fork-based parallel analysis, enabled by a timed probe and capped by
    available memory, with a per-worker watchdog so a killed run leaves no
    workers behind. TOWEL_WORKERS controls it.

Changed

  • Every accepted proposal is verified by instantiating the helper with each
    call site's arguments and comparing against the block it replaces, up to
    renamed binders. Arguments that could have observable effects or fresh
    identity are evaluated inside the helper at their original position.
  • Analysis is memoized by block structure and shares parsed graphs by
    reference, checked under TOWEL_CHECK_AST_IMMUTABLE=1.
  • Minimum Python is 3.11; the matrix covers 3.11 through 3.13.

Fixed

  • A large set of soundness and scope defects found by adversarial batteries and
    the ecosystem check, each now covered by a fixture and a row in
    docs/ADVERSARIAL_REVIEW.md.

Notes

  • The PyPI releases 1.0.0–1.0.4 are yanked for broken import handling and
    are not a recommended installation target.

See the changelog, quick start, and known limitations.