python-iso639 2025.2.18__tar.gz → 2025.11.16__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.
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/CHANGELOG.md +22 -0
- {python_iso639-2025.2.18/src/python_iso639.egg-info → python_iso639-2025.11.16}/PKG-INFO +26 -21
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/README.md +14 -10
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/pyproject.toml +10 -10
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/__init__.py +1 -1
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/__init__.py +16 -18
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/iso-639-3.tab +14 -11
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/iso-639-3_Name_Index.tab +27 -5
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/iso-639-3_Retirements.tab +20 -22
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/language.py +40 -42
- {python_iso639-2025.2.18 → python_iso639-2025.11.16/src/python_iso639.egg-info}/PKG-INFO +26 -21
- python_iso639-2025.11.16/src/python_iso639.egg-info/requires.txt +9 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/tests/test_language.py +36 -6
- python_iso639-2025.2.18/src/python_iso639.egg-info/requires.txt +0 -9
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/LICENSE.txt +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/MANIFEST.in +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/setup.cfg +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/iso-639-3-macrolanguages.tab +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/py.typed +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/python_iso639.egg-info/SOURCES.txt +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/python_iso639.egg-info/dependency_links.txt +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/python_iso639.egg-info/not-zip-safe +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/python_iso639.egg-info/top_level.txt +0 -0
- {python_iso639-2025.2.18 → python_iso639-2025.11.16}/tests/test_version_number.py +0 -0
|
@@ -17,6 +17,28 @@ major/minor/micro version numbers like `05` (it'd have to be just `5`).
|
|
|
17
17
|
### Fixed
|
|
18
18
|
### Security
|
|
19
19
|
|
|
20
|
+
## [2025.11.16]
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
* Fixed README.md (shown on the PyPI page) for the change from `exact` to `strict_case`
|
|
24
|
+
in `Language.match`.
|
|
25
|
+
|
|
26
|
+
## [2025.11.11]
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
* Added support for Python 3.14.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
* Updated the ISO 639 data from SIL to the latest 2025-10-15 release.
|
|
33
|
+
* Case-insensitive matching for `Language.match` is now opt-in.
|
|
34
|
+
The keyword argument has been renamed `strict_case` (from `exact` before),
|
|
35
|
+
defaulting to `True`.
|
|
36
|
+
|
|
37
|
+
### Removed
|
|
38
|
+
* In `Language.match`, removed the keyword argument `exact`
|
|
39
|
+
(replaced by `strict_case`, defaulting to `True`).
|
|
40
|
+
* Dropped support for Python 3.9.
|
|
41
|
+
|
|
20
42
|
## [2025.2.18]
|
|
21
43
|
|
|
22
44
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: python-iso639
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.11.16
|
|
4
4
|
Summary: ISO 639 language codes, names, and other associated information
|
|
5
5
|
Author-email: "Jackson L. Lee" <jacksonlunlee@gmail.com>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -15,26 +15,27 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
23
|
Classifier: Topic :: Text Processing
|
|
24
24
|
Classifier: Topic :: Text Processing :: General
|
|
25
25
|
Classifier: Topic :: Text Processing :: Indexing
|
|
26
26
|
Classifier: Topic :: Text Processing :: Linguistic
|
|
27
|
-
Requires-Python: >=3.
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
29
|
License-File: LICENSE.txt
|
|
30
30
|
Provides-Extra: dev
|
|
31
|
-
Requires-Dist: black==25.
|
|
32
|
-
Requires-Dist: build==1.
|
|
33
|
-
Requires-Dist: flake8==7.
|
|
34
|
-
Requires-Dist: mypy==1.
|
|
35
|
-
Requires-Dist: pytest==
|
|
36
|
-
Requires-Dist: requests==2.32.
|
|
37
|
-
Requires-Dist: twine==6.
|
|
31
|
+
Requires-Dist: black==25.11.0; extra == "dev"
|
|
32
|
+
Requires-Dist: build==1.3.0; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8==7.3.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy==1.18.2; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest==9.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: requests==2.32.5; extra == "dev"
|
|
37
|
+
Requires-Dist: twine==6.2.0; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
38
39
|
|
|
39
40
|
# python-iso639
|
|
40
41
|
|
|
@@ -154,22 +155,26 @@ Use the `match` classmethod:
|
|
|
154
155
|
True
|
|
155
156
|
```
|
|
156
157
|
|
|
157
|
-
By default, the classmethod `match`
|
|
158
|
-
|
|
159
|
-
To enforce exact matching instead, pass in `exact=True`:
|
|
158
|
+
By default, the classmethod `match` is case-sensitive.
|
|
159
|
+
To ignore case instead, pass in `strict_case=False`:
|
|
160
160
|
|
|
161
161
|
```python
|
|
162
|
-
>>> lang5 = iso639.Language.match('FRA')
|
|
163
|
-
>>> lang6 = iso639.Language.match('
|
|
164
|
-
>>>
|
|
165
|
-
>>> lang4 == lang5 == lang6 == lang7
|
|
162
|
+
>>> lang5 = iso639.Language.match('FRA', strict_case=False)
|
|
163
|
+
>>> lang6 = iso639.Language.match('french', strict_case=False)
|
|
164
|
+
>>> lang4 == lang5 == lang6
|
|
166
165
|
True
|
|
167
|
-
>>> iso639.Language.match("french"
|
|
166
|
+
>>> iso639.Language.match("french")
|
|
168
167
|
Traceback (most recent call last):
|
|
169
168
|
File "<stdin>", line 1, in <module>
|
|
170
169
|
LanguageNotFoundError: 'french' isn't an ISO language code or name
|
|
171
170
|
```
|
|
172
171
|
|
|
172
|
+
> [!NOTE]
|
|
173
|
+
> Depending on your use case, ignoring case could potentially lead to matching issues,
|
|
174
|
+
where a language code might match an unintended language name (or vice versa),
|
|
175
|
+
e.g., conflating "igo" and "Igo", while there exist the ISO 639-3 code `ahl` for Igo and
|
|
176
|
+
the ISO 639-3 code `igo` for Isebe.
|
|
177
|
+
|
|
173
178
|
The classmethod `match` is particularly useful for consistently
|
|
174
179
|
accessing a specific attribute from unknown inputs, e.g., the ISO 639-3 code.
|
|
175
180
|
|
|
@@ -302,7 +307,7 @@ e.g., [`dataclasses.asdict`](https://docs.python.org/3/library/dataclasses.html#
|
|
|
302
307
|
```python
|
|
303
308
|
>>> import iso639
|
|
304
309
|
>>> iso639.DATA_LAST_UPDATED
|
|
305
|
-
datetime.date(2025,
|
|
310
|
+
datetime.date(2025, 10, 15)
|
|
306
311
|
```
|
|
307
312
|
|
|
308
313
|
* `ALL_LANGUAGES`: The list of all `Language` objects based on the included language code data
|
|
@@ -312,7 +317,7 @@ e.g., [`dataclasses.asdict`](https://docs.python.org/3/library/dataclasses.html#
|
|
|
312
317
|
>>> type(iso639.ALL_LANGUAGES)
|
|
313
318
|
<class 'set'>
|
|
314
319
|
>>> len(iso639.ALL_LANGUAGES)
|
|
315
|
-
|
|
320
|
+
8311
|
|
316
321
|
```
|
|
317
322
|
|
|
318
323
|
## Links
|
|
@@ -116,22 +116,26 @@ Use the `match` classmethod:
|
|
|
116
116
|
True
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
By default, the classmethod `match`
|
|
120
|
-
|
|
121
|
-
To enforce exact matching instead, pass in `exact=True`:
|
|
119
|
+
By default, the classmethod `match` is case-sensitive.
|
|
120
|
+
To ignore case instead, pass in `strict_case=False`:
|
|
122
121
|
|
|
123
122
|
```python
|
|
124
|
-
>>> lang5 = iso639.Language.match('FRA')
|
|
125
|
-
>>> lang6 = iso639.Language.match('
|
|
126
|
-
>>>
|
|
127
|
-
>>> lang4 == lang5 == lang6 == lang7
|
|
123
|
+
>>> lang5 = iso639.Language.match('FRA', strict_case=False)
|
|
124
|
+
>>> lang6 = iso639.Language.match('french', strict_case=False)
|
|
125
|
+
>>> lang4 == lang5 == lang6
|
|
128
126
|
True
|
|
129
|
-
>>> iso639.Language.match("french"
|
|
127
|
+
>>> iso639.Language.match("french")
|
|
130
128
|
Traceback (most recent call last):
|
|
131
129
|
File "<stdin>", line 1, in <module>
|
|
132
130
|
LanguageNotFoundError: 'french' isn't an ISO language code or name
|
|
133
131
|
```
|
|
134
132
|
|
|
133
|
+
> [!NOTE]
|
|
134
|
+
> Depending on your use case, ignoring case could potentially lead to matching issues,
|
|
135
|
+
where a language code might match an unintended language name (or vice versa),
|
|
136
|
+
e.g., conflating "igo" and "Igo", while there exist the ISO 639-3 code `ahl` for Igo and
|
|
137
|
+
the ISO 639-3 code `igo` for Isebe.
|
|
138
|
+
|
|
135
139
|
The classmethod `match` is particularly useful for consistently
|
|
136
140
|
accessing a specific attribute from unknown inputs, e.g., the ISO 639-3 code.
|
|
137
141
|
|
|
@@ -264,7 +268,7 @@ e.g., [`dataclasses.asdict`](https://docs.python.org/3/library/dataclasses.html#
|
|
|
264
268
|
```python
|
|
265
269
|
>>> import iso639
|
|
266
270
|
>>> iso639.DATA_LAST_UPDATED
|
|
267
|
-
datetime.date(2025,
|
|
271
|
+
datetime.date(2025, 10, 15)
|
|
268
272
|
```
|
|
269
273
|
|
|
270
274
|
* `ALL_LANGUAGES`: The list of all `Language` objects based on the included language code data
|
|
@@ -274,7 +278,7 @@ e.g., [`dataclasses.asdict`](https://docs.python.org/3/library/dataclasses.html#
|
|
|
274
278
|
>>> type(iso639.ALL_LANGUAGES)
|
|
275
279
|
<class 'set'>
|
|
276
280
|
>>> len(iso639.ALL_LANGUAGES)
|
|
277
|
-
|
|
281
|
+
8311
|
|
278
282
|
```
|
|
279
283
|
|
|
280
284
|
## Links
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "python-iso639"
|
|
7
|
-
version = "2025.
|
|
7
|
+
version = "2025.11.16"
|
|
8
8
|
description = "ISO 639 language codes, names, and other associated information"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">= 3.
|
|
10
|
+
requires-python = ">= 3.10"
|
|
11
11
|
license = { text = "Apache 2.0" }
|
|
12
12
|
authors = [ { name = "Jackson L. Lee", email = "jacksonlunlee@gmail.com" } ]
|
|
13
13
|
keywords = ["ISO 639", "language codes", "languages", "linguistics"]
|
|
@@ -21,11 +21,11 @@ classifiers = [
|
|
|
21
21
|
"Operating System :: OS Independent",
|
|
22
22
|
"Programming Language :: Python :: 3",
|
|
23
23
|
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
-
"Programming Language :: Python :: 3.9",
|
|
25
24
|
"Programming Language :: Python :: 3.10",
|
|
26
25
|
"Programming Language :: Python :: 3.11",
|
|
27
26
|
"Programming Language :: Python :: 3.12",
|
|
28
27
|
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Programming Language :: Python :: 3.14",
|
|
29
29
|
"Topic :: Text Processing",
|
|
30
30
|
"Topic :: Text Processing :: General",
|
|
31
31
|
"Topic :: Text Processing :: Indexing",
|
|
@@ -34,13 +34,13 @@ classifiers = [
|
|
|
34
34
|
|
|
35
35
|
[project.optional-dependencies]
|
|
36
36
|
dev = [
|
|
37
|
-
"black == 25.
|
|
38
|
-
"build == 1.
|
|
39
|
-
"flake8 == 7.
|
|
40
|
-
"mypy == 1.
|
|
41
|
-
"pytest ==
|
|
42
|
-
"requests == 2.32.
|
|
43
|
-
"twine == 6.
|
|
37
|
+
"black == 25.11.0",
|
|
38
|
+
"build == 1.3.0",
|
|
39
|
+
"flake8 == 7.3.0",
|
|
40
|
+
"mypy == 1.18.2",
|
|
41
|
+
"pytest == 9.0.0",
|
|
42
|
+
"requests == 2.32.5",
|
|
43
|
+
"twine == 6.2.0",
|
|
44
44
|
]
|
|
45
45
|
|
|
46
46
|
[project.urls]
|
|
@@ -9,7 +9,7 @@ from .language import ALL_LANGUAGES, Language, LanguageNotFoundError
|
|
|
9
9
|
# While DATA_LAST_UPDATED is strictly the date for the ISO 639-3 data release,
|
|
10
10
|
# __version__ can be bumped for changes other than data updates.
|
|
11
11
|
__version__ = version("python-iso639")
|
|
12
|
-
DATA_LAST_UPDATED = datetime.date(2025,
|
|
12
|
+
DATA_LAST_UPDATED = datetime.date(2025, 10, 15)
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
__all__ = [
|
|
@@ -5,8 +5,6 @@ import os
|
|
|
5
5
|
from collections import defaultdict
|
|
6
6
|
from enum import Enum
|
|
7
7
|
|
|
8
|
-
from typing import Dict, List, Union
|
|
9
|
-
|
|
10
8
|
|
|
11
9
|
class _CodesColumn(Enum):
|
|
12
10
|
ID = "Id"
|
|
@@ -40,10 +38,10 @@ class _MacrolanguagesColumn(Enum):
|
|
|
40
38
|
STATUS = "I_Status"
|
|
41
39
|
|
|
42
40
|
|
|
43
|
-
_COLUMN_TYPE =
|
|
44
|
-
_CodesColumn
|
|
45
|
-
|
|
46
|
-
_ROW_TYPE =
|
|
41
|
+
_COLUMN_TYPE = (
|
|
42
|
+
_CodesColumn | _NameIndexColumn | _RetirementsColumn | _MacrolanguagesColumn
|
|
43
|
+
)
|
|
44
|
+
_ROW_TYPE = dict[_COLUMN_TYPE, str]
|
|
47
45
|
|
|
48
46
|
|
|
49
47
|
class _Table(Enum):
|
|
@@ -62,56 +60,56 @@ _DATA_TSV_PATHS = {
|
|
|
62
60
|
}
|
|
63
61
|
|
|
64
62
|
|
|
65
|
-
def _load_tsv(table: _Table) ->
|
|
63
|
+
def _load_tsv(table: _Table) -> list[_ROW_TYPE]:
|
|
66
64
|
column = table.value
|
|
67
65
|
with open(_DATA_TSV_PATHS[table], encoding="utf-8", newline="") as tsv_file:
|
|
68
66
|
tsv_reader = csv.DictReader(tsv_file, delimiter="\t")
|
|
69
67
|
return [{column(k): v for k, v in row.items()} for row in tsv_reader]
|
|
70
68
|
|
|
71
69
|
|
|
72
|
-
_PART3_TO_CODES:
|
|
70
|
+
_PART3_TO_CODES: dict[str, _ROW_TYPE] = {
|
|
73
71
|
row[_CodesColumn.ID]: row for row in _load_tsv(_Table.CODES)
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
_part3_to_name_index: defaultdict[str,
|
|
74
|
+
_part3_to_name_index: defaultdict[str, list[_ROW_TYPE]] = defaultdict(list)
|
|
77
75
|
for row in _load_tsv(_Table.NAME_INDEX):
|
|
78
76
|
_part3_to_name_index[row[_NameIndexColumn.ID]].append(row)
|
|
79
|
-
_PART3_TO_NAME_INDEX:
|
|
77
|
+
_PART3_TO_NAME_INDEX: dict[str, list[_ROW_TYPE]] = dict(_part3_to_name_index)
|
|
80
78
|
|
|
81
|
-
_PART3_TO_RETIREMENTS:
|
|
79
|
+
_PART3_TO_RETIREMENTS: dict[str, _ROW_TYPE] = {
|
|
82
80
|
row[_RetirementsColumn.ID]: row for row in _load_tsv(_Table.RETIREMENTS)
|
|
83
81
|
}
|
|
84
|
-
_PART3_TO_MACROLANGUAGES:
|
|
82
|
+
_PART3_TO_MACROLANGUAGES: dict[str, _ROW_TYPE] = {
|
|
85
83
|
row[_MacrolanguagesColumn.ID]: row for row in _load_tsv(_Table.MACROLANGUAGES)
|
|
86
84
|
}
|
|
87
85
|
|
|
88
|
-
_PART2B_TO_PART3:
|
|
86
|
+
_PART2B_TO_PART3: dict[str, str] = {
|
|
89
87
|
row[_CodesColumn.PART2B]: part3
|
|
90
88
|
for part3, row in _PART3_TO_CODES.items()
|
|
91
89
|
if row[_CodesColumn.PART2B]
|
|
92
90
|
}
|
|
93
|
-
_PART2T_TO_PART3:
|
|
91
|
+
_PART2T_TO_PART3: dict[str, str] = {
|
|
94
92
|
row[_CodesColumn.PART2T]: part3
|
|
95
93
|
for part3, row in _PART3_TO_CODES.items()
|
|
96
94
|
if row[_CodesColumn.PART2T]
|
|
97
95
|
}
|
|
98
|
-
_PART1_TO_PART3:
|
|
96
|
+
_PART1_TO_PART3: dict[str, str] = {
|
|
99
97
|
row[_CodesColumn.PART1]: part3
|
|
100
98
|
for part3, row in _PART3_TO_CODES.items()
|
|
101
99
|
if row[_CodesColumn.PART1]
|
|
102
100
|
}
|
|
103
|
-
_REF_NAME_TO_PART3:
|
|
101
|
+
_REF_NAME_TO_PART3: dict[str, str] = {
|
|
104
102
|
row[_CodesColumn.REF_NAME]: part3
|
|
105
103
|
for part3, row in _PART3_TO_CODES.items()
|
|
106
104
|
if row[_CodesColumn.REF_NAME]
|
|
107
105
|
}
|
|
108
|
-
_PRINT_NAME_TO_PART3:
|
|
106
|
+
_PRINT_NAME_TO_PART3: dict[str, str] = {
|
|
109
107
|
row[_NameIndexColumn.PRINT_NAME]: part3
|
|
110
108
|
for part3, rows in _PART3_TO_NAME_INDEX.items()
|
|
111
109
|
for row in rows
|
|
112
110
|
if row[_NameIndexColumn.PRINT_NAME]
|
|
113
111
|
}
|
|
114
|
-
_INVERTED_NAME_TO_PART3:
|
|
112
|
+
_INVERTED_NAME_TO_PART3: dict[str, str] = {
|
|
115
113
|
row[_NameIndexColumn.INVERTED_NAME]: part3
|
|
116
114
|
for part3, rows in _PART3_TO_NAME_INDEX.items()
|
|
117
115
|
for row in rows
|
|
@@ -1297,7 +1297,7 @@ cli I L Chakali
|
|
|
1297
1297
|
clj I L Laitu Chin
|
|
1298
1298
|
clk I L Idu-Mishmi
|
|
1299
1299
|
cll I L Chala
|
|
1300
|
-
clm I L
|
|
1300
|
+
clm I L Klallam
|
|
1301
1301
|
clo I L Lowland Oaxaca Chontal
|
|
1302
1302
|
cls I H Classical Sanskrit
|
|
1303
1303
|
clt I L Lautu Chin
|
|
@@ -2325,7 +2325,7 @@ gyz I L Geji
|
|
|
2325
2325
|
gza I L Ganza
|
|
2326
2326
|
gzi I L Gazi
|
|
2327
2327
|
gzn I L Gane
|
|
2328
|
-
haa I L
|
|
2328
|
+
haa I L Hän
|
|
2329
2329
|
hab I L Hanoi Sign Language
|
|
2330
2330
|
hac I L Gurani
|
|
2331
2331
|
had I L Hatam
|
|
@@ -2892,7 +2892,7 @@ kce I L Kaivi
|
|
|
2892
2892
|
kcf I L Ukaan
|
|
2893
2893
|
kcg I L Tyap
|
|
2894
2894
|
kch I L Vono
|
|
2895
|
-
kci I L
|
|
2895
|
+
kci I L Ngyian
|
|
2896
2896
|
kcj I L Kobiana
|
|
2897
2897
|
kck I L Kalanga
|
|
2898
2898
|
kcl I L Kela (Papua New Guinea)
|
|
@@ -3390,7 +3390,7 @@ kwg I L Sara Kaba Deme
|
|
|
3390
3390
|
kwh I L Kowiai
|
|
3391
3391
|
kwi I L Awa-Cuaiquer
|
|
3392
3392
|
kwj I L Kwanga
|
|
3393
|
-
kwk I L
|
|
3393
|
+
kwk I L Kwak'wala
|
|
3394
3394
|
kwl I L Kofyar
|
|
3395
3395
|
kwm I L Kwambi
|
|
3396
3396
|
kwn I L Kwangali
|
|
@@ -3795,7 +3795,7 @@ lup I L Lumbu
|
|
|
3795
3795
|
luq I L Lucumi
|
|
3796
3796
|
lur I L Laura
|
|
3797
3797
|
lus lus lus I L Lushai
|
|
3798
|
-
lut I
|
|
3798
|
+
lut I E Lushootseed
|
|
3799
3799
|
luu I L Lumba-Yakkha
|
|
3800
3800
|
luv I L Luwati
|
|
3801
3801
|
luw I L Luo (Cameroon)
|
|
@@ -4011,7 +4011,7 @@ mhj I L Mogholi
|
|
|
4011
4011
|
mhk I L Mungaka
|
|
4012
4012
|
mhl I L Mauwake
|
|
4013
4013
|
mhm I L Makhuwa-Moniga
|
|
4014
|
-
mhn I L
|
|
4014
|
+
mhn I L Mòcheno
|
|
4015
4015
|
mho I L Mashi (Zambia)
|
|
4016
4016
|
mhp I L Balinese Malay
|
|
4017
4017
|
mhq I L Mandan
|
|
@@ -4574,7 +4574,7 @@ nes I L Bhoti Kinnauri
|
|
|
4574
4574
|
net I L Nete
|
|
4575
4575
|
neu I C Neo
|
|
4576
4576
|
nev I L Nyaheun
|
|
4577
|
-
new new new I L
|
|
4577
|
+
new new new I L Nepal Bhasa
|
|
4578
4578
|
nex I L Neme
|
|
4579
4579
|
ney I L Neyo
|
|
4580
4580
|
nez I L Nez Perce
|
|
@@ -4916,7 +4916,7 @@ nxo I L Ndambomo
|
|
|
4916
4916
|
nxq I L Naxi
|
|
4917
4917
|
nxr I L Ninggerum
|
|
4918
4918
|
nxx I L Nafri
|
|
4919
|
-
nya nya nya ny I L
|
|
4919
|
+
nya nya nya ny I L Chichewa
|
|
4920
4920
|
nyb I L Nyangbo
|
|
4921
4921
|
nyc I L Nyanga-li
|
|
4922
4922
|
nyd I L Nyore
|
|
@@ -4954,6 +4954,7 @@ nzy I L Nzakambay
|
|
|
4954
4954
|
nzz I L Nanga Dama Dogon
|
|
4955
4955
|
oaa I L Orok
|
|
4956
4956
|
oac I L Oroch
|
|
4957
|
+
oak I L Noakhali
|
|
4957
4958
|
oar I H Old Aramaic (up to 700 BCE)
|
|
4958
4959
|
oav I H Old Avar
|
|
4959
4960
|
obi I E Obispeño
|
|
@@ -5017,6 +5018,7 @@ okv I L Orokaiva
|
|
|
5017
5018
|
okx I L Okpe (Northwestern Edo)
|
|
5018
5019
|
okz I H Old Khmer
|
|
5019
5020
|
ola I L Walungge
|
|
5021
|
+
olb I L Oli-Bodiman
|
|
5020
5022
|
old I L Mochi
|
|
5021
5023
|
ole I L Olekha
|
|
5022
5024
|
olk I E Olkol
|
|
@@ -5088,11 +5090,12 @@ ory I L Odia
|
|
|
5088
5090
|
orz I L Ormu
|
|
5089
5091
|
osa osa osa I L Osage
|
|
5090
5092
|
osc I H Oscan
|
|
5093
|
+
osd I L Digor Ossetic
|
|
5091
5094
|
osi I L Osing
|
|
5092
5095
|
osn I H Old Sundanese
|
|
5093
5096
|
oso I L Ososo
|
|
5094
5097
|
osp I H Old Spanish
|
|
5095
|
-
oss oss oss os I L
|
|
5098
|
+
oss oss oss os I L Iron Ossetic
|
|
5096
5099
|
ost I L Osatu
|
|
5097
5100
|
osu I L Southern One
|
|
5098
5101
|
osx I H Old Saxon
|
|
@@ -5758,6 +5761,7 @@ scu I L Shumcho
|
|
|
5758
5761
|
scv I L Sheni
|
|
5759
5762
|
scw I L Sha
|
|
5760
5763
|
scx I H Sicel
|
|
5764
|
+
scz I L Shaetlan
|
|
5761
5765
|
sda I L Toraja-Sa'dan
|
|
5762
5766
|
sdb I L Shabak
|
|
5763
5767
|
sdc I L Sassarese Sardinian
|
|
@@ -7651,7 +7655,6 @@ yob I E Yoba
|
|
|
7651
7655
|
yog I L Yogad
|
|
7652
7656
|
yoi I L Yonaguni
|
|
7653
7657
|
yok I L Yokuts
|
|
7654
|
-
yol I E Yola
|
|
7655
7658
|
yom I L Yombe
|
|
7656
7659
|
yon I L Yongkom
|
|
7657
7660
|
yor yor yor yo I L Yoruba
|
|
@@ -7833,7 +7836,7 @@ zml I E Matngala
|
|
|
7833
7836
|
zmm I L Marimanindji
|
|
7834
7837
|
zmn I L Mbangwe
|
|
7835
7838
|
zmo I L Molo
|
|
7836
|
-
zmp I L
|
|
7839
|
+
zmp I L Mbuun
|
|
7837
7840
|
zmq I L Mituku
|
|
7838
7841
|
zmr I L Maranunggu
|
|
7839
7842
|
zms I L Mbesa
|
{python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/iso-639-3_Name_Index.tab
RENAMED
|
@@ -378,6 +378,7 @@ ary Moroccan Arabic Arabic, Moroccan
|
|
|
378
378
|
arz Egyptian Arabic Arabic, Egyptian
|
|
379
379
|
asa Asu (Tanzania) Asu (Tanzania)
|
|
380
380
|
asb Assiniboine Assiniboine
|
|
381
|
+
asb Nakoda Assiniboine Nakoda Assiniboine
|
|
381
382
|
asc Casuarina Coast Asmat Asmat, Casuarina Coast
|
|
382
383
|
ase American Sign Language American Sign Language
|
|
383
384
|
asf Auslan Auslan
|
|
@@ -413,6 +414,7 @@ ate Atemble Atemble
|
|
|
413
414
|
atg Ivbie North-Okpela-Arhe Ivbie North-Okpela-Arhe
|
|
414
415
|
ati Attié Attié
|
|
415
416
|
atj Atikamekw Atikamekw
|
|
417
|
+
atj Nehirowimowin Nehirowimowin
|
|
416
418
|
atk Ati Ati
|
|
417
419
|
atl Mt. Iraya Agta Agta, Mt. Iraya
|
|
418
420
|
atm Ata Ata
|
|
@@ -1340,6 +1342,7 @@ cky Cakfem-Mushere Cakfem-Mushere
|
|
|
1340
1342
|
ckz Cakchiquel-Quiché Mixed Language Cakchiquel-Quiché Mixed Language
|
|
1341
1343
|
cla Ron Ron
|
|
1342
1344
|
clc Chilcotin Chilcotin
|
|
1345
|
+
clc Tsilhqot’in Tsilhqot’in
|
|
1343
1346
|
cld Chaldean Neo-Aramaic Neo-Aramaic, Chaldean
|
|
1344
1347
|
cle Lealao Chinantec Chinantec, Lealao
|
|
1345
1348
|
clh Chilisso Chilisso
|
|
@@ -1348,6 +1351,7 @@ clj Laitu Chin Chin, Laitu
|
|
|
1348
1351
|
clk Idu-Mishmi Idu-Mishmi
|
|
1349
1352
|
cll Chala Chala
|
|
1350
1353
|
clm Clallam Clallam
|
|
1354
|
+
clm Klallam Klallam
|
|
1351
1355
|
clo Lowland Oaxaca Chontal Chontal, Lowland Oaxaca
|
|
1352
1356
|
cls Classical Sanskrit Classical Sanskrit
|
|
1353
1357
|
clt Lautu Chin Chin, Lautu
|
|
@@ -2432,7 +2436,7 @@ gyz Gyaazi Gyaazi
|
|
|
2432
2436
|
gza Ganza Ganza
|
|
2433
2437
|
gzi Gazi Gazi
|
|
2434
2438
|
gzn Gane Gane
|
|
2435
|
-
haa
|
|
2439
|
+
haa Hän Hän
|
|
2436
2440
|
hab Hanoi Sign Language Hanoi Sign Language
|
|
2437
2441
|
hac Gurani Gurani
|
|
2438
2442
|
had Hatam Hatam
|
|
@@ -3042,6 +3046,7 @@ kcf Ukaan Ukaan
|
|
|
3042
3046
|
kcg Tyap Tyap
|
|
3043
3047
|
kch Vono Vono
|
|
3044
3048
|
kci Kamantan Kamantan
|
|
3049
|
+
kci Ngyian Ngyian
|
|
3045
3050
|
kcj Kobiana Kobiana
|
|
3046
3051
|
kck Kalanga Kalanga
|
|
3047
3052
|
kcl Kala Kala
|
|
@@ -3565,6 +3570,7 @@ kwh Kowiai Kowiai
|
|
|
3565
3570
|
kwi Awa-Cuaiquer Awa-Cuaiquer
|
|
3566
3571
|
kwj Kwanga Kwanga
|
|
3567
3572
|
kwk Kwakiutl Kwakiutl
|
|
3573
|
+
kwk Kwak'wala Kwak'wala
|
|
3568
3574
|
kwl Kofyar Kofyar
|
|
3569
3575
|
kwm Kwambi Kwambi
|
|
3570
3576
|
kwn Kwangali Kwangali
|
|
@@ -4217,7 +4223,7 @@ mhj Mogholi Mogholi
|
|
|
4217
4223
|
mhk Mungaka Mungaka
|
|
4218
4224
|
mhl Mauwake Mauwake
|
|
4219
4225
|
mhm Makhuwa-Moniga Makhuwa-Moniga
|
|
4220
|
-
mhn
|
|
4226
|
+
mhn Mòcheno Mòcheno
|
|
4221
4227
|
mho Mashi (Zambia) Mashi (Zambia)
|
|
4222
4228
|
mhp Balinese Malay Malay, Balinese
|
|
4223
4229
|
mhq Mandan Mandan
|
|
@@ -4804,6 +4810,7 @@ net Nete Nete
|
|
|
4804
4810
|
neu Neo Neo
|
|
4805
4811
|
nev Nyaheun Nyaheun
|
|
4806
4812
|
new Nepal Bhasa Bhasa, Nepal
|
|
4813
|
+
new Newar Newar
|
|
4807
4814
|
new Newari Newari
|
|
4808
4815
|
nex Neme Neme
|
|
4809
4816
|
ney Neyo Neyo
|
|
@@ -5202,6 +5209,8 @@ nzy Nzakambay Nzakambay
|
|
|
5202
5209
|
nzz Nanga Dama Dogon Dogon, Nanga Dama
|
|
5203
5210
|
oaa Orok Orok
|
|
5204
5211
|
oac Oroch Oroch
|
|
5212
|
+
oak Noakhailla Noakhailla
|
|
5213
|
+
oak Noakhali Noakhali
|
|
5205
5214
|
oar Ancient Aramaic (up to 700 BCE) Aramaic, Ancient (up to 700 BCE)
|
|
5206
5215
|
oar Old Aramaic (up to 700 BCE) Aramaic, Old (up to 700 BCE)
|
|
5207
5216
|
oav Old Avar Avar, Old
|
|
@@ -5266,6 +5275,7 @@ okv Orokaiva Orokaiva
|
|
|
5266
5275
|
okx Okpe (Northwestern Edo) Okpe (Northwestern Edo)
|
|
5267
5276
|
okz Old Khmer Khmer, Old
|
|
5268
5277
|
ola Walungge Walungge
|
|
5278
|
+
olb Oli-Bodiman Oli-Bodiman
|
|
5269
5279
|
old Mochi Mochi
|
|
5270
5280
|
ole Olekha Olekha
|
|
5271
5281
|
olk Olkol Olkol
|
|
@@ -5338,10 +5348,16 @@ ory Oriya (individual language) Oriya (individual language)
|
|
|
5338
5348
|
orz Ormu Ormu
|
|
5339
5349
|
osa Osage Osage
|
|
5340
5350
|
osc Oscan Oscan
|
|
5351
|
+
osd Digor Digor
|
|
5352
|
+
osd Digor Ossetian Ossetian, Digor
|
|
5353
|
+
osd Digor Ossetic Ossetic, Digor
|
|
5341
5354
|
osi Osing Osing
|
|
5342
5355
|
osn Old Sundanese Sundanese, Old
|
|
5343
5356
|
oso Ososo Ososo
|
|
5344
5357
|
osp Old Spanish Spanish, Old
|
|
5358
|
+
oss Iron Iron
|
|
5359
|
+
oss Iron Ossetian Ossetian, Iron
|
|
5360
|
+
oss Iron Ossetic Ossetic, Iron
|
|
5345
5361
|
oss Ossetian Ossetian
|
|
5346
5362
|
oss Ossetic Ossetic
|
|
5347
5363
|
ost Osatu Osatu
|
|
@@ -5738,7 +5754,7 @@ pyx Pyu (Myanmar) Pyu (Myanmar)
|
|
|
5738
5754
|
pyy Pyen Pyen
|
|
5739
5755
|
pze Pesse Pesse
|
|
5740
5756
|
pzh Pazeh Pazeh
|
|
5741
|
-
pzn Jejara Naga Jejara
|
|
5757
|
+
pzn Jejara Naga Naga, Jejara
|
|
5742
5758
|
pzn Para Naga Naga, Para
|
|
5743
5759
|
qua Quapaw Quapaw
|
|
5744
5760
|
qub Huallaga Huánuco Quechua Quechua, Huallaga Huánuco
|
|
@@ -6043,6 +6059,7 @@ scu Shumcho Shumcho
|
|
|
6043
6059
|
scv Sheni Sheni
|
|
6044
6060
|
scw Sha Sha
|
|
6045
6061
|
scx Sicel Sicel
|
|
6062
|
+
scz Shaetlan Shaetlan
|
|
6046
6063
|
sda Toraja-Sa'dan Toraja-Sa'dan
|
|
6047
6064
|
sdb Shabak Shabak
|
|
6048
6065
|
sdc Sassarese Sardinian Sardinian, Sassarese
|
|
@@ -6066,6 +6083,7 @@ sdz Sallands Sallands
|
|
|
6066
6083
|
sea Semai Semai
|
|
6067
6084
|
seb Shempire Senoufo Senoufo, Shempire
|
|
6068
6085
|
sec Sechelt Sechelt
|
|
6086
|
+
sec She shashishalhem She shashishalhem
|
|
6069
6087
|
sed Sedang Sedang
|
|
6070
6088
|
see Seneca Seneca
|
|
6071
6089
|
sef Cebaara Senoufo Senoufo, Cebaara
|
|
@@ -6130,6 +6148,7 @@ sho Shanga Shanga
|
|
|
6130
6148
|
shp Shipibo-Conibo Shipibo-Conibo
|
|
6131
6149
|
shq Sala Sala
|
|
6132
6150
|
shr Shi Shi
|
|
6151
|
+
shs Secwepemctsín Secwepemctsín
|
|
6133
6152
|
shs Shuswap Shuswap
|
|
6134
6153
|
sht Shasta Shasta
|
|
6135
6154
|
shu Chadian Arabic Arabic, Chadian
|
|
@@ -6335,6 +6354,7 @@ sqq Sou Sou
|
|
|
6335
6354
|
sqr Siculo Arabic Arabic, Siculo
|
|
6336
6355
|
sqs Sri Lankan Sign Language Sri Lankan Sign Language
|
|
6337
6356
|
sqt Soqotri Soqotri
|
|
6357
|
+
squ Sḵwx̱wú7mesh sníchim Sḵwx̱wú7mesh sníchim
|
|
6338
6358
|
squ Squamish Squamish
|
|
6339
6359
|
sqx Kufr Qassem Sign Language (KQSL) Kufr Qassem Sign Language (KQSL)
|
|
6340
6360
|
sra Saruga Saruga
|
|
@@ -6668,11 +6688,14 @@ thk Tharaka Tharaka
|
|
|
6668
6688
|
thl Dangaura Tharu Tharu, Dangaura
|
|
6669
6689
|
thm Aheu Aheu
|
|
6670
6690
|
thn Thachanadan Thachanadan
|
|
6691
|
+
thp Nłeʔkepmxcín Nłeʔkepmxcín
|
|
6671
6692
|
thp Thompson Thompson
|
|
6693
|
+
thp Thompson River Salish Salish, Thompson River
|
|
6672
6694
|
thq Kochila Tharu Tharu, Kochila
|
|
6673
6695
|
thr Rana Tharu Tharu, Rana
|
|
6674
6696
|
ths Thakali Thakali
|
|
6675
6697
|
tht Tahltan Tahltan
|
|
6698
|
+
tht Tāłtān Tāłtān
|
|
6676
6699
|
thu Thuri Thuri
|
|
6677
6700
|
thv Tahaggart Tamahaq Tamahaq, Tahaggart
|
|
6678
6701
|
thy Tha Tha
|
|
@@ -8011,7 +8034,6 @@ yob Yoba Yoba
|
|
|
8011
8034
|
yog Yogad Yogad
|
|
8012
8035
|
yoi Yonaguni Yonaguni
|
|
8013
8036
|
yok Yokuts Yokuts
|
|
8014
|
-
yol Yola Yola
|
|
8015
8037
|
yom Yombe Yombe
|
|
8016
8038
|
yon Yongkom Yongkom
|
|
8017
8039
|
yor Yoruba Yoruba
|
|
@@ -8201,7 +8223,7 @@ zmm Marimanindji Marimanindji
|
|
|
8201
8223
|
zmm Marramaninyshi Marramaninyshi
|
|
8202
8224
|
zmn Mbangwe Mbangwe
|
|
8203
8225
|
zmo Molo Molo
|
|
8204
|
-
zmp
|
|
8226
|
+
zmp Mbuun Mbuun
|
|
8205
8227
|
zmq Mituku Mituku
|
|
8206
8228
|
zmr Maranunggu Maranunggu
|
|
8207
8229
|
zms Mbesa Mbesa
|
{python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/iso-639-3_Retirements.tab
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Id Ref_Name Ret_Reason Change_To Ret_Remedy Effective
|
|
2
|
-
fri Western Frisian C fry
|
|
2
|
+
fri Western Frisian C fry 2005-11-16
|
|
3
3
|
auv Auvergnat M oci 2007-03-14
|
|
4
4
|
gsc Gascon M oci 2007-03-14
|
|
5
5
|
lms Limousin M oci 2007-03-14
|
|
@@ -18,7 +18,6 @@ mob Moinba S Split into five languages: Chug [cvg]; Lish [lsh]; Kalaktang Monp
|
|
|
18
18
|
mzf Aiku S Split into four languages: Ambrak [aag]; Yangum Dey [yde]; Yangum Gel [ygl]; Yangum Mon [ymo] 2007-07-18
|
|
19
19
|
nhj Tlalitzlipa Nahuatl M nhi 2007-07-18
|
|
20
20
|
nhs Southeastern Puebla Nahuatl S Split into Sierra Negra Nahuatl [nsu] and Southeastern Puebla Nahuatl [npl] 2007-07-18
|
|
21
|
-
occ Occidental D ile 2007-07-18
|
|
22
21
|
tmx Tomyang M ybi 2007-07-18
|
|
23
22
|
tot Patla-Chicontla Totonac S Split into Upper Necaxa Totonac [tku] and Tecpatlán Totonac [tcw] 2007-07-18
|
|
24
23
|
xmi Miarrã N 2007-07-18
|
|
@@ -27,6 +26,7 @@ ztc Lachirioag Zapotec M zty 2007-07-18
|
|
|
27
26
|
atf Atuence N 2007-08-10
|
|
28
27
|
bqe Navarro-Labourdin Basque M eus 2007-08-10
|
|
29
28
|
bsz Souletin Basque M eus 2007-08-10
|
|
29
|
+
occ Occidental D ile 2007-12-07
|
|
30
30
|
aex Amerax M eng 2008-01-14
|
|
31
31
|
ahe Ahe M knx 2008-01-14
|
|
32
32
|
aiz Aari S Split into Aari [aiw] (new identifier) and Gayil [gyl] 2008-01-14
|
|
@@ -169,21 +169,21 @@ cmk Chimakum D xch 2010-01-18
|
|
|
169
169
|
drh Darkhat M khk 2010-01-18
|
|
170
170
|
drw Darwazi M prs 2010-01-18
|
|
171
171
|
gav Gabutamon M dev 2010-01-18
|
|
172
|
-
mof Mohegan-Montauk-Narragansett S
|
|
172
|
+
mof Mohegan-Montauk-Narragansett S Split into Mohegan-Pequot [xpq] and Narragansett [xnt] 2010-01-18
|
|
173
173
|
mst Cataelano Mandaya M mry 2010-01-18
|
|
174
174
|
myt Sangab Mandaya M mry 2010-01-18
|
|
175
|
-
rmr Caló S
|
|
176
|
-
sgl Sanglechi-Ishkashimi S
|
|
175
|
+
rmr Caló S Split into Caló [rmq] and Erromintxela [emx] 2010-01-18
|
|
176
|
+
sgl Sanglechi-Ishkashimi S Split into Sanglechi [sgy] and Ishkashimi [isk] 2010-01-18
|
|
177
177
|
sul Surigaonon S Split into Tandaganon [tgn] and Surigaonon [sgd] (new identifier) 2010-01-18
|
|
178
178
|
sum Sumo-Mayangna S Split into Mayangna [yan] and Ulwa [ulw] 2010-01-18
|
|
179
179
|
tnf Tangshewi M prs 2010-01-18
|
|
180
180
|
wgw Wagawaga S Split into Yaleba [ylb] and Wagawaga [wgb] (new identifier) 2010-01-18
|
|
181
181
|
ayx Ayi (China) D nun 2011-05-18
|
|
182
|
-
bjq Southern Betsimisaraka Malagasy S
|
|
182
|
+
bjq Southern Betsimisaraka Malagasy S Split into Southern Betsimisaraka [bzc] and Tesaka Malagasy [tkg] 2011-05-18
|
|
183
183
|
dha Dhanwar (India) N 2011-05-18
|
|
184
|
-
dkl Kolum So Dogon S
|
|
184
|
+
dkl Kolum So Dogon S Split into Ampari Dogon [aqd] and Mombo Dogon [dmb] 2011-05-18
|
|
185
185
|
mja Mahei N 2011-05-18
|
|
186
|
-
nbf Naxi S
|
|
186
|
+
nbf Naxi S Split into Naxi [nxq] and Narua [nru] 2011-05-18
|
|
187
187
|
noo Nootka S Split into [dtd] Ditidaht and [nuk] Nuu-chah-nulth 2011-05-18
|
|
188
188
|
tie Tingal M ras 2011-05-18
|
|
189
189
|
tkk Takpa D twm 2011-05-18
|
|
@@ -195,15 +195,14 @@ dap Nisi (India) S Split into Nyishi [njz] and Tagin [tgj] 2012-02-03
|
|
|
195
195
|
dwl Walo Kumbe Dogon S Split into Dogon, Bankan Tey (Walo) [dbw] and Dogon, Ben Tey (Beni) [dbt] 2012-02-03
|
|
196
196
|
elp Elpaputih N 2012-02-03
|
|
197
197
|
gbc Garawa S Split into Garrwa [wrk] and Wanyi [wny] 2012-02-03
|
|
198
|
-
gio Gelao S Split into Qau [gqu] and A'ou [aou]
|
|
198
|
+
gio Gelao S Split into Qau [gqu] and A'ou [aou] 2012-02-03
|
|
199
199
|
hrr Horuru M jal 2012-02-03
|
|
200
200
|
ibi Ibilo M opa 2012-02-03
|
|
201
|
-
jar Jarawa (Nigeria) S
|
|
202
|
-
kdv Kado S
|
|
201
|
+
jar Jarawa (Nigeria) S Split into Gwak [jgk] and Bankal [jjr] 2012-02-03
|
|
202
|
+
kdv Kado S Split into Kadu [zkd] and Kanan [zkn] 2012-02-03
|
|
203
203
|
kgh Upper Tanudan Kalinga M kml 2012-02-03
|
|
204
204
|
kpp Paku Karen S Split into Paku Karen [jkp] and Mobwa Karen [jkm] 2012-02-03
|
|
205
205
|
kzh Kenuzi-Dongola S Split into Andaandi (Dongolawi) [dgl] and Kenzi (Mattoki) [xnz] 2012-02-03
|
|
206
|
-
lcq Luhu M ppr 2012-02-03
|
|
207
206
|
mgx Omati S Split into Barikewa [jbk] and Mouwase [jmw] 2012-02-03
|
|
208
207
|
nln Durango Nahuatl S Split into Eastern Durango Nahuatl [azd] and Western Durango Nahuatl [azn] 2012-02-03
|
|
209
208
|
pbz Palu N 2012-02-03
|
|
@@ -248,7 +247,6 @@ aue ǂKxʼauǁʼein D ktz 2015-01-12
|
|
|
248
247
|
bmy Bemba (Democratic Republic of Congo) N 2015-01-12
|
|
249
248
|
bxx Borna (Democratic Republic of Congo) N 2015-01-12
|
|
250
249
|
byy Buya N 2015-01-12
|
|
251
|
-
dzd Daza N 2015-01-12
|
|
252
250
|
gfx Mangetti Dune ǃXung M vaj 2015-01-12
|
|
253
251
|
gti Gbati-ri M nyc 2015-01-12
|
|
254
252
|
ime Imeraguen N 2015-01-12
|
|
@@ -265,7 +263,6 @@ sgo Songa N 2015-01-12
|
|
|
265
263
|
thx The D oyb 2015-01-12
|
|
266
264
|
tsf Southwestern Tamang M taj 2015-01-12
|
|
267
265
|
uok Uokha M ema 2015-01-12
|
|
268
|
-
xsj Subi D suj 2015-01-12
|
|
269
266
|
yds Yiddish Sign Language N 2015-01-12
|
|
270
267
|
ymt Mator-Taygi-Karagas D mtm 2015-01-12
|
|
271
268
|
ynh Yangho N 2015-01-12
|
|
@@ -276,9 +273,9 @@ cbh Cagua N 2016-01-15
|
|
|
276
273
|
coy Coyaima M pij 2016-01-15
|
|
277
274
|
cqu Chilean Quechua M quh 2016-01-15
|
|
278
275
|
cum Cumeral N 2016-01-15
|
|
279
|
-
duj Dhuwal S
|
|
276
|
+
duj Dhuwal S Split into [dwu] Dhuwal and [dwy] Dhuwaya 2016-01-15
|
|
280
277
|
ggn Eastern Gurung M gvr 2016-01-15
|
|
281
|
-
ggo Southern Gondi S
|
|
278
|
+
ggo Southern Gondi S Split into [esg] Aheri Gondi and [wsg] Adilabad Gondi 2016-01-15
|
|
282
279
|
guv Gey M duz 2016-01-15
|
|
283
280
|
iap Iapama N 2016-01-15
|
|
284
281
|
ill Iranun S Split into Iranun (Philippines) [ilp] and Iranun (Malaysia) [ilm] 2016-01-15
|
|
@@ -349,7 +346,7 @@ plp Palpa N 2020-01-23
|
|
|
349
346
|
sdm Semandang S Split into Semandang [sdq], Beginci [ebc] and Gerai [gef] 2020-01-23
|
|
350
347
|
tbb Tapeba N 2020-01-23
|
|
351
348
|
xrq Karranga M dmw 2020-01-23
|
|
352
|
-
xtz Tasmanian S Split into [xpv] Northern Tasman, [xph] North Midlands Tasman, [xpb] Northeastern Tasman, [xpd] Oyster Bay
|
|
349
|
+
xtz Tasmanian S Split into [xpv] Northern Tasman, [xph] North Midlands Tasman, [xpb] Northeastern Tasman, [xpd] Oyster Bay Tasman, [xpf] Southeast Tasman, [xpx] Southwestern Tasman, [xpw] Northwestern Tasman, [xpl] Port Sorell Tasman, and [xpz] Bruny Island Tasman 2020-01-23
|
|
353
350
|
zir Ziriya D scv 2020-01-23
|
|
354
351
|
thw Thudam M ola 2020-03-19
|
|
355
352
|
bic Bikaru M bir 2021-01-15
|
|
@@ -361,7 +358,7 @@ ngo Ngoni S Split into Ngoni (Tanzania) [xnj] and Ngoni (Mozambique) [xnq] 2021
|
|
|
361
358
|
pat Papitalai M kxr 2021-01-15
|
|
362
359
|
vki Ija-Zuba S Split into Koro Nulu [vkn] and Koro Zuba [vkz] 2021-01-15
|
|
363
360
|
wra Warapu S Split into Bauni [bpe], Uni [uni] and Bouni [suo] 2021-01-15
|
|
364
|
-
ajt Judeo-Tunisian Arabic
|
|
361
|
+
ajt Judeo-Tunisian Arabic M aeb 2022-01-20
|
|
365
362
|
cug Chungmboko S Split into Chung [cnq] and Mbuk [bpc] 2022-01-20
|
|
366
363
|
lak Laka (Nigeria) M ksp 2022-01-20
|
|
367
364
|
lno Lango (South Sudan) S Split into Lango [lgo], Imotong [imt], Logir [lqr] and Okolie [oie] 2022-01-20
|
|
@@ -373,7 +370,9 @@ wrd Warduji N 2022-01-20
|
|
|
373
370
|
wya Wyandot S Split into Wyandot [wyn] and Wendat [wdt] 2022-01-20
|
|
374
371
|
ajp South Levantine Arabic M apc 2023-01-20
|
|
375
372
|
kgm Karipúna D plu 2023-01-20
|
|
373
|
+
ksa Shuwa-Zamani S Split into [rsw] Rishiwa and [izm] Kizamani 2023-01-20
|
|
376
374
|
nom Nocamán M cbr 2023-01-20
|
|
375
|
+
plj Polci S Split into Pesse [pze], Nyamzak-Dir-Mbarimi [nzr], Zul [zlu], and Buli [uly] 2023-01-20
|
|
377
376
|
pmk Pamlico M crr 2023-01-20
|
|
378
377
|
prp Parsi M guj 2023-01-20
|
|
379
378
|
slq Salchuq N 2023-01-20
|
|
@@ -383,7 +382,6 @@ tpw Tupí D tpn 2023-01-20
|
|
|
383
382
|
xss Assan M zko 2023-01-20
|
|
384
383
|
zkb Koibal D kjh 2023-01-20
|
|
385
384
|
zua Zeem S Split into [tvi] Tulai, [dyr] Dyarim, [dsk] Dokshi, [cxh] Cha'ari, and [zem] Zeem 2023-01-20
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
nte Nathembo M eko 2024-09-09
|
|
385
|
+
dek Dek D sqm 2024-10-15
|
|
386
|
+
nte Nathembo M eko 2024-10-15
|
|
387
|
+
yol Yola M enm 2025-10-15
|
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import datetime
|
|
6
6
|
from dataclasses import dataclass
|
|
7
7
|
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import NoReturn
|
|
9
9
|
|
|
10
10
|
from ._data import (
|
|
11
11
|
_PART3_TO_CODES,
|
|
@@ -26,10 +26,7 @@ from ._data import (
|
|
|
26
26
|
)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
_STRING_CLEANING_FUNCS = [
|
|
30
|
-
lambda x: x.strip().lower(),
|
|
31
|
-
lambda x: x.strip().title(),
|
|
32
|
-
]
|
|
29
|
+
_STRING_CLEANING_FUNCS = [lambda x: x.lower(), lambda x: x.title()]
|
|
33
30
|
|
|
34
31
|
|
|
35
32
|
class LanguageNotFoundError(Exception):
|
|
@@ -73,31 +70,26 @@ class Language:
|
|
|
73
70
|
|
|
74
71
|
# From the "codes" table
|
|
75
72
|
part3: str
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
# When support for Python 3.9 is dropped, we will switch to the pipe syntax
|
|
80
|
-
# for `... | None`.
|
|
81
|
-
part2b: Union[str, None]
|
|
82
|
-
part2t: Union[str, None]
|
|
83
|
-
part1: Union[str, None]
|
|
73
|
+
part2b: str | None
|
|
74
|
+
part2t: str | None
|
|
75
|
+
part1: str | None
|
|
84
76
|
scope: str
|
|
85
|
-
type:
|
|
77
|
+
type: str | None
|
|
86
78
|
status: str
|
|
87
79
|
name: str
|
|
88
|
-
comment:
|
|
80
|
+
comment: str | None
|
|
89
81
|
|
|
90
82
|
# From the "name_index" table
|
|
91
|
-
other_names:
|
|
83
|
+
other_names: list[Name] | None
|
|
92
84
|
|
|
93
85
|
# From the "macrolanguages" table
|
|
94
|
-
macrolanguage:
|
|
86
|
+
macrolanguage: str | None
|
|
95
87
|
|
|
96
88
|
# From the "retirements" table
|
|
97
|
-
retire_reason:
|
|
98
|
-
retire_change_to:
|
|
99
|
-
retire_remedy:
|
|
100
|
-
retire_date:
|
|
89
|
+
retire_reason: str | None
|
|
90
|
+
retire_change_to: str | None
|
|
91
|
+
retire_remedy: str | None
|
|
92
|
+
retire_date: datetime.date | None
|
|
101
93
|
|
|
102
94
|
def __hash__(self) -> int:
|
|
103
95
|
return hash(self.part3)
|
|
@@ -106,17 +98,19 @@ class Language:
|
|
|
106
98
|
return isinstance(other, Language) and self.part3 == other.part3
|
|
107
99
|
|
|
108
100
|
@classmethod
|
|
109
|
-
def match(cls, user_input: str, /, *,
|
|
101
|
+
def match(cls, user_input: str, /, *, strict_case: bool = True) -> Language:
|
|
110
102
|
"""Return a ``Language`` instance by matching on the user input.
|
|
111
103
|
|
|
112
104
|
Parameters
|
|
113
105
|
----------
|
|
114
106
|
user_input : str
|
|
115
107
|
A language code or name.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
108
|
+
strict_case : bool, optional
|
|
109
|
+
Defaults to ``True``, for enforcing strict case sensitivity.
|
|
110
|
+
If ``False`` and if ``user_input`` doesn't find a match,
|
|
111
|
+
further match attempts will be made with the all-lowercase version of
|
|
112
|
+
``user_input`` (``"foobar"``) and the title-case version of ``user_input``
|
|
113
|
+
(``"Foobar"``).
|
|
120
114
|
|
|
121
115
|
Returns
|
|
122
116
|
-------
|
|
@@ -140,7 +134,7 @@ class Language:
|
|
|
140
134
|
# Order of columns to query the data tables.
|
|
141
135
|
# Bias towards (and therefore prioritize) the user input being
|
|
142
136
|
# a language code rather than a language name.
|
|
143
|
-
query_order:
|
|
137
|
+
query_order: list[_COLUMN_TYPE] = [
|
|
144
138
|
_CodesColumn.ID,
|
|
145
139
|
_CodesColumn.PART2B,
|
|
146
140
|
_CodesColumn.PART2T,
|
|
@@ -150,7 +144,7 @@ class Language:
|
|
|
150
144
|
_NameIndexColumn.PRINT_NAME,
|
|
151
145
|
_NameIndexColumn.INVERTED_NAME,
|
|
152
146
|
]
|
|
153
|
-
return _PART3_TO_LANGUAGES[_get_part3(user_input, query_order,
|
|
147
|
+
return _PART3_TO_LANGUAGES[_get_part3(user_input, query_order, strict_case)]
|
|
154
148
|
|
|
155
149
|
@classmethod
|
|
156
150
|
def from_part3(cls, user_input: str, /) -> Language:
|
|
@@ -177,7 +171,7 @@ class Language:
|
|
|
177
171
|
@classmethod
|
|
178
172
|
def from_name(cls, user_input: str, /) -> Language:
|
|
179
173
|
"""Return a ``Language`` instance from an ISO 639-3 reference language name."""
|
|
180
|
-
query_order:
|
|
174
|
+
query_order: list[_COLUMN_TYPE] = [
|
|
181
175
|
_CodesColumn.REF_NAME,
|
|
182
176
|
_NameIndexColumn.PRINT_NAME,
|
|
183
177
|
_NameIndexColumn.INVERTED_NAME,
|
|
@@ -190,7 +184,7 @@ def _raise_language_not_found_error(user_input: str) -> NoReturn:
|
|
|
190
184
|
|
|
191
185
|
|
|
192
186
|
def _get_part3(
|
|
193
|
-
user_input: str, query_order:
|
|
187
|
+
user_input: str, query_order: list[_COLUMN_TYPE], strict_case: bool = True
|
|
194
188
|
) -> str:
|
|
195
189
|
"""Get the part 3 code of a language.
|
|
196
190
|
|
|
@@ -200,9 +194,12 @@ def _get_part3(
|
|
|
200
194
|
The user-provided language code or name.
|
|
201
195
|
query_order : List[_COLUMN_TYPE]
|
|
202
196
|
A list of columns to specify query order.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
If
|
|
197
|
+
strict_case : bool, optional
|
|
198
|
+
Defaults to ``True``, for enforcing strict case sensitivity.
|
|
199
|
+
If ``False`` and if ``user_input`` doesn't find a match,
|
|
200
|
+
further match attempts will be made with the all-lowercase version of
|
|
201
|
+
``user_input`` (``"foobar"``) and the title-case version of ``user_input``
|
|
202
|
+
(``"Foobar"``).
|
|
206
203
|
|
|
207
204
|
Returns
|
|
208
205
|
-------
|
|
@@ -216,7 +213,7 @@ def _get_part3(
|
|
|
216
213
|
try:
|
|
217
214
|
return _get_part3_exact(user_input, query_order)
|
|
218
215
|
except LanguageNotFoundError as e:
|
|
219
|
-
if
|
|
216
|
+
if strict_case:
|
|
220
217
|
raise e
|
|
221
218
|
else:
|
|
222
219
|
for func in _STRING_CLEANING_FUNCS:
|
|
@@ -230,8 +227,8 @@ def _get_part3(
|
|
|
230
227
|
|
|
231
228
|
def _get_part3_exact(
|
|
232
229
|
user_input: str,
|
|
233
|
-
query_order:
|
|
234
|
-
original_user_input:
|
|
230
|
+
query_order: list[_COLUMN_TYPE],
|
|
231
|
+
original_user_input: str | None = None,
|
|
235
232
|
) -> str:
|
|
236
233
|
"""Get the part 3 code of a language.
|
|
237
234
|
|
|
@@ -239,7 +236,7 @@ def _get_part3_exact(
|
|
|
239
236
|
----------
|
|
240
237
|
user_input : str
|
|
241
238
|
The user-provided language code or name.
|
|
242
|
-
query_order :
|
|
239
|
+
query_order : list[_COLUMN_TYPE]
|
|
243
240
|
A list of columns to specify query order.
|
|
244
241
|
original_user_input : str, optional
|
|
245
242
|
The original user input. Default is `None`.
|
|
@@ -254,7 +251,8 @@ def _get_part3_exact(
|
|
|
254
251
|
LanguageNotFoundError
|
|
255
252
|
If `part3` isn't a language name or code
|
|
256
253
|
"""
|
|
257
|
-
|
|
254
|
+
user_input = user_input.strip()
|
|
255
|
+
part3: str | None = None
|
|
258
256
|
for column in query_order:
|
|
259
257
|
if column == _CodesColumn.ID:
|
|
260
258
|
if user_input in _PART3_TO_CODES:
|
|
@@ -307,7 +305,7 @@ def _get_language(part3: str) -> Language:
|
|
|
307
305
|
else from_retirements[_RetirementsColumn.REF_NAME] # type: ignore
|
|
308
306
|
)
|
|
309
307
|
|
|
310
|
-
other_names:
|
|
308
|
+
other_names: list[Name] | None = []
|
|
311
309
|
for row in _PART3_TO_NAME_INDEX.get(part3, []):
|
|
312
310
|
p, i = row[_NameIndexColumn.PRINT_NAME], row[_NameIndexColumn.INVERTED_NAME]
|
|
313
311
|
if not ref_name == p == i:
|
|
@@ -370,7 +368,7 @@ def _get_language(part3: str) -> Language:
|
|
|
370
368
|
return language
|
|
371
369
|
|
|
372
370
|
|
|
373
|
-
def _get_all_languages() ->
|
|
371
|
+
def _get_all_languages() -> dict[str, Language]:
|
|
374
372
|
languages = {}
|
|
375
373
|
for part3 in _PART3_TO_CODES:
|
|
376
374
|
languages[part3] = _get_language(part3)
|
|
@@ -379,6 +377,6 @@ def _get_all_languages() -> Dict[str, Language]:
|
|
|
379
377
|
return languages
|
|
380
378
|
|
|
381
379
|
|
|
382
|
-
_PART3_TO_LANGUAGES:
|
|
380
|
+
_PART3_TO_LANGUAGES: dict[str, Language] = _get_all_languages()
|
|
383
381
|
|
|
384
|
-
ALL_LANGUAGES:
|
|
382
|
+
ALL_LANGUAGES: set[Language] = set(_PART3_TO_LANGUAGES.values())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: python-iso639
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.11.16
|
|
4
4
|
Summary: ISO 639 language codes, names, and other associated information
|
|
5
5
|
Author-email: "Jackson L. Lee" <jacksonlunlee@gmail.com>
|
|
6
6
|
License: Apache 2.0
|
|
@@ -15,26 +15,27 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
15
15
|
Classifier: Operating System :: OS Independent
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
17
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
23
|
Classifier: Topic :: Text Processing
|
|
24
24
|
Classifier: Topic :: Text Processing :: General
|
|
25
25
|
Classifier: Topic :: Text Processing :: Indexing
|
|
26
26
|
Classifier: Topic :: Text Processing :: Linguistic
|
|
27
|
-
Requires-Python: >=3.
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
28
|
Description-Content-Type: text/markdown
|
|
29
29
|
License-File: LICENSE.txt
|
|
30
30
|
Provides-Extra: dev
|
|
31
|
-
Requires-Dist: black==25.
|
|
32
|
-
Requires-Dist: build==1.
|
|
33
|
-
Requires-Dist: flake8==7.
|
|
34
|
-
Requires-Dist: mypy==1.
|
|
35
|
-
Requires-Dist: pytest==
|
|
36
|
-
Requires-Dist: requests==2.32.
|
|
37
|
-
Requires-Dist: twine==6.
|
|
31
|
+
Requires-Dist: black==25.11.0; extra == "dev"
|
|
32
|
+
Requires-Dist: build==1.3.0; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8==7.3.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy==1.18.2; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest==9.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: requests==2.32.5; extra == "dev"
|
|
37
|
+
Requires-Dist: twine==6.2.0; extra == "dev"
|
|
38
|
+
Dynamic: license-file
|
|
38
39
|
|
|
39
40
|
# python-iso639
|
|
40
41
|
|
|
@@ -154,22 +155,26 @@ Use the `match` classmethod:
|
|
|
154
155
|
True
|
|
155
156
|
```
|
|
156
157
|
|
|
157
|
-
By default, the classmethod `match`
|
|
158
|
-
|
|
159
|
-
To enforce exact matching instead, pass in `exact=True`:
|
|
158
|
+
By default, the classmethod `match` is case-sensitive.
|
|
159
|
+
To ignore case instead, pass in `strict_case=False`:
|
|
160
160
|
|
|
161
161
|
```python
|
|
162
|
-
>>> lang5 = iso639.Language.match('FRA')
|
|
163
|
-
>>> lang6 = iso639.Language.match('
|
|
164
|
-
>>>
|
|
165
|
-
>>> lang4 == lang5 == lang6 == lang7
|
|
162
|
+
>>> lang5 = iso639.Language.match('FRA', strict_case=False)
|
|
163
|
+
>>> lang6 = iso639.Language.match('french', strict_case=False)
|
|
164
|
+
>>> lang4 == lang5 == lang6
|
|
166
165
|
True
|
|
167
|
-
>>> iso639.Language.match("french"
|
|
166
|
+
>>> iso639.Language.match("french")
|
|
168
167
|
Traceback (most recent call last):
|
|
169
168
|
File "<stdin>", line 1, in <module>
|
|
170
169
|
LanguageNotFoundError: 'french' isn't an ISO language code or name
|
|
171
170
|
```
|
|
172
171
|
|
|
172
|
+
> [!NOTE]
|
|
173
|
+
> Depending on your use case, ignoring case could potentially lead to matching issues,
|
|
174
|
+
where a language code might match an unintended language name (or vice versa),
|
|
175
|
+
e.g., conflating "igo" and "Igo", while there exist the ISO 639-3 code `ahl` for Igo and
|
|
176
|
+
the ISO 639-3 code `igo` for Isebe.
|
|
177
|
+
|
|
173
178
|
The classmethod `match` is particularly useful for consistently
|
|
174
179
|
accessing a specific attribute from unknown inputs, e.g., the ISO 639-3 code.
|
|
175
180
|
|
|
@@ -302,7 +307,7 @@ e.g., [`dataclasses.asdict`](https://docs.python.org/3/library/dataclasses.html#
|
|
|
302
307
|
```python
|
|
303
308
|
>>> import iso639
|
|
304
309
|
>>> iso639.DATA_LAST_UPDATED
|
|
305
|
-
datetime.date(2025,
|
|
310
|
+
datetime.date(2025, 10, 15)
|
|
306
311
|
```
|
|
307
312
|
|
|
308
313
|
* `ALL_LANGUAGES`: The list of all `Language` objects based on the included language code data
|
|
@@ -312,7 +317,7 @@ e.g., [`dataclasses.asdict`](https://docs.python.org/3/library/dataclasses.html#
|
|
|
312
317
|
>>> type(iso639.ALL_LANGUAGES)
|
|
313
318
|
<class 'set'>
|
|
314
319
|
>>> len(iso639.ALL_LANGUAGES)
|
|
315
|
-
|
|
320
|
+
8311
|
|
316
321
|
```
|
|
317
322
|
|
|
318
323
|
## Links
|
|
@@ -7,9 +7,10 @@ import pytest
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
@pytest.mark.parametrize(
|
|
10
|
-
"user_input,
|
|
10
|
+
"user_input, strict_case, expected_part3",
|
|
11
11
|
[
|
|
12
12
|
("fra", True, "fra"),
|
|
13
|
+
(" fra ", True, "fra"),
|
|
13
14
|
("fra", False, "fra"),
|
|
14
15
|
("FRA", True, None),
|
|
15
16
|
("FRA", False, "fra"),
|
|
@@ -28,12 +29,38 @@ import pytest
|
|
|
28
29
|
("Castilian", True, "spa"),
|
|
29
30
|
],
|
|
30
31
|
)
|
|
31
|
-
def test_match(user_input,
|
|
32
|
+
def test_match(user_input, strict_case, expected_part3):
|
|
32
33
|
if expected_part3 is None:
|
|
33
34
|
with pytest.raises(LanguageNotFoundError):
|
|
34
|
-
Language.match(user_input,
|
|
35
|
+
Language.match(user_input, strict_case=strict_case)
|
|
35
36
|
else:
|
|
36
|
-
actual_part3 = Language.match(user_input,
|
|
37
|
+
actual_part3 = Language.match(user_input, strict_case=strict_case).part3
|
|
38
|
+
assert actual_part3 == expected_part3
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.mark.parametrize(
|
|
42
|
+
"user_input, expected_part3",
|
|
43
|
+
[
|
|
44
|
+
("fra", "fra"),
|
|
45
|
+
(" fra ", "fra"),
|
|
46
|
+
("FRA", None),
|
|
47
|
+
(" FRA ", None),
|
|
48
|
+
("Fra", None),
|
|
49
|
+
(" Fra ", None),
|
|
50
|
+
("French", "fra"),
|
|
51
|
+
("FRENCH", None),
|
|
52
|
+
(" FRENCH ", None),
|
|
53
|
+
("french", None),
|
|
54
|
+
(" french ", None),
|
|
55
|
+
("Castilian", "spa"),
|
|
56
|
+
],
|
|
57
|
+
)
|
|
58
|
+
def test_match_no_strict_case_kwarg(user_input, expected_part3):
|
|
59
|
+
if expected_part3 is None:
|
|
60
|
+
with pytest.raises(LanguageNotFoundError):
|
|
61
|
+
Language.match(user_input)
|
|
62
|
+
else:
|
|
63
|
+
actual_part3 = Language.match(user_input).part3
|
|
37
64
|
assert actual_part3 == expected_part3
|
|
38
65
|
|
|
39
66
|
|
|
@@ -105,12 +132,15 @@ def test_invalid_inputs():
|
|
|
105
132
|
|
|
106
133
|
|
|
107
134
|
def test_data_last_updated():
|
|
108
|
-
assert DATA_LAST_UPDATED == datetime.date(2025,
|
|
135
|
+
assert DATA_LAST_UPDATED == datetime.date(2025, 10, 15), "Need to update README.md"
|
|
109
136
|
|
|
110
137
|
|
|
111
138
|
def test_all_languages():
|
|
112
139
|
assert type(ALL_LANGUAGES) is set
|
|
113
|
-
|
|
140
|
+
# Defining `len_all_languages` so that when the assertion fails,
|
|
141
|
+
# the error message is more informative.
|
|
142
|
+
len_all_languages = len(ALL_LANGUAGES)
|
|
143
|
+
assert len_all_languages == 8311, "Need to update README.md"
|
|
114
144
|
lang = list(ALL_LANGUAGES)[0]
|
|
115
145
|
assert type(lang) is Language
|
|
116
146
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/iso639/_data/iso-639-3-macrolanguages.tab
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/python_iso639.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/python_iso639.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{python_iso639-2025.2.18 → python_iso639-2025.11.16}/src/python_iso639.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|