why I get 'msgid' format string unnamed arguments warning, (only) when running mki18n.py for gettext on wxPython

StackOverflow https://stackoverflow.com/questions/23405521

  •  13-07-2023
  •  | 
  •  

Question

Trying to run the mki18n.py script on my Python code, I get a warning on this line:

 >>> dlg = wx.MessageDialog(None, str (_("Attached device is \"%s\",\nschedule file header is for \"%s\"") % (rt_model, line)), _("Device mismatch"), wx.OK | wx.ICON_ERROR)

which then gives this:

warning: 'msgid' format string with unnamed arguments cannot be properly localized:
         The translator cannot reorder the arguments.
         Please consider using a format string with named arguments,
         and a mapping instead of a tuple for the arguments.

The mki18n.py script does not like the presence of the two successive s%, but I am not able to decode what the warning message says. Otherwise (running my program without to care about i18n) I get no errors and that dialog always displays fine.

What is wrong in that line ? (what can be improved ?)

edit By using geni18n.py (and its associated file from the i18nwxapp package) I get the expected result with no error (i.e. generate the .pot file for translation). Still I don't know if there is a problem in my code that geni18n tolerates, or if mki18n has a problem that gets triggered by my particular line of code (?).

Était-ce utile?

La solution

So basically what the message says is that the translator would have difficulties reordering the variables, if he/she needs to. So consider the following:

my_string = "Hello %s, it is %s o'clock." % ('Foo', 'two')

Now assume the translator needs the two first and the Foo second:

translated_string = "It is %s o'clock, Mr. %s" % ('Foo', 'two')

Without using format string with named arguments, the Foo would still go into the first %s, thus giving you:

print translated_string
# Output: It is Foo o'clock, Mr. two.

To solve the problem, simply use named arguments. So the above example would be:

my_string = "Hello %(person)s, it is %(time)s o'clock." % ({
    'person':'Foo', 
    'time':'two'
})

translated_string = "It is %(time)s o'clock, Mr. %(person)s" % ({
    'person':'Foo', 
    'time':'two'
})

This way, the translator can put person and time where ever he/she wants. It also gives them an idea, what the variable is about, which they wouldn't know if you used %s only.

Hope that clarifies things.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top