Repository: jmsv/ety-python

Issue:
Any word with generic Nahuatl language will raise exception
Language code for Nahuatl is missing.

`print(ety.tree('avocado'))`

Will raise an exception:
"Language with iso code 'nah' unknown"

ISO 639 specifies it:
[https://en.wikipedia.org/wiki/Template:ISO_639_name_nah](https://en.wikipedia.org/wiki/Template:ISO_639_name_nah)

Recommend adding it to data/iso-639-3.json

btw thank you! awesome work!

Discussion:

Patch:
diff --git a/.travis.yml b/.travis.yml
index 0eb324e..e5e3da2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,12 +30,7 @@ install:
 before_script:
   - pip install flake8
   - pip install pytest
-  - pip install codecov
 
 script:
   - timeout 30s python -c "import tests; tests.test_circular_etymology()"
-  - coverage run -m pytest tests.py
-
-after_success:
-  - codecov
-
+  - pytest tests.py
diff --git a/Pipfile b/Pipfile
index 60fcf8c..25875a9 100644
--- a/Pipfile
+++ b/Pipfile
@@ -14,8 +14,11 @@ pylint = "*"
 requests = "*"
 clint = "*"
 pytest = "*"
-codecov = "*"
 black = "==18.6b4"
 
 [requires]
 python_version = "3.6"
+
+[scripts]
+test = "pytest tests.py"
+format = "black ."
diff --git a/README.md b/README.md
index 4553b68..f4840db 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,6 @@
 <a href="https://pypi.python.org/pypi/ety"><img src="https://img.shields.io/pypi/wheel/ety.svg" alt="Wheel Support"></a>
 <a href="https://ety-python.readthedocs.io/en/latest/?badge=latest"><img src="https://readthedocs.org/projects/ety-python/badge/?version=latest" alt="Documentation Status"></a><br>
 <a href="https://travis-ci.org/jmsv/ety-python"><img src="https://travis-ci.org/jmsv/ety-python.svg?branch=master" alt="Build Status"></a>
-<a href="https://codecov.io/gh/jmsv/ety-python"><img src="https://codecov.io/gh/jmsv/ety-python/branch/master/graph/badge.svg" alt="codecov"></a>
 <a href="https://github.com/ambv/black"><img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="Code style: black"></a>
 </p>
 
@@ -44,10 +43,10 @@ python setup.py install
 >>> ety.origins("potato")
 [Word(batata, language=Taino)]
 
->>> ety.origins('drink', recursive=True)
+>>> ety.origins("drink", recursive=True)
 [Word(drync, language=Old English (ca. 450-1100)), Word(drinken, language=Middle English (1100-1500)), Word(drincan, language=Old English (ca. 450-1100))]
 
->>> print(ety.tree('aerodynamically'))
+>>> print(ety.tree("aerodynamically"))
 aerodynamically (English)
 ├── -ally (English)
 └── aerodynamic (English)
diff --git a/codecov.yml b/codecov.yml
deleted file mode 100644
index 3fb7f55..0000000
--- a/codecov.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-coverage:
-  status:
-    project: yes
-    patch: no
diff --git a/docs/about/changelog.md b/docs/about/changelog.md
index d7af90a..75fe5fb 100644
--- a/docs/about/changelog.md
+++ b/docs/about/changelog.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## [1.3.2] - 2019/08/11
+
+### Fixed
+
+- Use ISO-639-2 language codes if 639-3 lookup fails
+
 ## [1.3.1] - 2018/07/28
 
 ### Fixed
diff --git a/docs/index.md b/docs/index.md
index 43ade3e..bd7570a 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -40,10 +40,10 @@ python setup.py install
 >>> ety.origins("potato")
 [Word(batata, language=Taino)]
 
->>> ety.origins('drink', recursive=True)
+>>> ety.origins("drink", recursive=True)
 [Word(drync, language=Old English (ca. 450-1100)), Word(drinken, language=Middle English (1100-1500)), Word(drincan, language=Old English (ca. 450-1100))]
 
->>> print(ety.tree('aerodynamically'))
+>>> print(ety.tree("aerodynamically"))
 aerodynamically (English)
 ├── -ally (English)
 └── aerodynamic (English)
diff --git a/ety/__init__.py b/ety/__init__.py
index e9a75f7..e2cfd11 100644
--- a/ety/__init__.py
+++ b/ety/__init__.py
@@ -10,7 +10,7 @@ from .tree import EtyTree
 from .word import Word, Language  # noqa: F401
 
 
-__version__ = "1.3.1"
+__version__ = "1.3.2"
 
 
 def _get_source_word(word, language, color=False):
diff --git a/ety/census.py b/ety/census.py
index a002ff2..175b157 100644
--- a/ety/census.py
+++ b/ety/census.py
@@ -28,8 +28,7 @@ class Census(object):
             else:
                 raise ValueError(
                     "Invalid word type: '%s'. Words must "
-                    "be ety.Word objects or strings"
-                    % str(type(word))
+                    "be ety.Word objects or strings" % str(type(word))
                 )
 
     def origins(self, recursive=False):
diff --git a/ety/data/__init__.py b/ety/data/__init__.py
index 17d204b..b04d095 100644
--- a/ety/data/__init__.py
+++ b/ety/data/__init__.py
@@ -7,17 +7,16 @@ import json
 from pkg_resources import resource_filename
 
 
-def load_etymologies():
-    resource = resource_filename('ety', 'data/etymologies.json')
-    with io.open(resource, 'r', encoding='utf-8') as f:
+def load_json_resource(resource):
+    resource = resource_filename("ety", resource)
+    with io.open(resource, "r", encoding="utf-8") as f:
         return json.load(f)
 
 
-def load_country_codes():
-    resource = resource_filename('ety', 'data/iso-639-3.json')
-    with io.open(resource, 'r', encoding='utf-8') as f:
-        return json.load(f)
+def load_country_codes(iso_version):
+    return load_json_resource("data/iso-{}.json".format(iso_version))
 
 
-etyms = load_etymologies()
-langs = load_country_codes()
+etyms = load_json_resource("data/etymologies.json")
+iso_639_3_codes = load_country_codes("639-3")
+iso_639_2_codes = load_country_codes("639-2")
diff --git a/ety/data/generate.py b/ety/data/generate.py
index ffde91a..4c82dd0 100644
--- a/ety/data/generate.py
+++ b/ety/data/generate.py
@@ -31,16 +31,17 @@ def download_dataset(url, dl_path):
     """
     r = requests.get(url, stream=True)
 
-    with open(dl_path, 'wb') as f:
-        total_length = int(r.headers.get('content-length'))
+    with open(dl_path, "wb") as f:
+        total_length = int(r.headers.get("content-length"))
         chunk_size = 4096
         for chunk in progress.bar(
-                r.iter_content(chunk_size=chunk_size),
-                expected_size=(total_length / chunk_size) + 1):
+            r.iter_content(chunk_size=chunk_size),
+            expected_size=(total_length / chunk_size) + 1,
+        ):
             if chunk:
                 f.write(chunk)
                 f.flush()
-    print('Downloaded to ' + dl_path)
+    print("Downloaded to " + dl_path)
 
 
 def verify_local_data(url, dl_path):
@@ -50,14 +51,14 @@ def verify_local_data(url, dl_path):
     :return: True if local file matches, otherwise False
     """
     try:
-        with open(dl_path, 'rb') as f:
+        with open(dl_path, "rb") as f:
             # Local file checksum
             actual = hashlib.md5(f.read()).hexdigest()
     except EnvironmentError:
         # Return False if file doesn't exit
         return False
 
-    expected = requests.get('%s.checksum' % url).text.strip()
+    expected = requests.get("%s.checksum" % url).text.strip()
     return actual == expected
 
 
@@ -67,11 +68,11 @@ def split_elements(compound):
     e.g.: 'rel:etymology' => ['rel', 'etymology']
     :return: Elements as list
     """
-    elements = [e.strip() for e in compound.split(':')]
+    elements = [e.strip() for e in compound.split(":")]
     if len(elements) == 2:
         return elements
 
-    result = [elements[0], ':'.join(elements[1:])]
+    result = [elements[0], ":".join(elements[1:])]
     return result
 
 
@@ -82,14 +83,14 @@ def generate_json(source_path, dir):
     """
     result = {}
 
-    print('Loading source tsv')
-    with io.open(source_path, 'r', newline='', encoding='utf-8') as source:
-        reader = csv.reader(source, delimiter='\t')
+    print("Loading source tsv")
+    with io.open(source_path, "r", newline="", encoding="utf-8") as source:
+        reader = csv.reader(source, delimiter="\t")
         source_rows = list(reader)
 
     gc.collect()
 
-    print('Structuring data')
+    print("Structuring data")
     for row in progress.bar(source_rows):
         source_lang, source_word = split_elements(row[0])
 
@@ -110,8 +111,8 @@ def generate_json(source_path, dir):
     #         f.write(json.dumps(result[key], sort_keys=False))
 
     # Save data
-    print('Writing etymologies file')
-    with io.open(os.path.join(dir, 'etymologies.json'), 'w') as f:
+    print("Writing etymologies file")
+    with io.open(os.path.join(dir, "etymologies.json"), "w") as f:
         json.dump(result, f)
 
 
@@ -120,9 +121,9 @@ def main():
     Define paths, download data if required, generate json dataset
     """
     dir = os.path.dirname(os.path.realpath(__file__))
-    source_dir = os.path.join(dir, 'source')
-    source_path = os.path.join(source_dir, 'etymwn.tsv')
-    source_url = 'https://data.jmsv.me/etymwn-filtered.tsv'
+    source_dir = os.path.join(dir, "source")
+    source_path = os.path.join(source_dir, "etymwn.tsv")
+    source_url = "https://data.jmsv.me/etymwn-filtered.tsv"
 
     # Exit if not Python 3
     if not six.PY3:
@@ -133,22 +134,22 @@ def main():
 
     # (Re)download data if required
     if not verify_local_data(source_url, source_path):
-        print('Downloading source data')
+        print("Downloading source data")
         download_dataset(source_url, source_path)
 
         # If checksum still doesn't match, exit
         if verify_local_data(source_url, source_path):
-            print('Verified local source data')
+            print("Verified local source data")
         else:
-            print('Error verifying local source data, exiting')
+            print("Error verifying local source data, exiting")
             exit(1)
     else:
-        print('Verified local source data')
+        print("Verified local source data")
 
     generate_json(source_path, dir)
 
-    print('Done')
+    print("Done")
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main()
diff --git a/ety/data/iso-639-2.json b/ety/data/iso-639-2.json
new file mode 100644
index 0000000..871617e
--- /dev/null
+++ b/ety/data/iso-639-2.json
@@ -0,0 +1,489 @@
+{
+  "aar": "Afar",
+  "abk": "Abkhazian",
+  "ace": "Achinese",
+  "ach": "Acoli",
+  "ada": "Adangme",
+  "ady": "Adyghe; Adygei",
+  "afa": "Afro-Asiatic languages",
+  "afh": "Afrihili",
+  "afr": "Afrikaans",
+  "ain": "Ainu",
+  "aka": "Akan",
+  "akk": "Akkadian",
+  "alb": "Albanian",
+  "ale": "Aleut",
+  "alg": "Algonquian languages",
+  "alt": "Southern Altai",
+  "amh": "Amharic",
+  "ang": "English, Old (ca.450-1100)",
+  "anp": "Angika",
+  "apa": "Apache languages",
+  "ara": "Arabic",
+  "arc": "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)",
+  "arg": "Aragonese",
+  "arm": "Armenian",
+  "arn": "Mapudungun; Mapuche",
+  "arp": "Arapaho",
+  "art": "Artificial languages",
+  "arw": "Arawak",
+  "asm": "Assamese",
+  "ast": "Asturian; Bable; Leonese; Asturleonese",
+  "ath": "Athapascan languages",
+  "aus": "Australian languages",
+  "ava": "Avaric",
+  "ave": "Avestan",
+  "awa": "Awadhi",
+  "aym": "Aymara",
+  "aze": "Azerbaijani",
+  "bad": "Banda languages",
+  "bai": "Bamileke languages",
+  "bak": "Bashkir",
+  "bal": "Baluchi",
+  "bam": "Bambara",
+  "ban": "Balinese",
+  "baq": "Basque",
+  "bas": "Basa",
+  "bat": "Baltic languages",
+  "bej": "Beja; Bedawiyet",
+  "bel": "Belarusian",
+  "bem": "Bemba",
+  "ben": "Bengali",
+  "ber": "Berber languages",
+  "bho": "Bhojpuri",
+  "bih": "Bihari languages",
+  "bik": "Bikol",
+  "bin": "Bini; Edo",
+  "bis": "Bislama",
+  "bla": "Siksika",
+  "bnt": "Bantu (Other)",
+  "bos": "Bosnian",
+  "bra": "Braj",
+  "bre": "Breton",
+  "btk": "Batak languages",
+  "bua": "Buriat",
+  "bug": "Buginese",
+  "bul": "Bulgarian",
+  "bur": "Burmese",
+  "byn": "Blin; Bilin",
+  "cad": "Caddo",
+  "cai": "Central American Indian languages",
+  "car": "Galibi Carib",
+  "cat": "Catalan; Valencian",
+  "cau": "Caucasian languages",
+  "ceb": "Cebuano",
+  "cel": "Celtic languages",
+  "cha": "Chamorro",
+  "chb": "Chibcha",
+  "che": "Chechen",
+  "chg": "Chagatai",
+  "chi": "Chinese",
+  "chk": "Chuukese",
+  "chm": "Mari",
+  "chn": "Chinook jargon",
+  "cho": "Choctaw",
+  "chp": "Chipewyan; Dene Suline",
+  "chr": "Cherokee",
+  "chu": "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic",
+  "chv": "Chuvash",
+  "chy": "Cheyenne",
+  "cmc": "Chamic languages",
+  "cnr": "Montenegrin",
+  "cop": "Coptic",
+  "cor": "Cornish",
+  "cos": "Corsican",
+  "cpe": "Creoles and pidgins, English based",
+  "cpf": "Creoles and pidgins, French-based ",
+  "cpp": "Creoles and pidgins, Portuguese-based ",
+  "cre": "Cree",
+  "crh": "Crimean Tatar; Crimean Turkish",
+  "crp": "Creoles and pidgins ",
+  "csb": "Kashubian",
+  "cus": "Cushitic languages",
+  "cze": "Czech",
+  "dak": "Dakota",
+  "dan": "Danish",
+  "dar": "Dargwa",
+  "day": "Land Dayak languages",
+  "del": "Delaware",
+  "den": "Slave (Athapascan)",
+  "dgr": "Dogrib",
+  "din": "Dinka",
+  "div": "Divehi; Dhivehi; Maldivian",
+  "doi": "Dogri",
+  "dra": "Dravidian languages",
+  "dsb": "Lower Sorbian",
+  "dua": "Duala",
+  "dum": "Dutch, Middle (ca.1050-1350)",
+  "dut": "Dutch; Flemish",
+  "dyu": "Dyula",
+  "dzo": "Dzongkha",
+  "efi": "Efik",
+  "egy": "Egyptian (Ancient)",
+  "eka": "Ekajuk",
+  "elx": "Elamite",
+  "eng": "English",
+  "enm": "English, Middle (1100-1500)",
+  "epo": "Esperanto",
+  "est": "Estonian",
+  "ewe": "Ewe",
+  "ewo": "Ewondo",
+  "fan": "Fang",
+  "fao": "Faroese",
+  "fat": "Fanti",
+  "fij": "Fijian",
+  "fil": "Filipino; Pilipino",
+  "fin": "Finnish",
+  "fiu": "Finno-Ugrian languages",
+  "fon": "Fon",
+  "fre": "French",
+  "frm": "French, Middle (ca.1400-1600)",
+  "fro": "French, Old (842-ca.1400)",
+  "frr": "Northern Frisian",
+  "frs": "Eastern Frisian",
+  "fry": "Western Frisian",
+  "ful": "Fulah",
+  "fur": "Friulian",
+  "gaa": "Ga",
+  "gay": "Gayo",
+  "gba": "Gbaya",
+  "gem": "Germanic languages",
+  "geo": "Georgian",
+  "ger": "German",
+  "gez": "Geez",
+  "gil": "Gilbertese",
+  "gla": "Gaelic; Scottish Gaelic",
+  "gle": "Irish",
+  "glg": "Galician",
+  "glv": "Manx",
+  "gmh": "German, Middle High (ca.1050-1500)",
+  "goh": "German, Old High (ca.750-1050)",
+  "gon": "Gondi",
+  "gor": "Gorontalo",
+  "got": "Gothic",
+  "grb": "Grebo",
+  "grc": "Greek, Ancient (to 1453)",
+  "gre": "Greek, Modern (1453-)",
+  "grn": "Guarani",
+  "gsw": "Swiss German; Alemannic; Alsatian",
+  "guj": "Gujarati",
+  "gwi": "Gwich'in",
+  "hai": "Haida",
+  "hat": "Haitian; Haitian Creole",
+  "hau": "Hausa",
+  "haw": "Hawaiian",
+  "heb": "Hebrew",
+  "her": "Herero",
+  "hil": "Hiligaynon",
+  "him": "Himachali languages; Western Pahari languages",
+  "hin": "Hindi",
+  "hit": "Hittite",
+  "hmn": "Hmong; Mong",
+  "hmo": "Hiri Motu",
+  "hrv": "Croatian",
+  "hsb": "Upper Sorbian",
+  "hun": "Hungarian",
+  "hup": "Hupa",
+  "iba": "Iban",
+  "ibo": "Igbo",
+  "ice": "Icelandic",
+  "ido": "Ido",
+  "iii": "Sichuan Yi; Nuosu",
+  "ijo": "Ijo languages",
+  "iku": "Inuktitut",
+  "ile": "Interlingue; Occidental",
+  "ilo": "Iloko",
+  "ina": "Interlingua (International Auxiliary Language Association)",
+  "inc": "Indic languages",
+  "ind": "Indonesian",
+  "ine": "Indo-European languages",
+  "inh": "Ingush",
+  "ipk": "Inupiaq",
+  "ira": "Iranian languages",
+  "iro": "Iroquoian languages",
+  "ita": "Italian",
+  "jav": "Javanese",
+  "jbo": "Lojban",
+  "jpn": "Japanese",
+  "jpr": "Judeo-Persian",
+  "jrb": "Judeo-Arabic",
+  "kaa": "Kara-Kalpak",
+  "kab": "Kabyle",
+  "kac": "Kachin; Jingpho",
+  "kal": "Kalaallisut; Greenlandic",
+  "kam": "Kamba",
+  "kan": "Kannada",
+  "kar": "Karen languages",
+  "kas": "Kashmiri",
+  "kau": "Kanuri",
+  "kaw": "Kawi",
+  "kaz": "Kazakh",
+  "kbd": "Kabardian",
+  "kha": "Khasi",
+  "khi": "Khoisan languages",
+  "khm": "Central Khmer",
+  "kho": "Khotanese; Sakan",
+  "kik": "Kikuyu; Gikuyu",
+  "kin": "Kinyarwanda",
+  "kir": "Kirghiz; Kyrgyz",
+  "kmb": "Kimbundu",
+  "kok": "Konkani",
+  "kom": "Komi",
+  "kon": "Kongo",
+  "kor": "Korean",
+  "kos": "Kosraean",
+  "kpe": "Kpelle",
+  "krc": "Karachay-Balkar",
+  "krl": "Karelian",
+  "kro": "Kru languages",
+  "kru": "Kurukh",
+  "kua": "Kuanyama; Kwanyama",
+  "kum": "Kumyk",
+  "kur": "Kurdish",
+  "kut": "Kutenai",
+  "lad": "Ladino",
+  "lah": "Lahnda",
+  "lam": "Lamba",
+  "lao": "Lao",
+  "lat": "Latin",
+  "lav": "Latvian",
+  "lez": "Lezghian",
+  "lim": "Limburgan; Limburger; Limburgish",
+  "lin": "Lingala",
+  "lit": "Lithuanian",
+  "lol": "Mongo",
+  "loz": "Lozi",
+  "ltz": "Luxembourgish; Letzeburgesch",
+  "lua": "Luba-Lulua",
+  "lub": "Luba-Katanga",
+  "lug": "Ganda",
+  "lui": "Luiseno",
+  "lun": "Lunda",
+  "luo": "Luo (Kenya and Tanzania)",
+  "lus": "Lushai",
+  "mac": "Macedonian",
+  "mad": "Madurese",
+  "mag": "Magahi",
+  "mah": "Marshallese",
+  "mai": "Maithili",
+  "mak": "Makasar",
+  "mal": "Malayalam",
+  "man": "Mandingo",
+  "mao": "Maori",
+  "map": "Austronesian languages",
+  "mar": "Marathi",
+  "mas": "Masai",
+  "may": "Malay",
+  "mdf": "Moksha",
+  "mdr": "Mandar",
+  "men": "Mende",
+  "mga": "Irish, Middle (900-1200)",
+  "mic": "Mi'kmaq; Micmac",
+  "min": "Minangkabau",
+  "mis": "Uncoded languages",
+  "mkh": "Mon-Khmer languages",
+  "mlg": "Malagasy",
+  "mlt": "Maltese",
+  "mnc": "Manchu",
+  "mni": "Manipuri",
+  "mno": "Manobo languages",
+  "moh": "Mohawk",
+  "mon": "Mongolian",
+  "mos": "Mossi",
+  "mul": "Multiple languages",
+  "mun": "Munda languages",
+  "mus": "Creek",
+  "mwl": "Mirandese",
+  "mwr": "Marwari",
+  "myn": "Mayan languages",
+  "myv": "Erzya",
+  "nah": "Nahuatl languages",
+  "nai": "North American Indian languages",
+  "nap": "Neapolitan",
+  "nau": "Nauru",
+  "nav": "Navajo; Navaho",
+  "nbl": "Ndebele, South; South Ndebele",
+  "nde": "Ndebele, North; North Ndebele",
+  "ndo": "Ndonga",
+  "nds": "Low German; Low Saxon; German, Low; Saxon, Low",
+  "nep": "Nepali",
+  "new": "Nepal Bhasa; Newari",
+  "nia": "Nias",
+  "nic": "Niger-Kordofanian languages",
+  "niu": "Niuean",
+  "nno": "Norwegian Nynorsk; Nynorsk, Norwegian",
+  "nob": "Bokmål, Norwegian; Norwegian Bokmål",
+  "nog": "Nogai",
+  "non": "Norse, Old",
+  "nor": "Norwegian",
+  "nqo": "N'Ko",
+  "nso": "Pedi; Sepedi; Northern Sotho",
+  "nub": "Nubian languages",
+  "nwc": "Classical Newari; Old Newari; Classical Nepal Bhasa",
+  "nya": "Chichewa; Chewa; Nyanja",
+  "nym": "Nyamwezi",
+  "nyn": "Nyankole",
+  "nyo": "Nyoro",
+  "nzi": "Nzima",
+  "oci": "Occitan (post 1500); Provençal",
+  "oji": "Ojibwa",
+  "ori": "Oriya",
+  "orm": "Oromo",
+  "osa": "Osage",
+  "oss": "Ossetian; Ossetic",
+  "ota": "Turkish, Ottoman (1500-1928)",
+  "oto": "Otomian languages",
+  "paa": "Papuan languages",
+  "pag": "Pangasinan",
+  "pal": "Pahlavi",
+  "pam": "Pampanga; Kapampangan",
+  "pan": "Panjabi; Punjabi",
+  "pap": "Papiamento",
+  "pau": "Palauan",
+  "peo": "Persian, Old (ca.600-400 B.C.)",
+  "per": "Persian",
+  "phi": "Philippine languages",
+  "phn": "Phoenician",
+  "pli": "Pali",
+  "pol": "Polish",
+  "pon": "Pohnpeian",
+  "por": "Portuguese",
+  "pra": "Prakrit languages",
+  "pro": "Provençal, Old (to 1500)",
+  "pus": "Pushto; Pashto",
+  "qaa-qtz": "Reserved for local use",
+  "que": "Quechua",
+  "raj": "Rajasthani",
+  "rap": "Rapanui",
+  "rar": "Rarotongan; Cook Islands Maori",
+  "roa": "Romance languages",
+  "roh": "Romansh",
+  "rom": "Romany",
+  "rum": "Romanian; Moldavian; Moldovan",
+  "run": "Rundi",
+  "rup": "Aromanian; Arumanian; Macedo-Romanian",
+  "rus": "Russian",
+  "sad": "Sandawe",
+  "sag": "Sango",
+  "sah": "Yakut",
+  "sai": "South American Indian (Other)",
+  "sal": "Salishan languages",
+  "sam": "Samaritan Aramaic",
+  "san": "Sanskrit",
+  "sas": "Sasak",
+  "sat": "Santali",
+  "scn": "Sicilian",
+  "sco": "Scots",
+  "sel": "Selkup",
+  "sem": "Semitic languages",
+  "sga": "Irish, Old (to 900)",
+  "sgn": "Sign Languages",
+  "shn": "Shan",
+  "sid": "Sidamo",
+  "sin": "Sinhala; Sinhalese",
+  "sio": "Siouan languages",
+  "sit": "Sino-Tibetan languages",
+  "sla": "Slavic languages",
+  "slo": "Slovak",
+  "slv": "Slovenian",
+  "sma": "Southern Sami",
+  "sme": "Northern Sami",
+  "smi": "Sami languages",
+  "smj": "Lule Sami",
+  "smn": "Inari Sami",
+  "smo": "Samoan",
+  "sms": "Skolt Sami",
+  "sna": "Shona",
+  "snd": "Sindhi",
+  "snk": "Soninke",
+  "sog": "Sogdian",
+  "som": "Somali",
+  "son": "Songhai languages",
+  "sot": "Sotho, Southern",
+  "spa": "Spanish; Castilian",
+  "srd": "Sardinian",
+  "srn": "Sranan Tongo",
+  "srp": "Serbian",
+  "srr": "Serer",
+  "ssa": "Nilo-Saharan languages",
+  "ssw": "Swati",
+  "suk": "Sukuma",
+  "sun": "Sundanese",
+  "sus": "Susu",
+  "sux": "Sumerian",
+  "swa": "Swahili",
+  "swe": "Swedish",
+  "syc": "Classical Syriac",
+  "syr": "Syriac",
+  "tah": "Tahitian",
+  "tai": "Tai languages",
+  "tam": "Tamil",
+  "tat": "Tatar",
+  "tel": "Telugu",
+  "tem": "Timne",
+  "ter": "Tereno",
+  "tet": "Tetum",
+  "tgk": "Tajik",
+  "tgl": "Tagalog",
+  "tha": "Thai",
+  "tib": "Tibetan",
+  "tig": "Tigre",
+  "tir": "Tigrinya",
+  "tiv": "Tiv",
+  "tkl": "Tokelau",
+  "tlh": "Klingon; tlhIngan-Hol",
+  "tli": "Tlingit",
+  "tmh": "Tamashek",
+  "tog": "Tonga (Nyasa)",
+  "ton": "Tonga (Tonga Islands)",
+  "tpi": "Tok Pisin",
+  "tsi": "Tsimshian",
+  "tsn": "Tswana",
+  "tso": "Tsonga",
+  "tuk": "Turkmen",
+  "tum": "Tumbuka",
+  "tup": "Tupi languages",
+  "tur": "Turkish",
+  "tut": "Altaic languages",
+  "tvl": "Tuvalu",
+  "twi": "Twi",
+  "tyv": "Tuvinian",
+  "udm": "Udmurt",
+  "uga": "Ugaritic",
+  "uig": "Uighur; Uyghur",
+  "ukr": "Ukrainian",
+  "umb": "Umbundu",
+  "und": "Undetermined",
+  "urd": "Urdu",
+  "uzb": "Uzbek",
+  "vai": "Vai",
+  "ven": "Venda",
+  "vie": "Vietnamese",
+  "vol": "Volapük",
+  "vot": "Votic",
+  "wak": "Wakashan languages",
+  "wal": "Walamo",
+  "war": "Waray",
+  "was": "Washo",
+  "wel": "Welsh",
+  "wen": "Sorbian languages",
+  "wln": "Walloon",
+  "wol": "Wolof",
+  "xal": "Kalmyk; Oirat",
+  "xho": "Xhosa",
+  "yao": "Yao",
+  "yap": "Yapese",
+  "yid": "Yiddish",
+  "yor": "Yoruba",
+  "ypk": "Yupik languages",
+  "zap": "Zapotec",
+  "zbl": "Blissymbols; Blissymbolics; Bliss",
+  "zen": "Zenaga",
+  "zgh": "Standard Moroccan Tamazight",
+  "zha": "Zhuang; Chuang",
+  "znd": "Zande languages",
+  "zul": "Zulu",
+  "zun": "Zuni",
+  "zxx": "No linguistic content; Not applicable",
+  "zza": "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki"
+}
\ No newline at end of file
diff --git a/ety/language.py b/ety/language.py
index 8684453..e4b1f61 100644
--- a/ety/language.py
+++ b/ety/language.py
@@ -1,7 +1,7 @@
 #!/usr/local/bin/python
 # -*- coding: utf-8 -*-
 
-from .data import langs
+from .data import iso_639_3_codes, iso_639_2_codes
 
 
 class Language(object):
@@ -9,9 +9,12 @@ class Language(object):
         self.iso = iso
 
         try:
-            self.name = langs[iso]
+            self.name = iso_639_3_codes[iso]
         except KeyError:
-            raise KeyError("Language with iso code '%s' unknown" % iso)
+            try:
+                self.name = iso_639_2_codes[iso]
+            except KeyError:
+                raise KeyError("Language with iso code '%s' unknown" % iso)
 
     def __repr__(self):
         return u"Language(iso={})".format(self.iso)
diff --git a/setup.py b/setup.py
index 9001d4f..9d7d4a3 100644
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@ here = path.abspath(path.dirname(__file__))
 with open(path.join(here, "README.md"), encoding="utf-8") as f:
     long_description = f.read()
 
-with open(path.join(here, 'ety/__init__.py'), encoding='utf8') as f:
+with open(path.join(here, "ety/__init__.py"), encoding="utf8") as f:
     version = re.search(r'__version__ = "(.*?)"', f.read()).group(1)
 
 setup(
@@ -40,7 +40,9 @@ setup(
     packages=["ety", "ety/data"],
     install_requires=["treelib", "colorful", "six"],
     extras_require={"dev": ["flake8"]},
-    package_data={"ety": ["data/etymologies.json", "data/iso-639-3.json"]},
+    package_data={
+        "ety": ["data/etymologies.json", "data/iso-639-3.json", "data/iso-639-2.json"]
+    },
     entry_points={"console_scripts": ["ety=ety:cli"]},
     project_urls={
         "Source": "https://github.com/jmsv/ety-python",


Test patch:
diff --git a/tests.py b/tests.py
index c64f9e0..0d50743 100644
--- a/tests.py
+++ b/tests.py
@@ -116,6 +116,11 @@ class TestEty(unittest.TestCase):
     def test_tree_dict(self):
         self.assertIsInstance(ety.tree("potato").__dict__, dict)
 
+    def test_nah_lang_code(self):
+        tree = str(ety.tree("avocado"))
+        self.assertTrue(tree.startswith("avocado (English)\n└── aguacate (Spanish)"))
+        self.assertTrue("Nahuatl languages" in tree)
+
     @stdout_capture
     def test_cli_no_args(self, output):
         words = ["test"]