Skip to main content

Static localization system that reduces the headache of working with localization

Project description

sl10n

PyPI release Python supported versions License
Tests Documentation status

sl10n is a library that takes a unique approach to dealing with localization by using statically typed translation keys.

Features

  • Type-safe: we use statically typed translation keys, so you don't have to worry about making a typo or using a wrong key.
  • Explicit: you get the exact result that you expect.
  • Versatile: you can use it in any project.
  • Self-sufficient, no other tools required.
  • Written purely on Python.
  • Easy to use.
  • Small.

Why?

Imagine you have a lang folder containing all our translation files and a parser that reads these files and stores them in a mapping.

{
    "my_key_1": "My text",
    "my_key_2": "Wrong text"
}
import parser  # your handwritten parser

locales = parser.parse('/lang')
locale = locales.get('en')

print(locale.get('my_key_1'))  # My text

You may probably think "Sounds pretty simple" and you'd be right. This approach is pretty common (e.g., Minecraft mods use it).

But it's really error-prone. You can easily make a typo or refer to a different key with similar name.

print(locale.get('my_key_I'))  # my_key_I
print(locale.get('my_key_2'))  # Wrong text

This becomes a real trouble once you change the schema of your translation files and even IDEs won't help you.

So?

sl10n fixes this by introducing locale containers.

In short, a locale container is a spec of your translation files that contains all possible keys. At parsing, all your localization gets collected into locale containers, so you can access them freely.

sl10n defines a base class for your locale container (SLocale) and a parsing system (SL10n).

from sl10n import SL10n, SLocale


class MyLocale(SLocale):  # your locale container, it MUST inherit from SLocale
    my_key_1: str
    my_key_2: str


l10n = SL10n(MyLocale, 'lang')  # creating a reference for system

l10n.init()  # execute parser

The key difference is that now you can access your translated strings as class attributes.

locale: MyLocale = l10n.locale('en')  # returns default one if this language wasn't found

print(locale.my_key_1)  # My text

That way, your IDE can suggest what keys you can use and also tell you if you made a typo.

print(locale.my_key_I)  # Unresolved attribute reference 'my_key_I for class 'MyLocale' 

You can still access your locale container dynamically if you want (e.g. when the key is known only at runtime).

key = f()  # returned 'my_key_1'

print(locale.get(key))  # My text

Other features?

  • If your translation files don't follow the spec - SL10n will notify you and also try to fix it:

    • add all undefined keys
    • move all unexpected keys to the bottom of the file
  • You can also create new translation files:

    from sl10n import SL10n, SLocale
    
    
    class MyLocale(SLocale):
        my_key_1: str
        my_key_2: str
    
    
    l10n = SL10n(MyLocale, 'lang')
    
    l10n.create_lang_file('de')  # copy the contents of default language file ('en') to a new file
    
  • Define what filenames should be ignored:

    l10n = SL10n(MyLocale, 'lang', ignore_filenames=['config', 'tags'])
    
  • Make a custom parsing implementation:

    from sl10n import SL10n
    from sl10n.pimpl import ParsingImpl
    import yaml
    
    
    class YAMLImpl(ParsingImpl):
        file_ext = 'yml'
    
        def __init__(self, module=yaml, *args, **kwargs):
            self.module = module
            self.args = args
            self.kwargs = kwargs
    
        def load(self, file):
            return self.module.load(file, self.loader)  # yaml.load and yaml.dump are not safe
    
        def dump(self, data, file):
            self.module.dump(data, file, self.dumper, *self.args, **self.kwargs)
    
    ...
    
    l10n = SL10n(MyLocale, 'lang', parsing_impl=YAMLImpl())
    
  • Apply some modifiers to your file (todo: make a docs explaining modifiers):

    {
        "my_key_1": "My text",
        "my_key_2": "Wrong text",
        "$redump": true  // redumps the file anyway
    }
    
    {
        "my_key_1": "My text",
        "my_key_2": "<not finished>",
        "$exclude": true  // excludes the file from parsing
    }
    

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sl10n-0.3.0.0.tar.gz (14.6 kB view hashes)

Uploaded Source

Built Distribution

sl10n-0.3.0.0-py3-none-any.whl (13.5 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page