GNOME Bugzilla – Bug 515884
gnome-about crashed with KeyError in make_info_label()
Last modified: 2008-03-24 22:31:01 UTC
The bug has been opened on https://bugs.launchpad.net/ubuntu/+source/gnome-desktop/+bug/186118 "just tried to run gnome-about and it crushed Traceback (most recent call last):
+ Trace 188887
about = GnomeAbout ()
self.create_ui ()
info_labels = map (make_info_label, self.system_infos)
label.set_markup (_("<b>%(name)s:</b> %(value)s") % infos_dict)
That's a bug in the translation: #: ../gnome-about/gnome-about.in:865 msgid "%(name)s: %(value)s" msgstr "%(имя)s: %(значение)s" "%(name)s" shouldn't be translated. We have a comment for this in the code, but it doesn't appear in po files. Fixing this issue and moving to l10n.
Fixed, thanks
+ Trace 192527
There's no need to have the variable inside of the gettext function. Assume param = "foo". If you use _("some %s string" %param) then you will be looking up the interpolated string "some foo string" in the message catalog. The message catalog should have "some %s string" translated. Therefore, % should always be outside of _().
Og: % is already outside of _()
Hey Vincent, I'm refering to %(value)s
Oh: it's python. %(value)s is a way to know which %s we want in infos_dict. There's a translator comment about this, but it doesn't appear in the po files for some reason.
Yup... the whole thing should not be marked for translation.
Og, I don't understand: the string is like "%s: %s". That's the same thing, so it should be marked for translation. What's the string you propose instead? Remember that we need to specify which one is the name and which one is the value.
Hey Vincent, sorry for the confusion. First off, I was saying that in a normal case where you have "foo: %s" % bar, there is no need to include bar in gettext _(). So instead of _("foo: %s" % bar), it should be _("foo: %s") % bar. Now, the problem at hand. label.set_markup (_("<b>%(name)s:</b> %(value)s") % infos_dict) Am I correct that this is responsible for displaying the list of names of all contributors in the about dialog? If so, we shouldn't translate %(name)s and %(value)s... looking at the comment right above line 920 of /usr/bin/gnome-about: # Translators: %(name)s and %(value)s should not be translated: # it's a way to identify a string, so just handle them like %s so my suggestion, if I'm not mistaken so far is: label.set_markup ("<b>%(name)s:</b> %(value)s" % infos_dict)
(In reply to comment #9) > Hey Vincent, sorry for the confusion. First off, I was saying that in a normal > case where you have "foo: %s" % bar, there is no need to include bar in gettext > _(). So instead of _("foo: %s" % bar), it should be _("foo: %s") % bar. Perfectly agree. Note that the "% infos_dict" part is not in _(). So we're saying the same thing so far. > Now, the problem at hand. > > label.set_markup (_("<b>%(name)s:</b> %(value)s") % infos_dict) > > Am I correct that this is responsible for displaying the list of names of all > contributors in the about dialog? I don't think it's about the names of contributors, but about displaying the strings displayed by "gnome-about --gnome-version". > If so, we shouldn't translate %(name)s and > %(value)s... looking at the comment right above line 920 of > /usr/bin/gnome-about: > > # Translators: %(name)s and %(value)s should not be translated: > # it's a way to identify a string, so just handle them like %s > > so my suggestion, if I'm not mistaken so far is: > > label.set_markup ("<b>%(name)s:</b> %(value)s" % infos_dict) That's wrong: some languages might want to have "%(value)s - %(name)s". It has to be translatable. Really, it's like "%s: %s". Let me repeat this again "%(name)s" is a way in python to say "%s". That's the same thing. Forget about the "(name)" part. It's just here to say that we want the name part of infos_dict.
I know this. :) But how, could someone know how to translate %(name)s and %(value)s then without any context? So if we were to "imagine" this as (_("<b>%s:</b> %s") % infos_dict) I want to believe (and I haven't checked it myself) that infos_dict has been translated somewhere else as infos_dict = { _('foo'): _('translation for foo'), _('bar'): _('translation for bar') } then having %(name)s and %(value)s inside gettext method is not necessary, as we both agree, and the translating the dictionary would make a whole lot of sense.
Og: you don't translate %(name)s. You keep %(name)s in the translation. That's the whole point. The string %(name)s has been translated in the code before.
Vincent: I *know* we're not supposed to translate it... but the strings *are* inside the gettext method... so here's my question: Why are %(name)s and %(value)s inside the gettext method? The translation has already taken place.
Og: there's certainly something I don't understand here. It's like "%1$s: %2$s". What's the difference? We still want to translate the string so it can be displayed as "%2$s - %1$s" in some language.
Vincent: the translation should be done already in infos_dict by the time it arrives at that specific piece of code. In /usr/bin/gnome-about +935 we have the function get_system_infos which returns: return [ (_("Version"), version), (_("Distributor"), infos["distributor"]), (_("Build Date"), cleanup_date (infos["date"])) ] All strings are translated... and assigned to self.system_infos (+837)... good. Then move on to +929... info_labels = map (make_info_label, self.system_infos) make_info_label is a function (+913) that takes an already translated list (self.system_infos). '''System info labels''' def make_info_label (info): if not info[1]: return False label = gtk.Label () infos_dict = {"name": info[0], "value": info[1]} # Translators: %(name)s and %(value)s should not be translated: # it's a way to identify a string, so just handle them like %s label.set_markup (_("<b>%(name)s:</b> %(value)s") % infos_dict) Soooo... what is the point of marking %(name)s and %(value)s for translation if their "content" has already been translated? Hope this is a bit clearer.
(In reply to comment #15) > Soooo... what is the point of marking %(name)s and %(value)s for translation if > their "content" has already been translated? We're not marking %(name)s and %(value)s for translation. We're marking "%s: %s" for translation.
> We're not marking %(name)s and %(value)s for translation. We're marking "%s: > %s" for translation. Yes, I understand that... but you're missing the bigger picture: %s and %s are already translated... they are info[0] and info[1], which in turn are self.system_infos which in turn is return [ (_("Version"), version), (_("Distributor"), infos["distributor"]), (_("Build Date"), cleanup_date (infos["date"])) ] see?
Og, I know they are already translated. What I want to translate is "%s: %s" and nothing all. I want languages to be able to display "2.22.0 Version" instead of "Version: 2.22.0".
Vincent: That is a different picture then... Because "Version" for instance is already translated as I mentioned before (and you already know). However, label.set_markup (_("<b>%(name)s:</b> %(value)s") % infos_dict) will allow translators to translate Version and its Value, and then render them as Version: Value... not "2.22.0 Version" as you're suggesting... or is there some other hackery that I'm missing?
(In reply to comment #19) > However, > label.set_markup (_("<b>%(name)s:</b> %(value)s") % infos_dict) will allow > translators to translate Version and its Value, and then render them as > Version: Value... not "2.22.0 Version" as you're suggesting... or is there some > other hackery that I'm missing? No, it will allow translators to translate "<b>%s</b>: %s", and nothing else. It will then substitute a %s with the name in infos_dict and the other one with the value in infos_dict. And then, it will display the whole string.
why translators will need to translate "<b>%s</b>: %s"???? The real string was translated before, i dont think that is a good idea to translating it the way you are suggesting, but if so, something looks very very weird. I cant see a reason to have any changes from Version: value to "2.22.0 Version" That will show some inconsistency if everyone changes the way a message is showed to the user. label.set_markup ("<b>%(name)s:</b> %(value)s" % infos_dict) is the right thing to do IMHO, because name is a placeholder for a key in the dict, not a string to be translated.
"%s: %s" has to be translated to "%s : %s" in French. I know it's still "%s: %s" for many languages, but not for all languages.
One thing I don't understand is, if I run gnome-about inside jhbuild env, it does *not* crash, it runs perfectly. It only crashes in Ubuntu context.
Jonh: could be the translation in Ubuntu that's wrong...
I have personally (manually) imported the translation of gnome-desktop (which contains gnome-about, straight from upstream GNOME) over this past weekend. The translation *should* be the same as upstream now. Jonh, can you confirm this? Thanks Og
Og, I'm almost sure that the problem is on Ubuntu. So, we can continue this thread there, or, at least, in l10n mailing list.
The problem is in Ubuntu only. The portuguese from Portugal translation in Launchpad was wrong and somehow this was causing problems for the brazilian locale too. I should have double checked it before assigning it to you guys, please accept my apologies.