Skip to content

Preserve fitting post-replacement output during modern truncation - #193

Open
emme1t wants to merge 1 commit into
un33k:masterfrom
emme1t:fix/modern-truncation-preserve-fitting-output
Open

Preserve fitting post-replacement output during modern truncation#193
emme1t wants to merge 1 commit into
un33k:masterfrom
emme1t:fix/modern-truncation-preserve-fitting-output

Conversation

@emme1t

@emme1t emme1t commented Sep 12, 2026

Copy link
Copy Markdown

With the modern algorithm, enabling a length limit can change a slug which already fits that limit:

from slugify import slugify

options = dict(
    algorithm="modern",
    word_boundary=True,
    replacements=[("one", "one---")],
    replacement_stage="post",
)

print(slugify("one two", **options))
# one----two
print(slugify("one two", max_length=100, **options))
# one-two

The README specifies that post replacements remain unfiltered. The word-boundary truncation loop drops empty internal tokens, which collapses intentionally repeated delimiters even when the whole output fits. At an exact length limit, the hard-cut branch can also drop an intentionally added trailing delimiter.

Check the final emitted length before truncating. When the entire output fits, return it with the configured separator mapping intact. The length calculation accounts for empty and multi-character separators without constructing an expanded output just to measure it. This change is confined to the modern helper; the default legacy algorithm and public smart_truncate retain their implementations.

Validation on Windows with Python 3.13.13:

  • The original implementation fails 28 new regression subcases covering repeated/boundary delimiters, exact/spare budgets, empty/multi-character separators, word boundaries, and save_order.
  • Full suite: 105 passed, 104 subtests passed. This includes the unchanged legacy suite and its 2,688-case differential comparison against the frozen reference.
  • Strict Mypy, repository-configured pycodestyle and flake8 commands, and git diff --check all pass.

Dojo follow-up: OpenAI Codex assisted with the investigation, patch, regression tests, and this PR description. The reproductions and checks above were executed locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant