Repository navigation
blueprints, stages/authenticator_sms: translate before interpolating - #25993
Merged
BeryJu merged 2 commits intoSep 10, 2026
Merged
Conversation
`_("...".format(...))` interpolates first and then asks gettext for the
result, so the msgid that gets extracted into locale/ can never be matched
at runtime and the translations already shipped for these two strings are
never used. Move the interpolation outside the gettext call, matching what
core/api/applications.py and tenants/api/settings.py already do.
✅ Deploy Preview for authentik-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
BeryJu
approved these changes
Sep 10, 2026
BeryJu
enabled auto-merge (squash)
September 10, 2026 11:01
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #25993 +/- ##
==========================================
- Coverage 91.86% 91.82% -0.04%
==========================================
Files 1169 1169
Lines 75451 75451
Branches 4054 4054
==========================================
- Hits 69310 69285 -25
- Misses 6099 6124 +25
Partials 42 42
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. |
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.
Details
What does this PR change?
Two call sites interpolate a string and then hand the result to
gettext:The
.format_map()runs before_(), so the string that reaches the catalog lookup is"User lacks permission to create authentik_providers_saml.samlprovider", not the msgid"User lacks permission to create {model}". It never matches, and the translations thatare already in
locale/for both of these strings are dead.This moves the interpolation outside the
_()call, which is whatauthentik/core/api/applications.pyandauthentik/tenants/api/settings.pyalready do:Why is this change needed?
The msgids are extracted and translated in every locale, they just can't be reached. From
locale/fr_FR/LC_MESSAGES/django.po:The SMS one is the user-visible half: the OTP text message body always goes out in English,
whatever the brand/user locale is.
How was this tested?
I don't have a full dev environment on this machine, so I checked the thing that actually
breaks rather than the surrounding view code.
gettext_lazy/gettextend up ingettext.GNUTranslations.gettext()against the compiledlocale/<lang>/LC_MESSAGES/django.mo,so I pulled the real
_()expression out of each file withast, evaluated it with_boundto the repo's own compiled
fr_FRcatalog, and compared against themsgstr.Before:
After:
For no-regression I ran the same comparison against the
encatalog on both revisions:That matters for
authentik/core/tests/test_transactional_applications_api.py, which assertson the literal English text of the blueprints message — the output is byte-identical, so it
should still pass.
One note on
blueprints/api.py:_there isgettext_lazy, so.format()on the proxyforces evaluation and returns a plain
strinstead of a lazy object. That's the same shape astenants/api/settings.py, and both messages are built inside a request, so the active languageis already set. In
authenticator_sms/models.pythe annotation is already-> strand bothcallers do
str(self.get_message(token)), so returning a realstris if anything more correct.Linked issues
None.
While grepping for the pattern I found four more instances of it —
policies/password/models.py,providers/oauth2/api/providers.py,sources/ldap/api/sources.py,sources/oauth/views/callback.py(and a handful of
_(f"...")inadmin/files/validation.pyandenterprise/, which xgettext can'textract at all). I left them out because open PRs are currently touching those files and I didn't
want to hand you conflicts over a one-line change. Happy to fold them in here or send a follow-up,
whichever you prefer.
Checklist
make all) — I couldn't run this locally, see above for what I did runmake docs) — no docs affectedAI tools used: Claude Code, to sweep the tree for the
_("...".format(...))pattern and to draftthe ast-based reproduction script. The diff, the verification against the real catalogs, and this
description are mine and I've re-run every output pasted above.