Package: python-iso639
python-iso639python-iso639is a Python package for accessing ISO 639 language codes, names, and
other associated information.Current features:A representation of languages mapped across ISO 639-1, 639-2, and 639-3.Functionality to "guess" what a language is for a given
unknown language code or name.Installationpipinstallpython-iso639Usagepython-iso639revolves around aLanguageclass.
Instances ofLanguagehave attributes and methods that you will find useful.Note that while the package name registered on PyPI ispython-iso639,
the actual import name during runtime isiso639(which means you should doimport iso639in your Python code).CreatingLanguageInstancesCreate aLanguageinstance by one of the methods.from_part3, with an ISO 639-3 code>>>importiso639>>>lang1=iso639.Language.from_part3('fra')>>>type(lang1)<class'iso639.language.Language'>>>>lang1Language(part3='fra',part2b='fre',part2t='fra',part1='fr',scope='I',type='L',name='French',comment=None,other_names=None,macrolanguage=None,retire_reason=None,retire_change_to=None,retire_remedy=None,retire_date=None)From Another ISO 639 Code Set or a Reference Name>>>lang2=iso639.Language.from_part2b('fre')# ISO 639-2 (bibliographic)>>>lang3=iso639.Language.from_part2t('fra')# ISO 639-2 (terminological)>>>lang4=iso639.Language.from_part1('fr')# ISO 639-1>>>lang5=iso639.Language.from_name('French')# ISO 639-3 reference language nameALanguageNotFoundErroris Raised for Invalid Inputs>>>iso639.Language.from_part3('Fra')# The user input is case-sensitive!Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>LanguageNotFoundError:'Fra'isn't an ISO language code or name>>>>>>iso639.Language.from_name("unknown language")Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>LanguageNotFoundError:'unknown language'isn't an ISO language code or nameAccessing Attributes>>>lang1Language(part3='fra',part2b='fre',part2t='fra',part1='fr',scope='I',type='L',name='French',comment=None,other_names=None,macrolanguage=None,retire_reason=None,retire_change_to=None,retire_remedy=None,retire_date=None)>>>lang1.part3'fra'>>>lang1.name'French'Comparison>>>lang1==lang2==lang3==lang4==lang5# All are FrenchTrue>>>lang6=iso639.Language.from_part3('spa')# Spanish>>>lang1==lang6# French vs. SpanishFalse>>>'French'==lang1.name==lang2.name==lang3.name==lang4.name==lang5.nameTrue>>>lang6.name'Spanish'Guess a Language: ClassmethodmatchYou don't know which code set or name your input is from?
Use thematchclassmethod:>>>lang1=iso639.Language.match('fra')>>>lang2=iso639.Language.match('fre')>>>lang3=iso639.Language.match('fr')>>>lang4=iso639.Language.match('French')>>>lang1==lang2==lang3==lang4TrueThe classmethodmatchis particularly useful for consistently
accessing a specific attribute from unknown inputs, e.g., the ISO 639-3 code.>>>'fra'==lang1.part3==lang2.part3==lang3.part3==lang4.part3TrueIf there's no match, aLanguageNotFoundErroris raised,
which you may want to catch:>>>try:...lang=iso639.Language.match('not gonna find a match')...exceptiso639.LanguageNotFoundError:...print("no match found!")...nomatchfound!Macrolanguages and Alternative Names>>>language=iso639.Language.match('yue')>>>language.name'Yue Chinese'# also commonly known as Cantonese>>>language.macrolanguage'zho'# Chinese>>>language.other_names[Name(print='Yue Chinese',inverted='Chinese, Yue')]>>>fornameinlanguage.other_names:...print(f'{name.print}|{name.inverted}')...YueChinese|Chinese,YueRetired Language Codes:>>>language=iso639.Language.match('bvs')>>>language.part3'bvs'>>>language.name'Belgian Sign Language'>>>language.status'R'# (R)etired>>>language.retire_reason'S'# (S)plit>>>language.retire_change_toisNoneTrue>>>language.retire_remedy'Split into Langue des signes de Belgique Francophone [sfb], and Vlaamse Gebarentaal [vgt]'>>>language.retire_datedatetime.date(2007,7,18)Into the WeedsAttributes of aLanguageInstanceALanguageinstance has the following attributes:AttributeData typeCan it beNone?Descriptionpart3str✗ISO 639-3 codepart2bstr✓ISO 639-2 code (bibliographic)part2tstr✓ISO 639-2 code (terminological)part1str✓ISO 639-1 codescopestr✗One of {(I)ndividual, (M)acrolanguage, (S)pecial}typestr✓One of {(A)ncient, (C)onstructed, (E)xtinct, (H)istorical, (L)iving, (S)pecial} [1]statusstr✗One of {(A)ctive, (R)etired}, describing the ISO 639-3 codenamestr✗Reference language name in ISO 639-3commentstr✓Comment from ISO 639-3other_namesList[Name]✓Other print and inverted names [2]macrolanguagestr✓Macrolanguageretire_reasonstr✓Retirement reason, one of {(C)hange, (D)uplicate, (N)on-existent, (S)plit, (M)erge}retire_change_tostr✓ISO 639-3 code to which this language can be changed, if retirement reason is one of {(C)hange, (D)uplicate, (M)erge}retire_remedystr✓Instructions for updating this retired language coderetire_datedatetime.date✓The date the retirement became effective[1] If the ISO 639-3 code is retired, then thetypeattribute isNone,
because its value is not clearly discernible from the SIL data source.[2] ANameinstance has the attributesprintandinverted,
for the print name and inverted name, respectively.
If reference name, print name, and inverted name are all the same, then
that particular (print name, inverted name) pair is excluded from
theother_namesattribute.
For example, for Spanish (ISO 639-3: spa), one (print name, inverted name)
pair is (Spanish, Spanish) from the SIL data source, but this pair is
excluded from its list ofother_names.HowLanguage.matchMatches the LanguageAt a high level,Language.matchassumes the input is more likely to be
a language code rather than a language name.
Beyond that, the precise order in matching is as follows:ISO 639-3 codes (among the active codes)ISO 639-2 (bibliographic) codesISO 639-2 (terminological) codesISO 639-1 codesISO 639-3 codes (among the retired codes)ISO 639-3 reference language namesISO 639-3 alternative language names (the "print" ones)ISO 639-3 alternative language names (the "inverted" ones)Only exact matching is done (there's no fuzzy string matching of any sort).
As soon as a match is found,Language.matchreturns aLanguageinstance.
If there isn't a match, aLanguageNotFoundErroris raised.Languageis a dataclassTheLanguageclass is a dataclass.
All functionality ofdataclasesapplies toLanguageand its instances,
e.g.,dataclasses.asdict:>>>importdataclasses,iso639>>>language=iso639.Language.match('fra')>>>dataclasses.asdict(language){'part3':'fra','part2b':'fre','part2t':'fra','part1':'fr','scope':'I','type':'L','status':'A','name':'French','comment':None,'other_names':None,'macrolanguage':None,'retire_reason':None,'retire_change_to':None,'retire_remedy':None,'retire_date':None}ConstantsDATA_LAST_UPDATED: The release date of the included language code data from SIL>>>importiso639>>>iso639.DATA_LAST_UPDATEDdatetime.date(2024,2,7)ALL_LANGUAGES: The list of allLanguageobjects based on the included language code data>>>importiso639>>>type(iso639.ALL_LANGUAGES)<class'list'>>>>len(iso639.ALL_LANGUAGES)7919>>>iso639.ALL_LANGUAGES[0]Language(part3='aaa',scope='I',type='L',status='A',name='Ghotuo',...)LinksAuthor:Jackson L. LeeSource code:https://github.com/jacksonllee/iso639License and Data SourceThepython-iso639code is released under an Apache 2.0 license.
Please seeLICENSE.txtfor details.The data source that backs this package is thelanguage code tables published by SIL.
Note that SIL resources have theirterms of use.
For exactly how the data is included in the package,
see the script atscripts/create_languages_db.py.Why Another ISO 639 Package?Both packagesiso639andiso-639exist on PyPI.
However, as of this writing (May 2022), they were last updated in 2016 and don't seem to be maintained anymore
for updating the language codes.pycountryis a great package,
but what if you want a more lightweight package with just the language codes only and not the other stuff? :-)If you ever notice that the upstream ISO 639-3 tables from SIL have been updated
and yet this package isn't using the latest data,
please ping me byopening a GitHub issue.