django-admin makemessages --no-obsolete doesn't seem to be working
Asked Answered
B

3

6

First of all, I am expecting --no-obsolete would comment out msgid and msgstr if gettext is deleted, right?

How I am testing is:

  1. I wrote gettext("some string here") in view
  2. I ran makemessages command
  3. It wrote a .po file as expected
  4. Then I deleted gettext() line from view and saved file, verified runserver working.
  5. I ran makemessages --no-obsolete and it has not made any changes to .po file.

.po file content extract .

#. Translators: This message is a test of wrap line
#: servers/views.py:31
msgid "Do let me know if it works."
msgstr ""

dev environment

Django = 1.11
OS = Mac/Ubuntu 14.04

settings.py

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

LOCALE = (
      os.path.join(os.path.dirname(__file__), "locale"),
)
Broncobuster answered 17/3, 2018 at 16:37 Comment(5)
Can you please also add your environment setup? What Django version? Which OS are you using?Maculate
@TarunLalwani please see updatesBroncobuster
Can you please also add you settings.py file?Maculate
What specifically from settings file? I haven't changed anything from default settings.Broncobuster
All locale related stuffMaculate
B
3

Now with the help of Julien and Tarun, I found following observations.

python manage.py makemessages -l <locale>

If there is no gettext in the file being processed, the above command won't write/update .po file. That means if the corresponding .po file earlier had entries for msgstr and msgid, then it won't remove those entries unless file being processed had at least one gettext.

Note: Above behavior is irrespective of --no-obsolete

Now to make the --no-obsolete work as expected we need to follow the steps below.

  1. First thing run python manage.py makemessages -l <locale>, this would write .po file with msgid and msgstr.

  2. Now set msgstr and run python manage.py compilemessages -l <locale>. This command writes .mo file in the same directory as .po file.

  3. Now next time when you run makemessages again (without --no-obsolete), .po and .mo files are compared and missing/deleted gettext are commented in .po file.

  4. And when you run makemessages --no-obsolete, commented entries are removed from the .po file.

E.g

if you have 3 gettext entries, and you run makemessages first time, it would write 3 msgid and 3 msgstr in .po file. Now if you remove all gettext entries, .po file won't be updated after you run makemessages again, but if your keep at least 1 gettext entry in same file and run makemessages again, it would delete all msgid and msgstr for deleted gettext entries.

But if you run compilemessages after makemessages, .mo file is created and then for subsequent makemessages commands .po and .mo files are compared and then msgid and msgstr is commented in .po file for deleted gettext entries.

Then finally when you run makemessages with --no-obsolete option the commented messages from .po files are deleted permanently.

Broncobuster answered 20/3, 2018 at 18:52 Comment(0)
C
4

What the --no-obsolete does is to run a command called msgattrib with the --no-obsolete option on the content the po file. A typical case would be you generate your po file with makemessages, you get this:

#: servers/views.py:31
msgid "Do let me know if it works."
msgstr ""

Then you translate:

#: servers/views.py:31
msgid "Do let me know if it works."
msgstr "translation"

Then you remove the gettext entry, it'll still by default keep the translation, but mark it as obsolete.

#: servers/views.py:31
#~msgid "Do let me know if it works."
#~msgstr "translation"

If you set --no-obsolete option, then once your po file is done, it'll run msgattr with no-obsolete option. This will remove lines tagged with #~. See https://linux.die.net/man/1/msgattrib

But, the way makemessages is built, is that this will be called once the po file is written. But if there are no gettext in the files being processed, then it won't write to the po file. It'll just stop before getting to this msgattrib command. The po file you see is the one generated by the previous makemessages command. So the no-obsolete won't do anything.

There's no real solution to this. the no-obsolete option doesn't deal with the cases where you don't have any gettext to process.

Corespondent answered 19/3, 2018 at 21:50 Comment(5)
What do I need to do exactly to get the --no-obsolete effect?Broncobuster
You need to still have a gettext somewherePeremptory
I tried to have another gettext in same file in another view. No effectBroncobuster
@JulienGrégoire, I just test this on my laptop and your observation doesn't seem to be true. When I ran with --no-obsolete the data was actually deleted from the po file. Without --no-obsolete it gets commented like #~ and with --no-obsolete it removes the string from the fileMaculate
@TarunLalwani can you please list down the steps/process?Broncobuster
B
3

Now with the help of Julien and Tarun, I found following observations.

python manage.py makemessages -l <locale>

If there is no gettext in the file being processed, the above command won't write/update .po file. That means if the corresponding .po file earlier had entries for msgstr and msgid, then it won't remove those entries unless file being processed had at least one gettext.

Note: Above behavior is irrespective of --no-obsolete

Now to make the --no-obsolete work as expected we need to follow the steps below.

  1. First thing run python manage.py makemessages -l <locale>, this would write .po file with msgid and msgstr.

  2. Now set msgstr and run python manage.py compilemessages -l <locale>. This command writes .mo file in the same directory as .po file.

  3. Now next time when you run makemessages again (without --no-obsolete), .po and .mo files are compared and missing/deleted gettext are commented in .po file.

  4. And when you run makemessages --no-obsolete, commented entries are removed from the .po file.

E.g

if you have 3 gettext entries, and you run makemessages first time, it would write 3 msgid and 3 msgstr in .po file. Now if you remove all gettext entries, .po file won't be updated after you run makemessages again, but if your keep at least 1 gettext entry in same file and run makemessages again, it would delete all msgid and msgstr for deleted gettext entries.

But if you run compilemessages after makemessages, .mo file is created and then for subsequent makemessages commands .po and .mo files are compared and then msgid and msgstr is commented in .po file for deleted gettext entries.

Then finally when you run makemessages with --no-obsolete option the commented messages from .po files are deleted permanently.

Broncobuster answered 20/3, 2018 at 18:52 Comment(0)
M
1

So I think @JulienGrégoire was right about the fact that if there is no translation processed then the --no-obsolete won't work. There needs to be at least one translation captured for --no-obsolete to work.

But the solution to this quite simple. You can update your settings.py to define LANGUAGES like below

from django.utils.translation import ugettext_lazy as _
LANGUAGES = (
    ('en', _('English')),
    ('fr', _('French')),
)

Now your settings will always generate a translation. So it will make sure that you get --no-obsolete working every time you use it

Maculate answered 20/3, 2018 at 7:1 Comment(7)
Tarun, Can you write the steps, please? Or confirm that, the steps I have mentioned in the question are right.Broncobuster
and Yes, the LANGUAGES is there in my setting. I forgot to add here.Broncobuster
Do you use the _ like I did in the LANGUAGES value?Maculate
yes. I do. but only settings. in views I used gettext onlyBroncobuster
Please run like this python manage.py makemessages --no-obsolete --all and see if it helps. I have tested with both gettext and _ and it works fine for meMaculate
I have tested 1.11 and 2.00 and both work fine with thisMaculate
Let us continue this discussion in chat.Broncobuster

© 2022 - 2024 — McMap. All rights reserved.