Skip to content

fix(i18n-es): correct fuzzy-matcher strandings in Spanish catalog - #42808

Merged
rusackas merged 1 commit into
apache:masterfrom
glaterza:fix/i18n-es-fuzzy-strandings
Aug 7, 2026
Merged

fix(i18n-es): correct fuzzy-matcher strandings in Spanish catalog#42808
rusackas merged 1 commit into
apache:masterfrom
glaterza:fix/i18n-es-fuzzy-strandings

Conversation

@glaterza

@glaterza glaterza commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

SUMMARY

39 entries in the Spanish catalog carry a translation that renders a different string
than the English msgid
. Several render the opposite of the source:

msgid Spanish shown to users What it actually says
Select all Deseleccionar todo Deselect all
Data Export Options Opciones del gráfico Chart options
Export All Data Borrar todos los datos Delete all data
Sign in No está en Not in
Not Contains Denunciar un contenido Report content
Equals Secuencial Sequential
True MAR Tue
Client Secret Selección de columna Column select

Select all is the label on the button whose handler is handleSelectAll()
(Select.tsx:654) — so a user clicking a control that reads "Deselect all" selects
every option. Sign in renders twice on the login page, as the card title and the
submit button.

These are legacy strandings. The old pybabel update fuzzy matcher copied a translation
from a similar-looking msgid; where it guessed wrong, the copied Spanish stayed behind.
babel_update.sh has since moved to --no-fuzzy-matching, so this is cleanup of damage
already done rather than an ongoing source of new breakage.

They are live in the UI: both the frontend and backend builds compile with --use-fuzzy,
so a #, fuzzy entry is displayed, not withheld. This is also why msgfmt never caught
them — it skips format checking on fuzzy entries.

This is the follow-up to #42728, which fixed the 75 entries whose format placeholders
didn't match. That defect class had a mechanical proof (msgfmt). This one does not: the
placeholders here are fine, so the errors are only visible to someone who reads both
languages.

How these were found, and where the method fails

A script made the class tractable, and it is worth stating how it works so the change is
auditable rather than "trust me":

The fuzzy matcher copies a translation from another entry. When it guesses wrong, the
copied Spanish usually still sits on the entry it was correctly translating. So a fuzzy
entry whose msgstr is byte-identical to another entry's, where the two msgids are
textually dissimilar, is a stranding suspect.

The detector under-reports, and this is a structural property, not a tuning problem.
When a legitimate synonym shares the stranded translation, the pair scores as similar and
never surfaces. Three entries in this PR were missed that way:

Missed entry Masked by
Select all → "Deseleccionar todo" Deselect all → "Deseleccionar todo" (correct)
Data Export Options → "Opciones del gráfico" Chart Options → "Opciones del gráfico" (correct)
Revoke → "Eliminar" Remove → "Eliminar" (correct)

The first two were caught only by opening the running UI and looking. The third is left for
a follow-up. So: the detector is a lead generator, not a proof, and this PR is not a
claim that the catalog is clean.

Every entry here was confirmed by reading its call site, which changed several of the
translations. Entries with no reachable call site were left alone rather than guessed at
(e.g. beta, whose only occurrences are in test files).

Scope notes

  • The ag-Grid table filter menu is corrected as a whole. Three entries surfaced
    individually, then turned out to sit in one dropdown (AgGridTable/index.tsx:556-587)
    where most neighbours were also stranded. Fixing 3 of 13 in the same menu would have
    been incoherent. Note this table is behind AG_GRID_TABLE_ENABLED; Select all and
    Select All are not flag-gated and render in the core Select component.
  • Every shared msgid was checked for other call sites before being touched — to,
    Group, Select All, Select all.
  • The Datastore connection error listed the BigQuery roles and permissions instead
    of the Datastore ones (db_engine_specs/datastore.py).
  • Referrer is deliberately left untranslated. It is Log.referrer — the HTTP Referer
    URL — in an admin audit view, and this catalog already keeps protocol terms as-is
    (URL, JSON, dttm, Host). It replaces "Actualizar" (Refresh), which was wrong.
  • Feature Not Enabled → "Función no habilitada": funcionalidad is arguably the more
    precise Spanish, but this catalog uses función for the software sense throughout
    (función de desglose, función experimental) and funcionalidad appears nowhere in
    its 4,871 entries. Consistency was chosen over precision; happy to switch.
  • Entries carrying the # Machine-translated via backfill_po.py comment are out of
    scope
    — those are AI drafts awaiting review, a different workflow.

38 #, fuzzy flags are cleared, since the corrected entries are now confirmed
translations. Deleted %s was already un-fuzzy — confirmed, and wrong.

Deliberately not included, to keep this reviewable: two recently-added features
(API keys, semantic layers/views) shipped with almost entirely stranded catalogs and want
their own PR.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Captured on a local instance running apache/superset:f65b424, this PR's base commit.

Before After
Login page Sign in renders as "No está en" (Not in) on both the card title and the submit button "Iniciar sesión"
Explore → export menu "Opciones del gráfico" → "Borrar todos los datos" / "Invertir página actual" "Opciones de exportación de datos" → "Exportar todos los datos" / "Exportar la vista actual"
Multi-select bulk actions "Deseleccionar todo (66)" with 0 selected — the control that selects all "Seleccionar todo (66)"

