Skip to content

fix(common): load the expanded abbreviation set instead of assigning to list.extend - #16109

Open
udsy19 wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
udsy19:fix/en-char-parser-expanded-abbreviations
Open

fix(common): load the expanded abbreviation set instead of assigning to list.extend#16109
udsy19 wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
udsy19:fix/en-char-parser-expanded-abbreviations

Conversation

@udsy19

@udsy19 udsy19 commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

What does this PR do ?

Makes the expanded abbreviation set actually load, so ENCharParser(abbreviation_version='expanded') stops returning None.

Collection: Common

Fixes #16108.

Changelog

clean_abbreviations(version="expanded") assigned to list.extend instead of calling it:

elif version == "expanded":
    abbbreviations.extend = ABBREVIATIONS_EXPANDED

list.extend is read-only, so this raises AttributeError: 'list' object attribute 'extend' is read-only. clean_abbreviations is on the unconditional path inside clean_text, and
CharParser._normalize wraps clean_text in except Exception: return None; AudioText then treats
the None token list as a filtered sample. The result is that
ENCharParser(abbreviation_version="expanded") silently drops every utterance — including
utterances with no abbreviation in them — and the dataset loads zero samples with no traceback.

The fix builds a new list rather than mutating in place. abbbreviations aliases the module-level
ABBREVIATIONS_COMMON, so the obvious repair abbbreviations.extend(ABBREVIATIONS_EXPANDED) would
permanently grow that global and leak the expanded abbreviations into every later version=None and
version="fastpitch" call in the same process.

elif version == "expanded":
    abbbreviations = ABBREVIATIONS_COMMON + ABBREVIATIONS_EXPANDED

Scope: one line in cleaners.py plus a new unit-test module. version=None and version="fastpitch"
behaviour is unchanged.

Testing

New tests/collections/common/test_preprocessing_cleaners.py (8 unit tests). No existing test module
imported cleaners or ENCharParser.

  • Expansion: "expanded" now expands both the common abbreviations (mr.mister) and the
    expanded-only ones (ltd.limited).
  • Controls: version=None and version="fastpitch" are asserted unchanged; both pass before and
    after the fix.
  • No shared state: ABBREVIATIONS_COMMON / ABBREVIATIONS_TTS_FASTPITCH are unmodified after an
    "expanded" call, a later version=None call does not gain the expanded entries, and two
    ENCharParser instances stay independent regardless of construction order.

Results on this branch:

state result
before the fix 6 failed, 2 passed (AttributeError: 'list' object attribute 'extend' is read-only; assert None == [9, 6, 13, 13, 16])
with abbbreviations.extend(ABBREVIATIONS_EXPANDED) instead 3 failed, 5 passed — exactly the three state-leakage tests fail
with this fix 8 passed

The middle row is deliberate: the tests are written so that a fix which expands correctly but mutates
the module-level list still fails.

Wider run on this branch — tests/collections/common/test_preprocessing_cleaners.py,
tests/collections/asr/test_asr_ctcencdec_model.py, tests/collections/common/tokenizers:
18 passed, 48 skipped.

Style: black 24.10.0 and isort 5.13.2 (repo settings, line length 119) report no changes;
flake8 --config .flake8.other exits 0; pylint --rcfile .pylintrc.other rates cleaners.py 10.00/10;
pre-commit run --from-ref main --to-ref HEAD passes.

No documentation change: abbreviation_version is not documented in docs/, and this restores the
documented-by-signature behaviour rather than changing an API.

GitHub Actions CI

Trusted PRs run automatically through copy-pr-bot. For an untrusted PR, a maintainer can trigger CI by commenting
/ok to test <head-sha>; repeat this after a new push if the PR remains untrusted.

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you add or update any necessary documentation?
  • Does the PR affect components that are optional to install? (Ex: Numba, Pynini, Apex etc)
    • Reviewer: Does the PR have correct import guards for all optional libraries?

PR Type:

  • New Feature
  • Bugfix
  • Documentation

`clean_abbreviations(version="expanded")` assigned to `list.extend` instead
of calling it, which raises `AttributeError: 'list' object attribute 'extend'
is read-only`. `CharParser._normalize` wraps `clean_text` in a bare
`except Exception: return None`, and `AudioText` treats a `None` token list as
a filtered sample, so every utterance parsed by
`ENCharParser(abbreviation_version="expanded")` was silently dropped -
including utterances containing no abbreviation at all.

Build a new list instead of mutating in place: the local name aliases the
module-level `ABBREVIATIONS_COMMON`, so an in-place `extend()` would leak the
expanded entries into every later `version=None`/`"fastpitch"` call in the
process.

Adds unit tests covering both the expansion and the absence of cross-call and
cross-instance state leakage.

Signed-off-by: Udaya Tejas <udayatejas2004@gmail.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 18, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@svcnvidia-nemo-ci svcnvidia-nemo-ci added the waiting-on-maintainers Waiting on maintainers to respond label Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ENCharParser(abbreviation_version='expanded') returns None for every input

2 participants