Skip to content

Add runtime i18n hooks for validation messages - #547

Open
aleksandr-kotlyar wants to merge 16 commits into
alecthomas:masterfrom
aleksandr-kotlyar:issue-73
Open

aleksandr-kotlyar wants to merge 16 commits into
alecthomas:masterfrom
aleksandr-kotlyar:issue-73

Conversation

@aleksandr-kotlyar

@aleksandr-kotlyar aleksandr-kotlyar commented Jul 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds runtime i18n support for Voluptuous built-in validation messages.

This PR introduces gettext-compatible hooks so applications can translate Voluptuous error messages without Voluptuous shipping production translation catalogs.

Main changes:

  • Add configure_i18n() for loading gettext catalogs from an application-provided localedir
  • Add set_gettext() for injecting a custom translation callable
  • Add gettext_scope() for temporary context-local translation overrides
  • Route built-in user-facing validation messages and the Invalid.__str__ message/error-type format through the i18n hook
  • Keep the error path suffix, for example @ data[...], untranslated so existing tooling can continue to parse it
  • Document the i18n API in the README
  • Add test-only locale fixtures and packaging checks to ensure fixture catalogs are not treated as production catalogs

Voluptuous intentionally does not ship production translation catalogs in this PR. Applications are expected to provide their own gettext catalogs.

Also includes a few small validation correctness fixes covered by tests while touching error-message paths:

  • enum scalar schemas
  • set element transforms
  • non-numeric Number input
  • Schema.extend(Schema(...))
  • Invalid.__repr__

Resolves #73.

@aleksandr-kotlyar
aleksandr-kotlyar marked this pull request as ready for review July 5, 2026 10:35
@aleksandr-kotlyar aleksandr-kotlyar changed the title Add runtime i18n support and validation fixes Add runtime i18n hooks for validation messages Jul 5, 2026
@aleksandr-kotlyar

Copy link
Copy Markdown
Contributor Author

Hi @alecthomas, sorry for the ping.

This PR is ready for review when you have time. It keeps the change focused on runtime i18n support for validation messages, includes regression coverage, and the branch is up to date with master.

I would appreciate any feedback on whether this approach matches the project’s expected API and packaging semantics, especially around configure_i18n(), set_gettext(), gettext_scope(), and locale files.

Thanks!

@alecthomas

Copy link
Copy Markdown
Owner

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0d33e696b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread voluptuous/_i18n.py Outdated
return list(languages)


_default_translator: TranslateFunc = _gettext.gettext

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep the unconfigured translator independent of process gettext

When a host application has called gettext.textdomain()/bindtextdomain() (and selected a language through its environment), _gettext.gettext consults that process-global domain, so Voluptuous messages become translated—or collide with unrelated catalog entries—even though none of these new configuration APIs were called. This also lets another component's later domain changes alter validation output unexpectedly, contrary to the documented English default; initialize this to an identity translator and reserve gettext catalog lookup for configure_i18n().

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 1ffe417: the unconfigured default translator is now an identity function, and gettext catalog lookup is only used via configure_i18n(). Added a regression test covering process-global gettext isolation.

@aleksandr-kotlyar

Copy link
Copy Markdown
Contributor Author

Hi @alecthomas, a gentle follow-up: the Codex review feedback has been addressed in 1ffe417, with a regression test covering gettext isolation. Could you take a look when you have time? Thanks!

This branch has not been deployed

No deployments
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.

Make all messages i18n friendly

2 participants