-
-
Notifications
You must be signed in to change notification settings - Fork 36
Description
polib 1.2.0 on Python 3.7 installed via pip.
It either generates the error TypeError: list indices must be integers or slices, not str on POFile.save or results in a corrupt po file (as per msgcat or poedit).
Expectations (in order of decreasing importance):
- An empty msgstr_plural should result in a valid, empty entry in the po file.
- This is how it works with most (all other?) fields of POEntry.
- A field of type list[str] should be initialisable in all common ways, not arbitrarily reject some of them.
- Errors for invalid input should be generated on input, not at an arbitrary later point in time.
- It is probably necessary to create a type for msgstr_plural, which would be able to enforce or at least assert correct input format.
- Alternatively, a docstring could have helped.
Steps to reproduce:
- get a po file with at least one translated, non-obsolete plural entry (for the next stepts assumed to be 'en.po' in the script folder)
- for the successful result ensure the plural has exactly two entries
- run the MVE script given below
- you will have created a valid, new po file 'pt_BR.po' containing all entries from 'en.po' with empty translation
- replace the marked code block with one of the variants given below
- if you picked a crashing variant,
new_file.savewill throw 'TypeError: list indices must be integers or slices, not str' - if you picked a corrupting variant, opening 'pt_BR.po' with will result in an error
- with
msgcat pt_BR.po -o copy.po:syntax error(on each empty msgstr placed instead of a msgstr_plural) - with poedit:
- with
- if you picked a crashing variant,
Thu 01 Aug 2024 15:20:14 CEST: Broken catalogue file: singular form msgstr used together with msgid_plural
Thu 01 Aug 2024 15:20:14 CEST: Couldn’t load file /home/beyer/projects/internationalisation/Internationalization/Internationalization/pt_BR.po, it is probably corrupted.
The MVE script with workaround:
from polib import POFile, pofile
english = pofile('en.po')
new_file = POFile() # Usually we'd set more metadata, but for the MVP these are the necessary fields... - I had to find out the hard way.
for entry in english:
if entry.obsolete:
continue
if entry.msgstr:
entry.msgstr = ''
if entry.msgstr_plural:
# Replace this block with the variants below. ... While I am glad I have found a workaround, that *this* is it, I find particularly vexxing.
entry.msgstr_plural[0] = ''
entry.msgstr_plural[1] = ''
new_file.append(entry)
new_file.save('pt_BR.po')Crashing variants:
entry.msgstr_plural = ['']
entry.msgstr_plural = list('' for plural in entry.msgid_plural)
entry.msgstr_plural = list()
entry.msgstr_plural.append('')Corrupting variants:
entry.msgstr_plural = [] - emits msgstr = "" which is forbidden for entries with msgid_plural
FWIW:
Valid output would always be (regardless of Plural-Forms entry): msgstr[0] '', so it might be sensible to rework POEntry and only use a list[str], not the separate POEntry.msgstr: str. Then on POFile.save decide via presence of msgid_plural whether to write out msgstr or msgstr[i].