cosmo-intl 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.9", "3.11", "3.13"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ # PyICU is a C extension; it needs the system ICU headers + a compiler.
19
+ - name: Install ICU
20
+ run: sudo apt-get update && sudo apt-get install -y libicu-dev pkg-config
21
+
22
+ - uses: astral-sh/setup-uv@v5
23
+ with:
24
+ enable-cache: true
25
+
26
+ - name: Run tests
27
+ run: uv run --extra test --python ${{ matrix.python-version }} pytest -q
@@ -0,0 +1,6 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.egg-info/
4
+ .pytest_cache/
5
+ build/
6
+ dist/
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: cosmo-intl
3
+ Version: 0.1.0
4
+ Summary: Ergonomic internationalization (i18n) and localization (l10n) for Python — format numbers, currency, dates, times, units, lists and ICU plurals for any locale, powered by ICU and Unicode CLDR via PyICU. No bundled locale data.
5
+ Project-URL: Homepage, https://github.com/cosmo-intl/cosmo-python
6
+ Project-URL: Repository, https://github.com/cosmo-intl/cosmo-python
7
+ Project-URL: PHP port, https://github.com/cosmo-intl/cosmo-php
8
+ Author-email: Miloun <cosmo-python@miloun.com>
9
+ License: MIT
10
+ Keywords: cldr,currency,date,datetime,i18n,icu,internationalisation,internationalization,intl,l10n,locale,localisation,localization,money,pluralization,pyicu,timezone,translation,unicode
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Topic :: Software Development :: Internationalization
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Topic :: Software Development :: Localization
19
+ Requires-Python: >=3.9
20
+ Requires-Dist: pyicu>=2.10
21
+ Provides-Extra: test
22
+ Requires-Dist: pytest>=7; extra == 'test'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # Cosmo
26
+
27
+ Ergonomic application localisation for Python, powered by [ICU](https://icu.unicode.org/).
28
+
29
+ Cosmo is a thin, ergonomic layer over **ICU**, reached through
30
+ [PyICU](https://gitlab.pyicu.org/main/pyicu). Give it a locale (and optionally a
31
+ time zone) and it formats numbers, money, dates, units, lists and messages exactly
32
+ the way your users expect. There is **no bundled locale data** — every result comes
33
+ straight from ICU and [CLDR](https://cldr.unicode.org/), covering all languages,
34
+ scripts, calendars and time zones.
35
+
36
+ Cosmo is implemented consistently across four languages — the same concepts, method
37
+ names and behaviour, each built directly on its platform's ICU:
38
+ [JavaScript](https://github.com/cosmo-intl/cosmo-js) ([docs](https://cosmo.miloun.com/?lang=js)) ·
39
+ **Python** ·
40
+ [Java](https://github.com/cosmo-intl/cosmo-java) ([docs](https://cosmo.miloun.com/?lang=java)) ·
41
+ [PHP](https://github.com/salarmehr/cosmopolitan) ([docs](https://cosmo.miloun.com/?lang=php)).
42
+
43
+ 📖 **Full documentation, API reference and live playground:** https://cosmo.miloun.com/?lang=python
44
+
45
+ ## Requirements
46
+
47
+ - Python 3.9+
48
+ - System ICU development libraries for PyICU (e.g. `libicu-dev` + `pkg-config`)
49
+
50
+ ## Install
51
+
52
+ ```bash
53
+ pip install cosmo-intl # pulls in PyICU; the import package is `cosmo`
54
+ ```
55
+
56
+ ## Quick start
57
+
58
+ ```python
59
+ from cosmo import Cosmo
60
+
61
+ Cosmo("es_ES").money(11000.4, "EUR") # "11.000,40 €"
62
+ Cosmo("en").percentage(0.2) # "20%"
63
+ Cosmo("en_AU").money(1234.5) # "$1,234.50" (currency inferred)
64
+ Cosmo("en").spellout(42) # "forty-two"
65
+ Cosmo("fa").language("en") # "انگلیسی"
66
+ ```
67
+
68
+ All methods are `snake_case`. Underscore locales (`en_AU`) and [BCP-47](https://www.rfc-editor.org/info/bcp47)
69
+ [Unicode extensions](https://unicode.org/reports/tr35/#u_Extension)
70
+ (`fa-IR-u-nu-latn-ca-buddhist`) are both accepted.
71
+
72
+ ## What you get
73
+
74
+ - **Locale display names** — languages, regions, scripts, calendars and currencies, plus emoji flags and writing direction.
75
+ - **Numbers & money** — decimals, percentages, currencies (inferred from the region), units, compact notation, scientific, ranges, plus spelled-out and ordinal text.
76
+ - **Dates & times** — locale formats in any calendar (Gregorian, Persian, Buddhist…), custom ICU patterns, durations, date ranges, and relative times.
77
+ - **Text** — locale-aware sort and search, word/sentence/grapheme segmentation, case mapping and quotation marks.
78
+ - **Messages** — [ICU MessageFormat](https://unicode-org.github.io/icu/userguide/format_parse/messages/) (`plural`, `selectordinal`, `select`).
79
+ - **Parsing & transforms** — the inverse formatters for numbers, money and dates, transliteration, UTS #39 spoof checks, locale negotiation and contact-list index buckets.
80
+ - **Raw ICU access** — resource-bundle lookups for data the high-level methods don't cover.
81
+
82
+ See the [full API reference](https://cosmo.miloun.com/api-reference/?lang=python) for every method,
83
+ the [platform notes](https://cosmo.miloun.com/platform-notes/) for PyICU's binding
84
+ limits, and [resources](https://cosmo.miloun.com/resources/) for ICU/CLDR references.
85
+
86
+ ## Development
87
+
88
+ The dev environment is managed with [uv](https://docs.astral.sh/uv/), which
89
+ provisions a matching Python automatically. You still need the system ICU
90
+ libraries (e.g. `libicu-dev` + `pkg-config`) for PyICU to build and link.
91
+
92
+ ```bash
93
+ uv run --extra test pytest # run the test suite
94
+ uv build # build the wheel + sdist into dist/
95
+ ```
96
+
97
+ `uv.lock` pins the dev/test toolchain for reproducible local runs and CI. It does
98
+ **not** affect anyone who `pip install cosmo-intl` — they resolve from the
99
+ dependency ranges in `pyproject.toml`.
100
+
101
+ ## Errors
102
+
103
+ Recoverable problems raise `CosmoError`, with `InvalidArgumentError` and
104
+ `UnsupportedError` subclasses — an invalid currency in strict mode, an unsupported
105
+ unit, an unknown symbol name, an unformattable date, and the like.
106
+
107
+ ## License
108
+
109
+ MIT © Aiden Adrian
@@ -0,0 +1,85 @@
1
+ # Cosmo
2
+
3
+ Ergonomic application localisation for Python, powered by [ICU](https://icu.unicode.org/).
4
+
5
+ Cosmo is a thin, ergonomic layer over **ICU**, reached through
6
+ [PyICU](https://gitlab.pyicu.org/main/pyicu). Give it a locale (and optionally a
7
+ time zone) and it formats numbers, money, dates, units, lists and messages exactly
8
+ the way your users expect. There is **no bundled locale data** — every result comes
9
+ straight from ICU and [CLDR](https://cldr.unicode.org/), covering all languages,
10
+ scripts, calendars and time zones.
11
+
12
+ Cosmo is implemented consistently across four languages — the same concepts, method
13
+ names and behaviour, each built directly on its platform's ICU:
14
+ [JavaScript](https://github.com/cosmo-intl/cosmo-js) ([docs](https://cosmo.miloun.com/?lang=js)) ·
15
+ **Python** ·
16
+ [Java](https://github.com/cosmo-intl/cosmo-java) ([docs](https://cosmo.miloun.com/?lang=java)) ·
17
+ [PHP](https://github.com/salarmehr/cosmopolitan) ([docs](https://cosmo.miloun.com/?lang=php)).
18
+
19
+ 📖 **Full documentation, API reference and live playground:** https://cosmo.miloun.com/?lang=python
20
+
21
+ ## Requirements
22
+
23
+ - Python 3.9+
24
+ - System ICU development libraries for PyICU (e.g. `libicu-dev` + `pkg-config`)
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install cosmo-intl # pulls in PyICU; the import package is `cosmo`
30
+ ```
31
+
32
+ ## Quick start
33
+
34
+ ```python
35
+ from cosmo import Cosmo
36
+
37
+ Cosmo("es_ES").money(11000.4, "EUR") # "11.000,40 €"
38
+ Cosmo("en").percentage(0.2) # "20%"
39
+ Cosmo("en_AU").money(1234.5) # "$1,234.50" (currency inferred)
40
+ Cosmo("en").spellout(42) # "forty-two"
41
+ Cosmo("fa").language("en") # "انگلیسی"
42
+ ```
43
+
44
+ All methods are `snake_case`. Underscore locales (`en_AU`) and [BCP-47](https://www.rfc-editor.org/info/bcp47)
45
+ [Unicode extensions](https://unicode.org/reports/tr35/#u_Extension)
46
+ (`fa-IR-u-nu-latn-ca-buddhist`) are both accepted.
47
+
48
+ ## What you get
49
+
50
+ - **Locale display names** — languages, regions, scripts, calendars and currencies, plus emoji flags and writing direction.
51
+ - **Numbers & money** — decimals, percentages, currencies (inferred from the region), units, compact notation, scientific, ranges, plus spelled-out and ordinal text.
52
+ - **Dates & times** — locale formats in any calendar (Gregorian, Persian, Buddhist…), custom ICU patterns, durations, date ranges, and relative times.
53
+ - **Text** — locale-aware sort and search, word/sentence/grapheme segmentation, case mapping and quotation marks.
54
+ - **Messages** — [ICU MessageFormat](https://unicode-org.github.io/icu/userguide/format_parse/messages/) (`plural`, `selectordinal`, `select`).
55
+ - **Parsing & transforms** — the inverse formatters for numbers, money and dates, transliteration, UTS #39 spoof checks, locale negotiation and contact-list index buckets.
56
+ - **Raw ICU access** — resource-bundle lookups for data the high-level methods don't cover.
57
+
58
+ See the [full API reference](https://cosmo.miloun.com/api-reference/?lang=python) for every method,
59
+ the [platform notes](https://cosmo.miloun.com/platform-notes/) for PyICU's binding
60
+ limits, and [resources](https://cosmo.miloun.com/resources/) for ICU/CLDR references.
61
+
62
+ ## Development
63
+
64
+ The dev environment is managed with [uv](https://docs.astral.sh/uv/), which
65
+ provisions a matching Python automatically. You still need the system ICU
66
+ libraries (e.g. `libicu-dev` + `pkg-config`) for PyICU to build and link.
67
+
68
+ ```bash
69
+ uv run --extra test pytest # run the test suite
70
+ uv build # build the wheel + sdist into dist/
71
+ ```
72
+
73
+ `uv.lock` pins the dev/test toolchain for reproducible local runs and CI. It does
74
+ **not** affect anyone who `pip install cosmo-intl` — they resolve from the
75
+ dependency ranges in `pyproject.toml`.
76
+
77
+ ## Errors
78
+
79
+ Recoverable problems raise `CosmoError`, with `InvalidArgumentError` and
80
+ `UnsupportedError` subclasses — an invalid currency in strict mode, an unsupported
81
+ unit, an unknown symbol name, an unformattable date, and the like.
82
+
83
+ ## License
84
+
85
+ MIT © Aiden Adrian
@@ -0,0 +1,28 @@
1
+ """Runnable tour of cosmo. `python example.py`"""
2
+
3
+ import datetime
4
+
5
+ from cosmo import Cosmo
6
+
7
+ when = datetime.datetime(2020, 2, 2, 9, 30, tzinfo=datetime.timezone.utc)
8
+
9
+ for tag in ("en_AU", "fa_IR", "de_DE"):
10
+ c = Cosmo(tag, {"timeZone": "UTC"})
11
+ print(f"\n=== {tag} ===")
12
+ print("language(en): ", c.language("en"))
13
+ print("country/flag: ", c.country(), c.flag())
14
+ print("number: ", c.number(1234567.89))
15
+ print("money: ", c.money(1234.5))
16
+ print("percentage: ", c.percentage(0.1234))
17
+ print("compact: ", c.compact(1_200_000, "long"))
18
+ print("spellout/ord: ", c.spellout(42), "/", c.ordinal(21))
19
+ print("moment: ", c.moment(when, "full", "short"))
20
+ print("month[0]: ", c.month_names()[0])
21
+ print("relative: ", c.relative_duration(-3, "day"))
22
+ print("join: ", c.join(["apples", "pears", "figs"]))
23
+ print("quote: ", c.quote("hi"))
24
+ print("plural(2): ", c.plural_category(2))
25
+ print(
26
+ "message: ",
27
+ c.message("{0, plural, one {# file} other {# files}}", [3]),
28
+ )
@@ -0,0 +1,60 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ # PyPI distribution name; the bare `cosmo` is taken on PyPI, so we publish as
7
+ # `cosmo-intl` (matches the GitHub org) while the import package stays `cosmo`.
8
+ name = "cosmo-intl"
9
+ version = "0.1.0"
10
+ description = "Ergonomic internationalization (i18n) and localization (l10n) for Python — format numbers, currency, dates, times, units, lists and ICU plurals for any locale, powered by ICU and Unicode CLDR via PyICU. No bundled locale data."
11
+ readme = "README.md"
12
+ requires-python = ">=3.9"
13
+ license = { text = "MIT" }
14
+ authors = [{ name = "Miloun", email = "cosmo-python@miloun.com" }]
15
+ keywords = [
16
+ "i18n",
17
+ "l10n",
18
+ "internationalization",
19
+ "internationalisation",
20
+ "localization",
21
+ "localisation",
22
+ "intl",
23
+ "icu",
24
+ "cldr",
25
+ "unicode",
26
+ "locale",
27
+ "translation",
28
+ "currency",
29
+ "money",
30
+ "date",
31
+ "datetime",
32
+ "timezone",
33
+ "pluralization",
34
+ "pyicu",
35
+ ]
36
+ classifiers = [
37
+ "Programming Language :: Python :: 3",
38
+ "Programming Language :: Python :: 3 :: Only",
39
+ "Topic :: Software Development :: Localization",
40
+ "Topic :: Software Development :: Internationalization",
41
+ "Topic :: Software Development :: Libraries :: Python Modules",
42
+ "Intended Audience :: Developers",
43
+ "License :: OSI Approved :: MIT License",
44
+ "Operating System :: OS Independent",
45
+ ]
46
+ dependencies = ["PyICU>=2.10"]
47
+
48
+ [project.optional-dependencies]
49
+ test = ["pytest>=7"]
50
+
51
+ [project.urls]
52
+ Homepage = "https://github.com/cosmo-intl/cosmo-python"
53
+ Repository = "https://github.com/cosmo-intl/cosmo-python"
54
+ "PHP port" = "https://github.com/cosmo-intl/cosmo-php"
55
+
56
+ [tool.hatch.build.targets.wheel]
57
+ packages = ["src/cosmo"]
58
+
59
+ [tool.pytest.ini_options]
60
+ testpaths = ["tests"]
@@ -0,0 +1,15 @@
1
+ """Cosmo — application localisation for Python, backed entirely by ICU."""
2
+
3
+ from .bundle import Bundle
4
+ from .cosmo import Cosmo, Moment
5
+ from .errors import CosmoError, InvalidArgumentError, UnsupportedError
6
+
7
+ __all__ = [
8
+ "Cosmo",
9
+ "Bundle",
10
+ "CosmoError",
11
+ "InvalidArgumentError",
12
+ "UnsupportedError",
13
+ "Moment",
14
+ ]
15
+ __version__ = "0.1.0"
@@ -0,0 +1,18 @@
1
+ """Names of the ICU resource bundles reachable through :meth:`Cosmo.get`.
2
+
3
+ These mirror the constants in the PHP port's ``Bundle`` class. They are the
4
+ package identifiers PyICU's :class:`icu.ResourceBundle` understands.
5
+ """
6
+
7
+
8
+ class Bundle:
9
+ """ICU resource-bundle package names."""
10
+
11
+ #: Break-iterator rule source data.
12
+ BRKITR = "ICUDATA-brkitr"
13
+ #: Currency symbols and display names.
14
+ CURRENCY = "ICUDATA-curr"
15
+ #: The per-locale bundle (delimiters, layout, …).
16
+ LOCALE = "ICUDATA"
17
+ #: Language / script / calendar display names.
18
+ LANGUAGE = "ICUDATA-lang"