# Gettext: FileNotFoundError: \[Errno 2\] No translation file found for domain: 'base'

**URL:** <https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856>\
**Category:** Python Help\
**Created:** [November 8, 2022, 5:02am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856 "2022-11-08T05:02:03Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![vovavili](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vovavili/32/38249_2.png) [@vovavili](https://discuss.python.org/u/vovavili)\
**Post date:** [November 8, 2022, 5:02am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/1 "2022-11-08T05:02:03Z")

</div>

It seems that I am unable to get my GNU gettext utility to work properly, despite closely following both documentation and online resources.

My folder structure is the following:

```auto
/
|- src
| |- __init__.py
| |- main.py
|- locales
     |- ru
          |- LC_MESSAGES
               |- base.mo
               |- base.po

```

the top of my main.py reads like this (Windows machine):

```auto
import argparse
import gettext
from gettext import gettext as _

argparser = argparse.ArgumentParser()
argparser.add_argument("--language", required=False, default="en")
arguments = argparser.parse_args()
gettext.translation(
    "base", localedir=r".\locales", languages=[arguments.language[:2]]
).install()

```

And yet, when I try to run the script in either English or Russian, I still get an error:

```auto
FileNotFoundError: [Errno 2] No translation file found for domain: 'base'

```

What am I doing wrong?

I’ve tried putting `locales` dir inside the `src` folder and dropping the dot prefix (`gettext.translation("base", localedir=r"locales", ...`), but it doesn’t seem to have changed anything.

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [November 8, 2022, 6:50am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/2 "2022-11-08T06:50:17Z")

</div>

> [@vovavili](#):
>
> `from gettext import gettext as _`

When you install isn’t \_ added to builtins still ?

> [@vovavili](#):
>
> `localedir=r".\locales"`

This is relative to where you run the program from.  
Calculate the absolute path the locales.

---

<div class="post-metadata">

**Author:** ![vovavili](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vovavili/32/38249_2.png) [@vovavili](https://discuss.python.org/u/vovavili)\
**Post date:** [November 8, 2022, 7:52am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/4 "2022-11-08T07:52:23Z")

</div>

> [@barry-scott](#):
>
> When you install isn’t \_ added to builtins still ?

It does, but PyCharm doesn’t know that, and I want to avoid annoying faux syntax errors.

> This is relative to where you run the program from.  
> Calculate the absolute path the locales.

Being explicit about my path with `Path( __file__ ).resolve().parents[1] / "locale"` doesn’t seem to have changed anything. Why?:

 ![Untitled](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/7/777509271c65f83027901d2acb0743fad30c6148.png)

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [November 8, 2022, 7:58am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/5 "2022-11-08T07:58:37Z")

</div>

what is the value of languages=? Is it ru?

In my app i do not set languages at all i let it use the default.  
I also add fallback=True.

---

<div class="post-metadata">

**Author:** ![vovavili](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vovavili/32/38249_2.png) [@vovavili](https://discuss.python.org/u/vovavili)\
**Post date:** [November 8, 2022, 8:06am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/6 "2022-11-08T08:06:13Z")

</div>

Yes, the value that gets passed over to `gettext.translation(languages=)` is “ru”:

 ![Untitled](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/a/ae71c6a80dfeb071f2ca2fa06e697678fcc1f46e.png)

---

<div class="post-metadata">

**Author:** ![vovavili](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vovavili/32/38249_2.png) [@vovavili](https://discuss.python.org/u/vovavili)\
**Post date:** [November 8, 2022, 8:14am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/8 "2022-11-08T08:14:03Z")

</div>

Weird - adding `fallback=True` makes the script run, but the translation doesn’t get processed properly at all…:

 ![Untitled](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/5/5e9556fee027a571ef8ddaa890c712a73515a364.png)

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [November 8, 2022, 8:18am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/9 "2022-11-08T08:18:46Z")

</div>

I suggest that you make a simple test app and generate the gettext files.  
Maybe the problem is in your .pot, .po, and .mo files?  
Have one message in en and its ru translation.  
Can you make that work?

Post the script you use the make the gettext files.

---

<div class="post-metadata">

**Author:** ![vovavili](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vovavili/32/38249_2.png) [@vovavili](https://discuss.python.org/u/vovavili)\
**Post date:** [November 8, 2022, 8:35am UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/10 "2022-11-08T08:35:12Z")

</div>

Okay, let’s go step by step.

On my Windows 11, 64 bit, English locale, Python 3.10, PyCharm machine.

Here is a sample script:

```auto
import gettext
from pathlib import Path
from gettext import gettext as _

gettext.translation(
    "translate",
    localedir=Path( __file__ ).resolve() / "locale",
    languages="ru",
    fallback=True,
).install()

print(_("Near the seaside, the oak is green"))

```

The path to the script is:

`C:\Users\vladi\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_38.py`:

 ![Untitled](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/c/cbcb939f25cec392b90e59d8080300b612841745.png)

To create `.pot` file, I run this command in the command line:

`python C:\Users\vladi\AppData\Local\Programs\Python\Python310\Tools\i18n\pygettext.py -d translate C:\Users\vladi\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_38.py`

Then, I open `translate.pot` in Poedit, and make the following configuration:

Source text `Near the seaside, the oak is green` → translation `У лукоморья дуб зелёный`

I save `translate.mo` and `translate.mo` files in the following newly made directory: `C:\Users\vladi\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\locale\ru\LC_MESSAGES`:

 ![Untitled](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/d/d78038df7d29814ef64d0b708d774257509c8eb1.png)

`translate.po` reads as follows:

```auto
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2022-11-08 09:29+0100\n"
"PO-Revision-Date: 2022-11-08 09:31+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 3.2\n"

#: C:\Users\vladi\AppData\Roaming\JetBrains\PyCharmCE2022.2\scratches\scratch_38.py:12
msgid "Near the seaside, the oak is green"
msgstr "У лукоморья дуб зелёный"

```

I run the file, and still, I do not receive the Russian translation:

 ![Untitled](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/e/e6a9297c6382e7300f3784a6308c44b06a6c18a2.png)

What am I doing wrong?

---

<div class="post-metadata">

**Author:** ![aroberge](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/aroberge/32/6200_2.png) [@aroberge](https://discuss.python.org/u/aroberge)\
**Post date:** [November 8, 2022, 12:08pm UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/11 "2022-11-08T12:08:18Z")

</div>

Instead of `languages="ru"`, have you tried `languages=["ru"]`?

Here’s how I do it in one of my programs:

> <https://github.com/friendly-traceback/friendly-traceback/blob/main/friendly_traceback/ft_gettext.py#L36>

Note that I chose to use a different name (something like `base_ru.po`) for each file so that they are easier to identify when using Poedit, but this should be irrelevant.

---

<div class="post-metadata">

**Author:** ![vovavili](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vovavili/32/38249_2.png) [@vovavili](https://discuss.python.org/u/vovavili)\
**Post date:** [November 8, 2022, 12:18pm UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/13 "2022-11-08T12:18:20Z")

</div>

Aha, specifying it in a list AND removing the import seems to have worked, but now PyCharm screams as me. I guess I will have to trick PyCharm into thinking that this is okay:

 ![Untitled](https://us1.discourse-cdn.com/flex002/uploads/python1/original/2X/8/8e2d82caaff47c5f75120f395341d04c30c59fd3.png)

Thank you all. So, the answer is, for any person looking this up into the future:

1. Try specifying the absolute path

2. Do not overwrite the underscore after install

3. Keep in locale in a list.

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [November 8, 2022, 7:45pm UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/14 "2022-11-08T19:45:38Z")

</div>

> [@vovavili](#):
>
> Then, I open `translate.pot` in Poedit, and make the following configuration:

That not the work flow.

1. machine generate .pot
2. machine generate new .po
3. merge .po with your last translations with new .po
4. edit merged .po and update translations as required
5. commit update .po for use in the next interation
6. generate .mo from merged .po

---

<div class="post-metadata">

**Author:** ![barry-scott](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@barry-scott](https://discuss.python.org/u/barry-scott)\
**Post date:** [November 8, 2022, 7:49pm UTC](https://discuss.python.org/t/gettext-filenotfounderror-errno-2-no-translation-file-found-for-domain-base/20856/15 "2022-11-08T19:49:10Z")

</div>

> [@vovavili](#):
>
> Do not overwrite the underscore after install

This is the code I use that sets up the special functions for gettext in my code.  
I do not use the \_ but setup my own setup of builtins:

```python
        locale_path = wb_platform_specific.getLocalePath()
        self.translation = gettext.translation(
                '-'.join( [part.lower() for part in self.app_name_parts] ),
                str(locale_path),
                # language defaults
                fallback=True )

        import builtins
        # T_( 'non plural' )
        builtins. __dict__ ['T_'] = self.translation.gettext
        # S_( 'singular', 'plural', n )
        builtins. __dict__ ['S_'] = self.translation.ngettext
        # U_( 'static string' )
        # define here to keep mypy happy - humm does not work...
        builtins. __dict__ ['U_'] = U_

```

Notice that I get then from the object that gettext.translation() returned to me.
