Changelog¶
All notable changes to this project are documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.0.0 - 2026-07-14¶
Full modernization. The template syntax, compiled patterns, group numbering, and
serialize()/json() output are identical to 0.3.0 — templates written for
0.3.0 work unchanged. The Python API has a few breaking changes listed below.
Breaking changes¶
Exceptions renamed; all now inherit
ReplusError(wasReplusException):0.3.0
1.0.0
ReplusExceptionReplusErrorUnknownTemplateGroupUnknownTemplateGroupErrorNoSuchGroupNoSuchGroupErrorPatternBuildExceptionPatternBuildErrorKeyError(duplicate template key)DuplicatePatternKeyErrorAssertionError(bad backreference)InvalidBackreferenceErrorRecursionError(cyclic templates)CircularReferenceErrorRepeatedSpecialGroup(never raised)removed
Template errors now raise their specific exception instead of being wrapped in
PatternBuildException: an undefined{{placeholder}}raisesUnknownTemplateGroupError, a bad backreference raisesInvalidBackreferenceError.PatternBuildErroris reserved for patterns that fail to compile.parse()/search()/finditer()arguments after the string are keyword-only.Match.all_group_namesis a tuple (was a list).Replus.patternsis alist[CompiledPattern](was a list of tuples); thegroup_counterandall_groupsengine attributes are gone — that metadata now lives on eachCompiledPattern.Matchis constructed from aCompiledPattern(only relevant if you builtMatchobjects manually).whitespace_noiseinjects a non-capturing group(?:...)(was capturing).Requires Python >= 3.11.
Added¶
Replus.sub(): group-targeted replacement — rewrite the captures of chosen template keys inside every match (literal strings or callables receiving theGroup), leaving the rest of the string untouched. Built for OCR-style normalization. Overlapping targets raise the newOverlappingReplacementError.Replus.finditer(): lazy iterator over raw (unpurged, unsorted) matches.CompiledPattern: frozen dataclass exposing each pattern’s regex, source template, and group metadata.Cycle detection: cyclic template references are rejected at load time with the full cycle path (0.3.0 crashed with
RecursionError).Full type annotations and a
py.typedmarker.100% test coverage (lines and branches), enforced in CI.
Fixed¶
Group.keyno longer mangles user keys that end in_<digit>(e.g.part_2): group keys are recorded at build time instead of reverse-engineered from names.match.groups(key)no longer misses groups after an unnamed{{?:key}}expansion created a numbering gap.whitespace_noisepatterns containing backslashes (e.g.[\s\-]+) no longer raisebad escape.Templates with thousands of placeholders no longer risk
RecursionError: expansion is iterative.Template files load in deterministic (sorted) order.
Loading templates from a dict no longer mutates the caller’s dict.
coverageandpytest-covare no longer runtime dependencies.
Changed¶
Packaging: uv + PEP 621 +
src/layout (was Poetry); single version source.Tooling: ruff (lint + format) and ty (type checking); CI tests Python 3.11-3.14; releases publish to PyPI via trusted publishing.
Docs: rebuilt on Sphinx + Furo + MyST at replus.readthedocs.io.
Internals split into focused modules (
loader,builder,results,engine,exceptions);Match/Groupuse__slots__.
0.3.0 - 2023-09-04¶
Last release of the 0.x line, published to PyPI.