Skip to content

msgstr_plural cannot be emptied (in normal ways) #153

@Zsar

Description

@Zsar

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.save will 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:
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].

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions