Local names and writing systems
PyWorldAtlas can show every bundled country or area in English and in one selected local language. Names remain ordinary Unicode strings, so Arabic, Chinese, Devanagari, Japanese, Cyrillic, and Latin text work offline without a translation service.
Coverage at a glance
The current dataset separates four claims that are easy to confuse:
Layer |
Coverage |
Source |
|---|---|---|
English identity |
248 / 248 countries and areas |
United Nations M49 |
English formal name |
240 / 248 profiles |
World Factbook base, five UN Protocol excerpts, three Wikidata statements |
Selected local display name |
248 / 248 countries and areas |
Unicode CLDR 48.2, with 10 reviewed UNGEGN replacements |
Reviewed national official short and formal name |
10 / 248 records in the current development batch |
UNGEGN |
The local display-name layer is complete. The narrower national-official local layer remains a reviewed workstream and is never silently filled with a convenient translation. English formal names are a separate 240-profile layer.
Understand the English fields
name, official_name, and formal_name are related but not
interchangeable:
>>> from pyworldatlas import Atlas
>>> atlas = Atlas()
>>> turkey = atlas.country("TR")
>>> turkey.name
'Turkey'
>>> turkey.official_name
'Türkiye'
>>> turkey.formal_name
'Republic of Türkiye'
>>> turkey.has_distinct_formal_name
True
name is the familiar English atlas label. official_name retains the
canonical English UN M49 identity. formal_name is the sourced English long
form. Japan demonstrates that a sourced formal identity may equal the short
form:
>>> japan = atlas.country("JP")
>>> (japan.name, japan.official_name, japan.formal_name)
('Japan', 'Japan', 'Japan')
>>> japan.has_distinct_formal_name
False
>>> len(atlas.countries_with_formal_names())
240
Eight areas outside the captured English formal-name source intersection return
None. A false has_distinct_formal_name therefore does not by itself mean
that a profile is covered; inspect formal_name when the distinction matters.
Start with one country
The English name is the normal Country identity. Use
name_in() for the selected local-language record:
>>> saudi = atlas.country("Saudi Arabia")
>>> saudi.name
'Saudi Arabia'
>>> saudi.local_name_languages
('ar',)
>>> saudi.name_in("ar")
'المملكة العربية السعودية'
>>> saudi.local_name("AR").script_code
'Arab'
Language matching is case-insensitive and exact. The method does not translate at runtime and does not substitute a different language when the requested code is absent.
Explore writing systems
The same API returns text in many scripts:
>>> atlas.country("United Arab Emirates").name_in("ar")
'الإمارات العربية المتحدة'
>>> atlas.country("China").name_in("zh")
'中国'
>>> atlas.country("India").name_in("hi")
'भारत'
>>> atlas.country("Japan").name_in("ja")
'日本'
Inspect the evidence level
local_name() returns an immutable
LocalizedName. Its kind explains what the source
actually supports.
locale_displayA Unicode CLDR territory display name in a selected official or de-facto official language. It is suitable for labels, interfaces, search, lessons, and maps. It is not presented as a diplomatic formal name.
national_officialA visually reviewed UNGEGN national official short name with its formal form and source-provided romanization when available.
For example, Andorra has complete local display coverage but its formal Catalan name is not in the reviewed UNGEGN layer:
>>> andorra = atlas.country("Andorra").local_name("ca")
>>> (andorra.short_name, andorra.kind, andorra.language_status)
('Andorra', 'locale_display', 'official')
>>> andorra.formal_name is None
True
>>> andorra.source.id
'unicode-cldr-48.2'
>>> "common/main/ca.xml" in andorra.source_locator
True
The Dominican Republic already has a reviewed national official record:
>>> dominican = atlas.country("DO").local_name("es")
>>> (dominican.short_name, dominican.formal_name)
('República Dominicana', 'República Dominicana')
>>> dominican.kind
'national_official'
>>> dominican.is_national_official
True
>>> dominican.source.id
'ungegn-country-names-2017'
>>> 'PDF page 30' in dominican.source_locator
True
Romanization is source data
Romanization is present only when UNGEGN prints it. PyWorldAtlas never creates one at runtime:
>>> china = atlas.country("China")
>>> china.romanized_name_in("zh")
'Zhongguo'
>>> china.romanized_official_name_in("zh")
'Zhonghua Renmin Gongheguo'
>>> india = atlas.country("India")
>>> india.romanized_name_in("hi")
'Bhārat'
>>> andorra.romanized_short_name is None
True
Discover coverage
countries_with_local_names() can filter the complete
identity layer by BCP 47 language code or ISO 15924 script code:
>>> len(atlas.countries_with_local_names())
248
>>> len(atlas.countries_with_local_names(name_kind="national_official"))
10
>>> len(atlas.countries_with_local_names(name_kind="locale_display"))
238
>>> len(atlas.countries_with_local_names(language_code="es"))
20
>>> [country.name for country in atlas.countries_with_local_names(script_code="Jpan")]
['Japan']
>>> len(atlas.countries_with_local_names(script_code="Arab"))
25
Results are alphabetical. Each country or area currently contributes exactly one selected local identity, matching the deliberately small identity contract.
How the language is selected
The CLDR extractor uses a deterministic rule:
Prefer a language marked
official.Then consider
de_facto_officialandofficial_regional.Within the same status, prefer the language with the highest recorded population percentage.
If that locale does not contain the territory name, try the next eligible language.
Four remote or uninhabited areas do not have an applicable official-language
selection in CLDR. Their useful administrative display name remains available,
but is_official_language is False and language_status explains why:
>>> antarctica = atlas.country("Antarctica").local_names[0]
>>> (antarctica.short_name, antarctica.is_official_language)
('Antarctica', False)
>>> antarctica.language_status
'not_applicable'
Source and review rules
Preserve source Unicode in NFC form.
Record the exact CLDR locale/XPath or UNGEGN PDF entry and page.
Keep display names and national official names as different evidence levels.
Keep formal names and romanizations missing until the authoritative source supplies them.
Never infer a broader legal classification from a localized display label.
The English Country.formal_name layer follows its own source policy. Do not
use it as a substitute for official_name_in(language_code); the latter is a
local-language field with a stricter national-official evidence kind.
See Data sources and freshness for licensing, versioning, and source roles. The full
contract and later anthem, motto, and reference-date boundaries are recorded in
docs/project/COUNTRY_IDENTITY_DATA_SPEC.md in the source repository.
Try the example
1"""Explore English formal names, local identities, and writing systems."""
2
3import sys
4
5from pyworldatlas import Atlas
6
7
8if hasattr(sys.stdout, "reconfigure"):
9 sys.stdout.reconfigure(encoding="utf-8")
10
11
12with Atlas() as atlas:
13 print("Three English name fields")
14 turkey = atlas.country("TR")
15 print("Display:", turkey.name)
16 print("Canonical:", turkey.official_name)
17 print("Formal:", turkey.formal_name)
18 print(len(atlas.countries_with_formal_names()), "formal-name profiles")
19
20 print("\nA reviewed national official name")
21 dominican = atlas.country("DO")
22 print(dominican.flag, dominican.name, "->", dominican.name_in("es"))
23 print("Formal:", dominican.official_name_in("es"))
24
25 print("\nAcross writing systems")
26 for code, language in (
27 ("AE", "ar"),
28 ("CN", "zh"),
29 ("IN", "hi"),
30 ("JP", "ja"),
31 ):
32 country = atlas.country(code)
33 name = country.local_name(language)
34 print(f"{country.flag} {name.short_name} [{name.script_code}]")
35 print(" Evidence:", name.kind)
36 if name.formal_name:
37 print(" Formal:", name.formal_name)
38 if name.romanized_short_name:
39 print(" Romanized:", name.romanized_short_name)
40
41 print("\nComplete local identity coverage")
42 print(len(atlas.countries_with_local_names()), "countries and areas")
43
44 print("\nDisplay name versus formal official name")
45 andorra = atlas.country("AD").local_name("ca")
46 print(andorra.short_name, andorra.kind)
47 print("Formal name reviewed:", andorra.formal_name)
>>> atlas.close()