Login before
01-login
Login After
01-login
Export Menu Before
02-export-menu
Export Menu after
02-export-menu
Select all before
03-select-all
Select all after
03-select-all

TESTING INSTRUCTIONS

The catalog compiles cleanly and no new format errors are introduced:

msgfmt -c --statistics -o /dev/null superset/translations/es/LC_MESSAGES/messages.po
# 3931 translated, 978 fuzzy, 197 untranslated  (was 3893 / 1016 / 197)

To confirm none of the newly-confirmed entries hides a format defect, blanket-clear the
fuzzy flags and recompile — msgfmt only format-checks non-fuzzy entries:

sed -E 's/^#,(.*)fuzzy(.*)$/#,\1\2/' \
  superset/translations/es/LC_MESSAGES/messages.po > /tmp/t.po
msgfmt -c -o /dev/null /tmp/t.po

This reports 4 fatal errors both before and after this change — all pre-existing, in
%s column, %s item, Added to 1 dashboard and %(suggestion)s instead of …. Anything
above 4 would mean new breakage.

To see the strings in the UI, run with the locale set to es, then:

  • Login page — card title and submit button
  • Explore → any chart → ⋮ → Data Export Options — the submenu and its two children
  • Any multi-select (e.g. Explore → Filters → a string column → operator IN) — the
    bulk-action bar at the bottom of the dropdown
  • Settings → Action Log — the Referrer column
  • A table chart's column filter menu (requires AG_GRID_TABLE_ENABLED) — operators,
    Blanks, AND/OR

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

39 entries in the Spanish catalog carried a translation that renders a
different string than the English msgid. These are legacy strandings: the
old `pybabel update` fuzzy matcher copied a translation from a
similar-looking msgid, and where it guessed wrong the copied Spanish stayed
behind. Because both the frontend and backend builds compile with
`--use-fuzzy`, these entries are live in the UI.

Several render the opposite of the source string:

  Select all          -> "Deseleccionar todo"      (Deselect all)
  Data Export Options -> "Opciones del gráfico"    (Chart options)
  Export All Data     -> "Borrar todos los datos"  (Delete all data)
  Sign in             -> "No está en"              (Not in)
  Not Contains        -> "Denunciar un contenido"  (Report content)
  True                -> "MAR"                     (Tue)

`Select all` labels the button whose handler is handleSelectAll(), so a
user clicking "Deselect all" selects every option. The ag-Grid table filter
menu is corrected as a whole, since most of one dropdown was affected. Also
fixes the Datastore connection error, which listed the BigQuery roles and
permissions instead of the Datastore ones.

Every entry was verified against its call site; msgid strings with no
reachable call site were left alone. 38 `#, fuzzy` flags are cleared, since
the entries are now confirmed translations.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added i18n Namespace | Anything related to localization i18n:spanish Translation related to Spanish language labels Aug 5, 2026
@codecov

codecov Bot commented Aug 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 65.79%. Comparing base (f65b424) to head (43311d0).
⚠️ Report is 7 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #42808      +/-   ##
==========================================
- Coverage   65.79%   65.79%   -0.01%     
==========================================
  Files        2842     2842              
  Lines      162132   162157      +25     
  Branches    37159    37163       +4     
==========================================
+ Hits       106677   106691      +14     
- Misses      53391    53397       +6     
- Partials     2064     2069       +5     
Flag Coverage Δ
hive 38.08% <ø> (+<0.01%) ⬆️
mysql 57.90% <ø> (-0.01%) ⬇️
postgres 57.94% <ø> (-0.01%) ⬇️
presto 40.00% <ø> (+<0.01%) ⬆️
python 59.32% <ø> (-0.01%) ⬇️
sqlite 57.58% <ø> (+<0.01%) ⬆️
unit 100.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@glaterza
glaterza marked this pull request as ready for review August 5, 2026 19:23
@bito-code-review

bito-code-review Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Code Review Agent Run #9c00f2

Actionable Suggestions - 0
Filtered by Review Rules

Bito filtered these suggestions based on rules created automatically for your feedback. Manage rules.

  • superset/translations/es/LC_MESSAGES/messages.po - 1
Review Details
  • Files reviewed - 1 · Commit Range: 43311d0..43311d0
    • superset/translations/es/LC_MESSAGES/messages.po
  • Files skipped - 0
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

@rusackas rusackas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is exactly the kind of forensic follow-up #42728 needed. Spot-checked a chunk of these against my own Spanish and they all check out, especially glad to see Select all un-inverted and SSL fixed (it was showing "sql").

One more for the pile while you're in there: Client ID and Slice Id are both still #, fuzzy and share the same stranded string as Line width ("Anchura de la línea"), right next to Client Secret which this PR already caught. Not blocking, happy to see it land as-is or folded in.

LGTM!

@rusackas
rusackas merged commit 55af468 into apache:master Aug 7, 2026
117 checks passed
@glaterza

glaterza commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Oh we deploy on fridays here! ;) Thanks Evan! I'll keep working on this.

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

Labels

i18n:spanish Translation related to Spanish language i18n Namespace | Anything related to localization size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants