Repository navigation
The data is refreshed to iso-codes v4.20.1, the wheel is nearly half the size,
and import is about five times faster. Lookup correctness is the theme of the
breaking changes: find() and search() both returned wrong answers for
reasonable queries, and fixing them changes results.
Upgrading: requires Python 3.11+. Review the Breaking section if you rely on
find() with multiple keywords, on search() result order, or call
gettext.translation() directly against the bundled catalogues.
pip install --upgrade isocodesBreaking
-
Python 3.9 and 3.10 are no longer supported; the minimum is now 3.11.
Both are past or within weeks of end of life, and together they accounted for
0.34% of downloads. Dropping them removes the last version-conditional import,
which is what stopped a single test run from reaching full coverage. -
find()now honours every keyword. It previously returned on the first
indexed field that matched and ignored the rest, so
find(alpha_2="US", name="Nonsense")wrongly returned the United States. -
search()ignores word order and ranks its results. ISO stores many names
inverted, sosearch(name="Republic of Korea")used to return nothing; it now
returnsKorea, Republic offirst. Exact matches rank above prefixes, which
rank above substrings. -
The obsolete catalogue filenames are no longer shipped:
iso_3166.mo,
iso_3166_2.mo,iso_639.mo,iso_639_3.moandiso_639_5.mo. Upstream
installs these as symlinks to the current names, but a wheel turns them into
full copies, which was doubling the package. Every language is still included,
and the old domain names still work throughtranslate()andtranslator().
Only a rawgettext.translation("iso_3166", ...)call needs updating, to
"iso_3166-1".
Added
translate(),translator()andavailable_languages()for reading the
gettext catalogues, replacing the rawgettextrecipe in the README.isocodes localesto list the installed languages and remove unwanted ones,
for trimming container images. It previews by default and needs--yesto
delete anything.search_fuzzy()and a--fuzzyCLI flag, for queries containing typos, built
ondifflibso there is still no dependency.search()is unchanged and
never guesses: the approximate pass runs only when an ordinary search finds
nothing, so a correctly spelled query can never come back with an approximate
answer.
Changed
- The six near-identical CLI search handlers are now one table-driven handler,
and the subcommand parsers are built from the same table.cli.pyis about a
hundred lines shorter, and the CLI no longer loads every dataset at import, so
isocodes --helpandisocodes localesparse no data at all. The command
line interface is unchanged apart from the new--fuzzyflag. - The wheel is 8.1 MB, down from 15 MB, with all 163 languages still
included. The saving is entirely the duplicated catalogues described above. - Data updated to iso-codes v4.20.1 (was v4.18.0). Six currencies were
withdrawn upstream —BGN,HRK,ANG,CUC,SLLandZWL— and three
added:XCG,ZWGandXAD. Bulgaria and Croatia now use the euro. - Datasets load on first use instead of at import.
import isocodesdrops from
~145 ms and ~15 MB to ~29 ms and ~3 MB. get()is around 180x faster. Its substring matching is unchanged.update.shrewritten for meson; upstream dropped autotools in 4.19.0. It now
needsgit,mesonandninja, and takes an optional version tag.- Python 3.14 is supported and tested, including the free-threaded build.
Removed
- Unreachable code in the CLI:
format_output's single-record branches, which
no caller could trigger since every call site passes a list, and the six
"Please specify search criteria" branches, which argparse's required argument
group already prevents.
Fixed
--format jsonand--format csvemittedNo results found.when there
were no matches, which is neither valid JSON nor valid CSV and broke any
caller parsing the output. They now return[]and an empty string;table
still prints the message.--fieldswas ignored by--format json, which returned every field
regardless. Table and CSV already honoured it. JSON now returns only the
requested fields, in the order given.- Package metadata declared both LGPL-2.1 and MIT. The bundled data comes from
Debian's iso-codes, which is LGPL-2.1-or-later, so that is now declared as a
single SPDXLicense-Expression. The conflict caused some license scanners to
reject the package. - The wheel ignored the configured
package-dataglobs and shipped whatever was
in the tree, becauseinclude-package-datadefaults to true.
Full changelog: 2025.8.25...2026.9.2