import gettext import os.path import re from unittest.mock import patch import importlib_metadata import pytest import pycountry import pycountry.db @pytest.fixture(autouse=True, scope="session") def logging(): import logging logging.basicConfig(level=logging.DEBUG) def test_country_list(): assert len(pycountry.countries) == 249 assert isinstance(list(pycountry.countries)[0], pycountry.db.Data) def test_country_fuzzy_search(): results = pycountry.countries.search_fuzzy("England") assert len(results) == 1 assert results[0] == pycountry.countries.get(alpha_2="GB") # Match alternative names exactly and thus NL ends up with # "Sint Maarten" before SX with "Sint Maarten (Dutch part)" results = pycountry.countries.search_fuzzy("Sint Maarten") assert len(results) == 2 assert results[0] == pycountry.countries.get(alpha_2="NL") assert results[1] == pycountry.countries.get(alpha_2="SX") # Match with accents removed, first a country with a partial match in the # country name, then a country with multiple subdivision partial matches, # and then a country with a single subdivision match. results = pycountry.countries.search_fuzzy("Cote") assert len(results) == 3 assert results[0] == pycountry.countries.get(alpha_2="CI") assert results[1] == pycountry.countries.get(alpha_2="FR") assert results[2] == pycountry.countries.get(alpha_2="HN") # A somewhat carefully balanced point system allows for a (bias-based) # graceful sorting of common substrings being used in multiple matches: results = pycountry.countries.search_fuzzy("New") assert results[0] == pycountry.countries.get(alpha_2="NC") assert results[1] == pycountry.countries.get(alpha_2="NZ") assert results[2] == pycountry.countries.get(alpha_2="PG") assert results[3] == pycountry.countries.get(alpha_2="GB") assert results[4] == pycountry.countries.get(alpha_2="US") assert results[5] == pycountry.countries.get(alpha_2="CA") assert results[6] == pycountry.countries.get(alpha_2="AU") assert results[7] == pycountry.countries.get(alpha_2="BS") assert results[8] == pycountry.countries.get(alpha_2="TW") assert results[9] == pycountry.countries.get(alpha_2="MH") # bug #34, likely about capitalization that was broken results = pycountry.countries.search_fuzzy("united states of america") assert len(results) == 1 assert results[0] == pycountry.countries.get(alpha_2="US") def test_historic_country_fuzzy_search(): results = pycountry.historic_countries.search_fuzzy("burma") assert len(results) == 1 assert results[0] == pycountry.historic_countries.get(alpha_4="BUMM") def test_germany_has_all_attributes(): germany = pycountry.countries.get(alpha_2="DE") assert germany.alpha_2 == "DE" assert germany.alpha_3 == "DEU" assert germany.numeric == "276" assert germany.name == "Germany" assert germany.official_name == "Federal Republic of Germany" def test_missing_common_official_use_same(): aruba = pycountry.countries.get(alpha_2="AW") assert aruba.alpha_2 == "AW" assert aruba.name == "Aruba" assert aruba.official_name == "Aruba" assert aruba.common_name == "Aruba" def test_missing_common_official_use_different(): vietnam = pycountry.countries.get(alpha_2="VN") assert vietnam.alpha_2 == "VN" assert vietnam.name == "Viet Nam" assert vietnam.official_name == "Socialist Republic of Viet Nam" assert vietnam.common_name == "Vietnam" def test_country_missing_attribute(): germany = pycountry.countries.get(alpha_2="DE") with pytest.raises(AttributeError): _ = germany.foo def test_subdivisions_directly_accessible(): assert len(pycountry.subdivisions) == 5127 assert isinstance(list(pycountry.subdivisions)[0], pycountry.db.Data) de_st = pycountry.subdivisions.get(code="DE-ST") assert de_st.code == "DE-ST" assert de_st.name == "Sachsen-Anhalt" assert de_st.type == "Land" assert de_st.parent is None assert de_st.parent_code is None assert de_st.country is pycountry.countries.get(alpha_2="DE") def test_subdivisions_have_subdivision_as_parent(): fr_01 = pycountry.subdivisions.get(code="FR-01") assert fr_01.code == "FR-01" assert fr_01.name == "Ain" assert fr_01.type == "Metropolitan department" assert fr_01.parent_code == "FR-ARA" assert fr_01.parent is pycountry.subdivisions.get(code="FR-ARA") assert fr_01.parent.name == "Auvergne-Rhône-Alpes" def test_query_subdivisions_of_country(): assert len(pycountry.subdivisions.get(country_code="DE")) == 16 assert len(pycountry.subdivisions.get(country_code="US")) == 57 def test_scripts(): assert len(pycountry.scripts) == 182 assert isinstance(list(pycountry.scripts)[0], pycountry.db.Data) latin = pycountry.scripts.get(name="Latin") assert latin.alpha_4 == "Latn" assert latin.name == "Latin" assert latin.numeric == "215" def test_currencies(): assert len(pycountry.currencies) == 181 assert isinstance(list(pycountry.currencies)[0], pycountry.db.Data) argentine_peso = pycountry.currencies.get(alpha_3="ARS") assert argentine_peso.alpha_3 == "ARS" assert argentine_peso.name == "Argentine Peso" assert argentine_peso.numeric == "032" def test_languages(): assert len(pycountry.languages) == 7910 assert isinstance(list(pycountry.languages)[0], pycountry.db.Data) aragonese = pycountry.languages.get(alpha_2="an") assert aragonese.alpha_2 == "an" assert aragonese.alpha_3 == "arg" assert aragonese.name == "Aragonese" bengali = pycountry.languages.get(alpha_2="bn") assert bengali.name == "Bengali" assert bengali.common_name == "Bangla" # this tests the slow search path in lookup() bengali2 = pycountry.languages.lookup("bAngLa") assert bengali2 == bengali def test_language_families(): assert len(pycountry.language_families) == 115 assert isinstance(list(pycountry.language_families)[0], pycountry.db.Data) aragonese = pycountry.languages.get(alpha_3="arg") assert aragonese.alpha_3 == "arg" assert aragonese.name == "Aragonese" def test_locales(): german = gettext.translation( "iso3166-1", pycountry.LOCALES_DIR, languages=["de"] ) german.install() assert _("Germany") == "Deutschland" def test_removed_countries(): ussr = pycountry.historic_countries.get(alpha_3="SUN") assert isinstance(ussr, pycountry.db.Data) assert ussr.alpha_4 == "SUHH" assert ussr.alpha_3 == "SUN" assert ussr.name == "USSR, Union of Soviet Socialist Republics" assert ussr.withdrawal_date == "1992-08-30" def test_repr(): assert re.match( "Country\\(alpha_2=u?'DE', " "alpha_3=u?'DEU', " "flag='..', " "name=u?'Germany', " "numeric=u?'276', " "official_name=u?'Federal Republic of Germany'\\)", repr(pycountry.countries.get(alpha_2="DE")), ) def test_dict(): country = pycountry.countries.get(alpha_2="DE") exp = { "alpha_2": "DE", "alpha_3": "DEU", "name": "Germany", "numeric": "276", "official_name": "Federal Republic of Germany", "flag": country.flag, } assert dict(country) == exp def test_dir(): germany = pycountry.countries.get(alpha_2="DE") for n in "alpha_2", "alpha_3", "name", "numeric", "official_name": assert n in dir(germany) def test_get(): c = pycountry.countries with pytest.raises(TypeError): c.get(alpha_2="DE", alpha_3="DEU") assert c.get(alpha_2="DE") == c.get(alpha_3="DEU") assert c.get(alpha_2="Foo") is None tracer = object() assert c.get(alpha_2="Foo", default=tracer) is tracer def test_lookup(): c = pycountry.countries g = c.get(alpha_2="DE") assert g == c.get(alpha_2="de") assert g == c.lookup("de") assert g == c.lookup("DEU") assert g == c.lookup("276") assert g == c.lookup("germany") assert g == c.lookup("Federal Republic of Germany") # try a generated field bqaq = pycountry.historic_countries.get(alpha_4="BQAQ") assert bqaq == pycountry.historic_countries.lookup("atb") german = pycountry.languages.get(alpha_2="de") assert german == pycountry.languages.lookup("De") euro = pycountry.currencies.get(alpha_3="EUR") assert euro == pycountry.currencies.lookup("euro") latin = pycountry.scripts.get(name="Latin") assert latin == pycountry.scripts.lookup("latn") fr_ara = pycountry.subdivisions.get(code="FR-ARA") assert fr_ara == pycountry.subdivisions.lookup("fr-ara") with pytest.raises(LookupError): pycountry.countries.lookup("bogus country") with pytest.raises(LookupError): pycountry.countries.lookup(12345) with pytest.raises(LookupError): pycountry.countries.get(alpha_2=12345) def test_subdivision_parent(): s = pycountry.subdivisions sd = s.get(code="CV-BV") assert sd.parent_code == "CV-B" assert sd.parent is s.get(code=sd.parent_code) def test_subdivision_missing_code_raises_keyerror(): s = pycountry.subdivisions assert s.get(code="US-ZZ") is None def test_subdivision_empty_list(): s = pycountry.subdivisions assert len(s.get(country_code="DE")) == 16 assert len(s.get(country_code="JE")) == 0 assert s.get(country_code="FOOBAR") is None def test_has_version_attribute(): assert pycountry.__version__ != "n/a" assert len(pycountry.__version__) >= 5 assert "." in pycountry.__version__ def test_is_instance_of_language(): assert isinstance(pycountry.languages, pycountry.Languages) def test_is_instance_of_country(): united_states = pycountry.countries.get(alpha_2="US") class_name = united_states.__class__.__name__ assert class_name == "Country" def test_is_instance_of_subdivision(): assert isinstance(pycountry.subdivisions, pycountry.Subdivisions) def test_is_instance_of_script(): assert isinstance(pycountry.scripts, pycountry.Scripts) def test_is_instance_of_currency(): assert isinstance(pycountry.currencies, pycountry.Currencies) def test_add_entry(): pycountry.countries._clear() assert pycountry.countries.get(alpha_2="XK") is None pycountry.countries.add_entry( alpha_2="XK", alpha_3="XXK", name="Kosovo", numeric="926" ) country = pycountry.countries.get(alpha_2="XK") assert isinstance(country, pycountry.countries.data_class) def test_remove_entry(): pycountry.countries._clear() assert pycountry.countries.get(alpha_2="DE") is not None pycountry.countries.remove_entry(alpha_2="DE") assert pycountry.countries.get(alpha_2="DE") is None def test_no_results_lookup_error(): try: import importlib_resources # type: ignore except ModuleNotFoundError: from importlib import resources as importlib_resources def resource_filename(package_or_requirement, resource_name): return str( importlib_resources.files(package_or_requirement) / resource_name ) DATABASE_DIR = resource_filename("pycountry", "databases") countries = pycountry.ExistingCountries( os.path.join(DATABASE_DIR, "iso3166-1.json") ) query = "nonexistent query" with pytest.raises(LookupError): countries.search_fuzzy(query) def test_subdivision_fuzzy_search_match(): results = pycountry.subdivisions.search_fuzzy("Alabama") assert len(results) == 1 assert results[0].name == "Alabama" def test_subdivision_fuzzy_search_partial_match(): results = pycountry.subdivisions.search_fuzzy("Massachusett") assert len(results) == 1 assert results[0].name == "Massachusetts" def test_subdivision_match(): results = pycountry.subdivisions.match("Alabama") assert len(results) == 1 assert results[0].name == "Alabama" def test_subdivision_partial_match(): results = pycountry.subdivisions.partial_match("Massachusett") assert len(results) == 1 assert results[0].name == "Massachusetts" def non_country_attribute_error(self): with self.assertRaises(AttributeError): english = pycountry.languages.get(name="English") result = english.official_name def country_attribute_error(self): with self.assertRaises(AttributeError): canada = pycountry.countries.get(alpha_2="CA") result = canada.maple_syrup def test_with_accents(): assert pycountry.remove_accents("Café") == "Cafe" assert pycountry.remove_accents("résumé") == "resume" assert pycountry.remove_accents("naïve") == "naive" assert pycountry.remove_accents("São Paulo") == "Sao Paulo" def test_without_accents(): assert pycountry.remove_accents("apple") == "apple" assert pycountry.remove_accents("banana") == "banana" def test_empty_string(): assert pycountry.remove_accents("") == "" def test_special_characters(): assert pycountry.remove_accents("!@#$%^&*()") == "!@#$%^&*()" def test_unicode_characters(): assert pycountry.remove_accents("你好") == "你好" # Chinese characters assert pycountry.remove_accents("こんにちは") == "こんにちは" # Japanese characters def test_subdivision_search_fuzzy_non_existent_subdivision(): with pytest.raises(LookupError): pycountry.subdivisions.search_fuzzy("Non Existent Subdivision") def test_subdivision_partial_match_non(): result = pycountry.subdivisions.partial_match("Non Existent Subdivision") assert len(result) == 0 def test_subdivision_match_non(): result = pycountry.subdivisions.match("Non Existent Subdivision") assert len(result) == 0 def test_get_version_with_package_not_found(): # Mock importlib_metadata.version to raise PackageNotFoundError with patch( "importlib_metadata.version", side_effect=importlib_metadata.PackageNotFoundError, ): # Call get_version with a package name that doesn't exist result = pycountry.get_version("non_existent_package") # Assert that the result is 'n/a' assert result == "n/a" def test_all_subdivisions_have_name_attribute(): subdivisions = pycountry.subdivisions has_name_attr = [ hasattr(subdivision, "name") for subdivision in subdivisions ] all_have_name_attr = all(has_name_attr) assert all_have_name_attr def test_remove_countries(): # Test case 1: Removing an existing entry kw1 = {"name": "United States"} try: pycountry.countries.remove_entry(**kw1) except KeyError as e: assert False, f"Unexpected KeyError for 'United States': {e}" # Test case 2: Removing a non-existing entry kw2 = {"name": "Non Existent Country"} try: pycountry.countries.remove_entry(**kw2) except KeyError as e: assert "not found and cannot be removed" in str( e ) # Check the error message else: assert ( False ), "Expected KeyError for 'Non Existent Country', but no exception was raised"