Repository navigation
FIX Validate LeetspeakConverter custom_substitutions and match keys case-insensitively - #3295
Merged
Roman Lutz (romanlutz) merged 2 commits intoOct 18, 2026
Conversation
…ase-insensitively Characters are looked up in lowercase, so uppercase keys never matched, multi-character keys could never match, and an empty replacement list raised IndexError on the first matching character. Key custom substitutions by lowercase character and reject keys and values that cannot be applied. Fixes microsoft#3293 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Roman Lutz (romanlutz)
enabled auto-merge
October 18, 2026 07:42
Roman Lutz (romanlutz)
approved these changes
Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #3293.
LeetspeakConverter.convert_word_asynclooks each character up aschar.lower(), butcustom_substitutionswas used without validation. An uppercase key such as{"A": ["4"]}never matched, a multi-character key such as{"th": ["7"]}could never match, and an empty replacement list such as{"e": []}was accepted and then raisedIndexErroron the first matching character.The converter now validates custom substitutions when it is created:
{"A": ["4"]}replaces bothAanda, the same way the default substitutions already apply to both cases."a"and"A"), or a value that is not a non-empty list of strings raisesValueError.Custom substitutions with lowercase single-character keys keep their output and their identifier: the
custom_substitutions_hashis computed from the same mapping as before, so existing hashes do not change.{"A": ["4"]}now gets the same identifier as{"a": ["4"]}, because the two convert identically. An emptycustom_substitutionsdict still falls back to the defaults.Tests and Documentation
test_leetspeak_converter.py:{"A": ["4"]}and{"a": ["4"]}share an identifier.ValueErrorat construction, in both modes: an empty list, a string value, a non-string replacement, a multi-character key, an empty key, and keys differing only in case.main, all 15 new tests fail. With this change, all of them pass.pytest tests/unit/converter/test_leetspeak_converter.py: 24 passed.pytest tests/unit/converter tests/unit/registry tests/unit/backend/test_converter_service.py: 3735 passed, 38 skipped.ruff check,ruff formatandty checkpass on the changed files.git diff --checkis clean.🤖 Generated with Claude Code