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 details)

Uploaded Source

Built Distribution

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

Uploaded Python 3

File details

Details for the file sl10n-0.3.0.0.tar.gz.

File metadata

  • Download URL: sl10n-0.3.0.0.tar.gz
  • Upload date:
  • Size: 14.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.18

File hashes

Hashes for sl10n-0.3.0.0.tar.gz
Algorithm Hash digest
SHA256 95e6ebcbf5c3e2c9990c610f3da30eb0ba80b1b977fca8516a30491b46081908
MD5 056c55ecc01b31f885754d5437b34867
BLAKE2b-256 fad2f6181bf7f30bb53565bd5cd2f70adfad8d217c7fda8e204ddabdaaaebf33

See more details on using hashes here.

File details

Details for the file sl10n-0.3.0.0-py3-none-any.whl.

File metadata

  • Download URL: sl10n-0.3.0.0-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.18

File hashes

Hashes for sl10n-0.3.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2446a129641cecf46466d92b78e14a0362ba1056b00692070a9adc77516b024b
MD5 8b60a67ec4d8d1a36dd98ae54d1fe782
BLAKE2b-256 e2fdc2c04af56f1e7c29e5db2004644a0ccdb07e4c7ca62b09deb7d5dc6df0b9

See more details on using hashes here.

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