worldref 1.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.
- worldref-1.1.0/LICENSE +38 -0
- worldref-1.1.0/PKG-INFO +46 -0
- worldref-1.1.0/README.md +23 -0
- worldref-1.1.0/pyproject.toml +35 -0
- worldref-1.1.0/setup.cfg +4 -0
- worldref-1.1.0/tests/test_worldref.py +84 -0
- worldref-1.1.0/worldref/__init__.py +15 -0
- worldref-1.1.0/worldref/data/subdivisions.json +5014 -0
- worldref-1.1.0/worldref/data/worldref.json +244 -0
- worldref-1.1.0/worldref/data.py +43 -0
- worldref-1.1.0/worldref/helpers.py +175 -0
- worldref-1.1.0/worldref/models.py +198 -0
- worldref-1.1.0/worldref/py.typed +0 -0
- worldref-1.1.0/worldref/text.py +22 -0
- worldref-1.1.0/worldref.egg-info/PKG-INFO +46 -0
- worldref-1.1.0/worldref.egg-info/SOURCES.txt +16 -0
- worldref-1.1.0/worldref.egg-info/dependency_links.txt +1 -0
- worldref-1.1.0/worldref.egg-info/top_level.txt +1 -0
worldref-1.1.0/LICENSE
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 arj-89 and worldref contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
|
9
|
+
following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
12
|
+
portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
|
15
|
+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
|
16
|
+
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
18
|
+
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
The code in this repository is MIT licensed (above). The data in data/ is derived from third-party
|
|
23
|
+
sources under their own licences; full texts are in LICENSES/:
|
|
24
|
+
|
|
25
|
+
- Unicode CLDR (names, currencies, languages, locale data, subdivisions): Unicode-3.0.
|
|
26
|
+
Copyright (c) 1991-2026 Unicode, Inc.
|
|
27
|
+
- Google libphonenumber metadata (phone rules) and Google address metadata (address formats):
|
|
28
|
+
Apache-2.0. Copyright (C) 2009 The Libphonenumber Authors; Copyright (C) Google Inc.
|
|
29
|
+
These files were modified: reduced to the fields worldref publishes and reshaped to its format.
|
|
30
|
+
- World Bank World Development Indicators (population, area): CC-BY-4.0. Source: The World Bank.
|
|
31
|
+
- Wikidata (capitals, coordinates, aliases, plugs, voltage, sports codes, nationality forms): CC0-1.0.
|
|
32
|
+
- CIA World Factbook (English nationality, official names): public domain.
|
|
33
|
+
- IANA Time Zone Database and root zone list: public domain.
|
|
34
|
+
- flag-icons (SVG flags): MIT, Copyright (c) 2013 Panayiotis Lipiridis.
|
|
35
|
+
- Website map (upstream/snapshot/world-map.json): Natural Earth, public domain.
|
|
36
|
+
- Website fonts in site/assets/fonts (IBM Plex Sans Arabic, Noto Kufi Arabic, JetBrains Mono): OFL-1.1.
|
|
37
|
+
|
|
38
|
+
Per-column sources, versions and every editorial decision are listed in data/sources.json.
|
worldref-1.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: worldref
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Every country in Arabic, English, or both: names, nationalities, dial codes, phone validation, currencies, subdivisions.
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://arj-89.github.io/worldref
|
|
7
|
+
Project-URL: Source, https://github.com/arj-89/worldref
|
|
8
|
+
Project-URL: Issues, https://github.com/arj-89/worldref/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/arj-89/worldref/blob/main/CHANGELOG.md
|
|
10
|
+
Keywords: countries,arabic,bilingual,nationality,phone-number,dial-codes,iso-3166,i18n,dataset
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Natural Language :: Arabic
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Software Development :: Internationalization
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
|
|
24
|
+
# worldref (Python)
|
|
25
|
+
|
|
26
|
+
242 countries and territories in Arabic and English: names, aliases, phone plans, currencies, geo, locale, subdivisions, plus search, sorting and phone parsing. Standard library only, Python 3.9 or newer.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
pip install "git+https://github.com/arj-89/worldref@v1.1.0#subdirectory=python"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from worldref import countries, by_iso2, search, sort_countries, parse_phone, subdivisions
|
|
38
|
+
|
|
39
|
+
sa = by_iso2("sa")
|
|
40
|
+
print(sa.name_ar, sa.name_en, sa.flag) # السعودية Saudi Arabia 🇸🇦
|
|
41
|
+
print([c.iso2 for c in search(countries(), "سعودية", "ar")][:3])
|
|
42
|
+
print([c.name_en for c in sort_countries(countries(), "en", first="SA")][:3])
|
|
43
|
+
p = parse_phone("0501234567", sa, countries())
|
|
44
|
+
print(p.e164, p.valid, p.mobile) # +966501234567 True True
|
|
45
|
+
print(len(subdivisions("SA")))
|
|
46
|
+
```
|
worldref-1.1.0/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# worldref (Python)
|
|
2
|
+
|
|
3
|
+
242 countries and territories in Arabic and English: names, aliases, phone plans, currencies, geo, locale, subdivisions, plus search, sorting and phone parsing. Standard library only, Python 3.9 or newer.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pip install "git+https://github.com/arj-89/worldref@v1.1.0#subdirectory=python"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from worldref import countries, by_iso2, search, sort_countries, parse_phone, subdivisions
|
|
15
|
+
|
|
16
|
+
sa = by_iso2("sa")
|
|
17
|
+
print(sa.name_ar, sa.name_en, sa.flag) # السعودية Saudi Arabia 🇸🇦
|
|
18
|
+
print([c.iso2 for c in search(countries(), "سعودية", "ar")][:3])
|
|
19
|
+
print([c.name_en for c in sort_countries(countries(), "en", first="SA")][:3])
|
|
20
|
+
p = parse_phone("0501234567", sa, countries())
|
|
21
|
+
print(p.e164, p.valid, p.mobile) # +966501234567 True True
|
|
22
|
+
print(len(subdivisions("SA")))
|
|
23
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "worldref"
|
|
7
|
+
version = "1.1.0"
|
|
8
|
+
description = "Every country in Arabic, English, or both: names, nationalities, dial codes, phone validation, currencies, subdivisions."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
dependencies = []
|
|
13
|
+
keywords = ["countries", "arabic", "bilingual", "nationality", "phone-number", "dial-codes", "iso-3166", "i18n", "dataset"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 5 - Production/Stable",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Natural Language :: Arabic",
|
|
19
|
+
"Natural Language :: English",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Topic :: Software Development :: Internationalization",
|
|
22
|
+
"Typing :: Typed",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Homepage = "https://arj-89.github.io/worldref"
|
|
27
|
+
Source = "https://github.com/arj-89/worldref"
|
|
28
|
+
Issues = "https://github.com/arj-89/worldref/issues"
|
|
29
|
+
Changelog = "https://github.com/arj-89/worldref/blob/main/CHANGELOG.md"
|
|
30
|
+
|
|
31
|
+
[tool.setuptools]
|
|
32
|
+
packages = ["worldref"]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.package-data]
|
|
35
|
+
worldref = ["py.typed", "data/*.json"]
|
worldref-1.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import unittest
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import worldref
|
|
6
|
+
from worldref import (
|
|
7
|
+
by_iso2, countries, normalize, parse_phone, search, sort_countries, subdivisions, western_digits,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
V = json.loads((Path(__file__).resolve().parent / ".." / ".." / "tests" / "vectors.json").read_text(encoding="utf-8"))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Vectors(unittest.TestCase):
|
|
14
|
+
def test_western_digits(self) -> None:
|
|
15
|
+
for i, o in V["westernDigits"]:
|
|
16
|
+
self.assertEqual(western_digits(i), o, i)
|
|
17
|
+
|
|
18
|
+
def test_normalize(self) -> None:
|
|
19
|
+
for i, o in V["normalize"]:
|
|
20
|
+
self.assertEqual(normalize(i), o, i)
|
|
21
|
+
|
|
22
|
+
def test_search(self) -> None:
|
|
23
|
+
for c in V["search"]:
|
|
24
|
+
hits = search(countries(), c["query"], c["lang"])
|
|
25
|
+
if "count" in c:
|
|
26
|
+
self.assertEqual(len(hits), c["count"], c["query"])
|
|
27
|
+
if c.get("first"):
|
|
28
|
+
self.assertTrue(hits, c["query"])
|
|
29
|
+
self.assertEqual(hits[0].iso2, c["first"], f'{c["query"]} -> {[h.iso2 for h in hits[:3]]}')
|
|
30
|
+
|
|
31
|
+
def test_sort(self) -> None:
|
|
32
|
+
for c in V["sort"]:
|
|
33
|
+
n = len(c["head"])
|
|
34
|
+
head = [x.iso2 for x in sort_countries(countries(), c["lang"], c["first"])[:n]]
|
|
35
|
+
self.assertEqual(head, c["head"], f'{c["lang"]} {c["first"]}')
|
|
36
|
+
|
|
37
|
+
def test_phone(self) -> None:
|
|
38
|
+
for c in V["phone"]:
|
|
39
|
+
country = by_iso2(c["country"])
|
|
40
|
+
assert country is not None
|
|
41
|
+
p = parse_phone(c["input"], country, countries())
|
|
42
|
+
self.assertIsNotNone(p, c["input"])
|
|
43
|
+
assert p is not None
|
|
44
|
+
got = (p.e164, p.iso2, p.valid, p.mobile)
|
|
45
|
+
self.assertEqual(got, (c["e164"], c["iso2"], c["valid"], c["mobile"]), c["input"])
|
|
46
|
+
|
|
47
|
+
def test_absent(self) -> None:
|
|
48
|
+
for token in V["absent"]:
|
|
49
|
+
self.assertIsNone(by_iso2(token), token)
|
|
50
|
+
self.assertFalse(any(token in (c.iso2, c.iso3, c.name_en, c.name_ar) for c in countries()), token)
|
|
51
|
+
self.assertFalse([c for c in search(countries(), token, "en") if c.iso2 == token], token)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class Data(unittest.TestCase):
|
|
55
|
+
def test_shape(self) -> None:
|
|
56
|
+
self.assertEqual(len(countries()), 242)
|
|
57
|
+
sa = by_iso2("sa")
|
|
58
|
+
assert sa is not None
|
|
59
|
+
self.assertEqual(sa.iso2, "SA")
|
|
60
|
+
self.assertEqual(sa.phone[0].calling_code, "+966")
|
|
61
|
+
self.assertIsNone(by_iso2("ZZ"))
|
|
62
|
+
|
|
63
|
+
def test_subdivisions(self) -> None:
|
|
64
|
+
self.assertEqual(len(subdivisions()), 5012)
|
|
65
|
+
sa = subdivisions("sa")
|
|
66
|
+
self.assertTrue(sa and all(s.iso2 == "SA" for s in sa))
|
|
67
|
+
|
|
68
|
+
def test_every_pattern_compiles(self) -> None:
|
|
69
|
+
for c in countries():
|
|
70
|
+
for p in c.phone:
|
|
71
|
+
for pat in (p.pattern, p.mobile_pattern, p.leading_digits):
|
|
72
|
+
if pat:
|
|
73
|
+
worldref.helpers._regex(pat)
|
|
74
|
+
|
|
75
|
+
def test_format_national(self) -> None:
|
|
76
|
+
sa = by_iso2("SA")
|
|
77
|
+
assert sa is not None
|
|
78
|
+
plan = sa.phone[0]
|
|
79
|
+
self.assertTrue(worldref.is_valid_mobile("0501234567", sa))
|
|
80
|
+
self.assertEqual(worldref.format_national("12", plan), "12")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if __name__ == "__main__":
|
|
84
|
+
unittest.main()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""worldref: countries and territories in Arabic and English."""
|
|
2
|
+
from .data import by_iso2, countries, subdivisions
|
|
3
|
+
from .helpers import ParsedPhone, format_national, is_valid_mobile, parse_phone, search, sort_countries
|
|
4
|
+
from .models import (
|
|
5
|
+
Address, Country, Currency, Emergency, Geo, Language, Locale, Nationality, PhonePlan, Sports, Subdivision, Travel,
|
|
6
|
+
)
|
|
7
|
+
from .text import normalize, western_digits
|
|
8
|
+
|
|
9
|
+
__version__ = "1.0.0"
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"Address", "Country", "Currency", "Emergency", "Geo", "Language", "Locale", "Nationality", "ParsedPhone",
|
|
13
|
+
"PhonePlan", "Sports", "Subdivision", "Travel", "by_iso2", "countries", "format_national", "is_valid_mobile",
|
|
14
|
+
"normalize", "parse_phone", "search", "sort_countries", "subdivisions", "western_digits",
|
|
15
|
+
]
|