Bug 53350 - localization.translation() does not work in UDM Hooks
localization.translation() does not work in UDM Hooks
Status: NEW
Product: UCS
Classification: Unclassified
Component: UDM (Generic)
UCS 4.4
Other Linux
: P5 normal (vote)
: ---
Assigned To: UMC maintainers
UMC maintainers
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2021-05-28 18:28 CEST by Arvid Requate
Modified: 2021-05-28 21:20 CEST (History)
1 user (show)

See Also:
What kind of report is it?: Development Internal
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arvid Requate univentionstaff 2021-05-28 18:28:17 CEST
In a project I had a hard time working with the translation of messages issued from a UDM hook.

For example with this import:

from univention.admin import localization
translation = localization.translation('univention/admin')
_ = translation.translate

The following exception doesn't appear translated in UMC:

raise univention.admin.uexceptions.noLock(_('The attribute %r could not get locked.') % (obj_name,))

The exact same exception message gets translated just fine when raised from univention.admin.allocators though.

While debugging I had the impression that

1. It's not required to import localization, load translation or define _ at all.
2. getlocale(LC_MESSAGES) returns (none, none) in the Hook.

That makes me question if this works at all, even if I would supply a dedicated .mo file for the udm_hook.
Comment 1 Florian Best univentionstaff 2021-05-28 21:09:25 CEST
>>> import locale
>>> locale.setlocale(locale.LC_MESSAGES, 'de_DE.UTF-8')
'de_DE.UTF-8'
>>> from univention.admin import localization
>>> _ = localization.translation('univention.admin').translate
>>> _('The attribute %r could not get locked.')
u'Das Attribut %r konnte nicht gesperrt werden.'
Comment 2 Florian Best univentionstaff 2021-05-28 21:20:24 CEST
Could you re-test with:

diff --git management/univention-directory-manager-modules/modules/univention/admin/hook.py management/univention-directory-manager-modules/modules/univention/admin/hook.py
index 764b5a176c..c910efb100 100644
--- management/univention-directory-manager-modules/modules/univention/admin/hook.py
+++ management/univention-directory-manager-modules/modules/univention/admin/hook.py
@@ -56,18 +56,24 @@ def import_hook_files():
        """
        Load all additional hook files from :file:`.../univention/admin/hooks.d/*.py`
        """
+       global _  # don't allow syntax to overwrite our global _ function.
+       gettext = _
        for dir_ in sys.path:
                hooks_d = os.path.join(dir_, 'univention/admin/hooks.d/')
                if os.path.isdir(hooks_d):
                        hooks_files = (os.path.join(hooks_d, f) for f in os.listdir(hooks_d) if f.endswith('.py'))
                        for fn in hooks_files:
                                try:
+                                       x = sys.modules[__name__].__dict__.copy()
+                                       x.pop('_', None)
                                        with io.open(fn, 'rb') as fd:
-                                               exec(fd.read(), sys.modules[__name__].__dict__)
+                                               exec(fd.read(), x)
                                        ud.debug(ud.ADMIN, ud.INFO, 'admin.hook.import_hook_files: importing %r' % (fn,))
                                except Exception:
                                        ud.debug(ud.ADMIN, ud.ERROR, 'admin.hook.import_hook_files: loading %r failed' % (fn,))
                                        ud.debug(ud.ADMIN, ud.ERROR, 'admin.hook.import_hook_files: TRACEBACK:\n%s' % traceback.format_exc())
+                               finally:
+                                       _ = gettext
 
 
 class simpleHook(object):