Page MenuHome

I18n: fixes to add-on message extraction
ClosedPublic

Authored by Damien Picard (pioverfour) on Jul 16 2022, 11:20 PM.

Details

Summary

While trying to extract add-on message for translations, I ran into a few issues.

  • In multi-file modules, the script would crash because it tried to write to the dir instead of a translations.py file;
  • the add-on message extraction works by enabling the add-on, getting all messages; disabling the add-on, getting all messages; then comparing the two message sets. But often a bug happens where a class gets a description from somewhere else in memory. I couldn’t debug that, so a workaround is to check that the message isn’t a corrupted one before removing it;
  • printf() doesn't exist in Python and would crash the script;
  • self.src[self.settings.PARSER_PY_ID] can be replaced by self.py_file in class I18n, since a property exists to do that;
  • at one point a generator was printed instead of its values, so let's unpack the generator to get the values. Maybe the print could be deleted entirely;
  • use SPDX license identifier instead of GPL license block, to be more in line with other scripts from the codebase.

@Bastien Montagne (mont29) If that’s too much I can separate this into several diffs.

Diff Detail

Repository
rB Blender

Event Timeline

Damien Picard (pioverfour) requested review of this revision.Jul 16 2022, 11:20 PM
Damien Picard (pioverfour) created this revision.
Bastien Montagne (mont29) requested changes to this revision.Jul 18 2022, 2:38 PM

Generally looks fine, don't mind having all those changes in a single commit since most of them are more cleanup/obvious fixes than actual behavior changes... Amount of changes remain very reasonable, and they are properly listed in the commit message, so all good.

release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
967–970

This is likely due to add-ons not properly un-registering their data... Could be specified in the comment maybe?

release/scripts/modules/bl_i18n_utils/utils.py
1243

I don't think this is the proper fix... more something like:

if os.path.isdir(path):
    return os.path.join(path, "translations.py")
return os.path.join(os.path.dirname(path), "translations.py")

?

This revision now requires changes to proceed.Jul 18 2022, 2:38 PM
release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
967–970

Honestly it’s like dark magic to me! Here is an example of errors I printed when trying to export messages for AnimAll:

Key not found in msgs: (' matching of objects', 'tion to get the best possible match between source and destination meshes.\nWarning: Results will never be as good as manual matching of objects')
Key not found in msgs: ('*', 'best possible match between source and destination meshes.\nWarning: Results will never be as good as manual matching of objects')

These are both parts of bpy.types.OBJECT_OT_data_transfer.use_auto_transform, so completely unrelated to AnimAll. It seems really fishy that parts of the message wound up in both the context and the message, right?

I tried to follow the logic to understand how RNA is walked and all that but it’s too much for me just yet!

So it could well be an unregister error, but it’s not clear enough to me, and I wouldn’t know how to formulate the message…

release/scripts/modules/bl_i18n_utils/utils.py
1243

Ah, maybe I’m mistaken, but this always creates a translations.py, even for single-file scripts. I thought the intention was to create it only if the module is a directory, otherwise just put the translations at the end of the script.

If that is the case, I think this is better? Let me know.

@staticmethod
def _dst(self, path, uid, kind):
    if isinstance(path, str):
        if kind == 'PO':
            if uid == self.settings.PARSER_TEMPLATE_ID:
                if not path.endswith(".pot"):
                    return os.path.join(os.path.dirname(path), "blender.pot")
            if not path.endswith(".po"):
                return os.path.join(os.path.dirname(path), uid + ".po")
        elif kind == 'PY':
            if os.path.isdir(path):
                return os.path.join(path, "translations.py")
    return path
release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
967–970

OK... Can't spot anything wrong on first sight in animall code, so will wait for this pathc to be committed and will try to investigate further.

BTW, a bit unrelated, but unregistration of translations in that add-on should rather happen at the start of the unregister function. By principle, it's better to always unregister exactly in the inverse order of registration.

release/scripts/modules/bl_i18n_utils/utils.py
1243

That piece of code I proposed would be under the if not path.endswith(".py"): condition, so single py files would still be handled as expected.

it just makes it safe(r) in case we ever get a non-py file, non directory path, for whatever reason.

release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
967–970

Note that the issue does not happen every single time, but AnimAll is not the only add-on affected, I’ve tried several and they were all—with different messages, though.

Thanks for the unregister tip, I’ll fix it!

release/scripts/modules/bl_i18n_utils/utils.py
1243

Oh, right 🤦

Proper fix for files not ending in .py

This revision is now accepted and ready to land.Jul 20 2022, 11:04 AM