|
| 1 | +"""Country Codes.""" |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | + |
| 4 | +# local |
| 5 | +from validators.utils import validator |
| 6 | + |
| 7 | +# fmt: off |
| 8 | +alpha_2 = { |
| 9 | + "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", |
| 10 | + "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", |
| 11 | + "BT", "BV", "BW", "BY", "BZ", |
| 12 | + "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", |
| 13 | + "CX", "CY", "CZ", |
| 14 | + "DE", "DJ", "DK", "DM", "DO", "DZ", |
| 15 | + "EC", "EE", "EG", "EH", "ER", "ES", "ET", |
| 16 | + "FI", "FJ", "FK", "FM", "FO", "FR", |
| 17 | + "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", |
| 18 | + "GU", "GW", "GY", |
| 19 | + "HK", "HM", "HN", "HR", "HT", "HU", |
| 20 | + "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", |
| 21 | + "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", |
| 22 | + "KM", "KN", "KP", "KR", "KW", "KY", "KZ", |
| 23 | + "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", |
| 24 | + "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", |
| 25 | + "MT", "MU", "MV", "MW", "MX", "MY", "MZ", |
| 26 | + "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", |
| 27 | + "OM", |
| 28 | + "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", |
| 29 | + "QA", |
| 30 | + "RE", "RO", "RS", "RU", "RW", |
| 31 | + "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", |
| 32 | + "ST", "SV", "SX", "SY", "SZ", |
| 33 | + "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", |
| 34 | + "UA", "UG", "UM", "US", "UY", "UZ", |
| 35 | + "VC", "VE", "VG", "VI", "VN", "VU", |
| 36 | + "WF", "WS", |
| 37 | + "YE", "YT", |
| 38 | + "ZA", "ZM", "ZW", |
| 39 | +} |
| 40 | +alpha_3 = { |
| 41 | + "ABW", "AFG", "AGO", "AIA", "ALA", "ALB", "AND", "ARE", "ARG", "ARM", "ASM", "ATA", "ATF", |
| 42 | + "ATG", "AUS", "AUT", "AZE", |
| 43 | + "BDI", "BEL", "BEN", "BES", "BFA", "BGD", "BGR", "BHR", "BHS", "BIH", "BLM", "BLR", "BLZ", |
| 44 | + "BMU", "BOL", "BRA", "BRB", "BRN", "BTN", "BVT", "BWA", |
| 45 | + "CAF", "CAN", "CCK", "CHE", "CHL", "CHN", "CIV", "CMR", "COD", "COG", "COK", "COL", "COM", |
| 46 | + "CPV", "CRI", "CUB", "CUW", "CXR", "CYM", "CYP", "CZE", |
| 47 | + "DEU", "DJI", "DMA", "DNK", "DOM", "DZA", |
| 48 | + "ECU", "EGY", "ERI", "ESH", "ESP", "EST", "ETH", |
| 49 | + "FIN", "FJI", "FLK", "FRA", "FRO", "FSM", |
| 50 | + "GAB", "GBR", "GEO", "GGY", "GHA", "GIB", "GIN", "GLP", "GMB", "GNB", "GNQ", "GRC", "GRD", |
| 51 | + "GRL", "GTM", "GUF", "GUM", "GUY", |
| 52 | + "HKG", "HMD", "HND", "HRV", "HTI", "HUN", |
| 53 | + "IDN", "IMN", "IND", "IOT", "IRL", "IRN", "IRQ", "ISL", "ISR", "ITA", |
| 54 | + "JAM", "JEY", "JOR", "JPN", |
| 55 | + "KAZ", "KEN", "KGZ", "KHM", "KIR", "KNA", "KOR", "KWT", |
| 56 | + "LAO", "LBN", "LBR", "LBY", "LCA", "LIE", "LKA", "LSO", "LTU", "LUX", "LVA", |
| 57 | + "MAC", "MAF", "MAR", "MCO", "MDA", "MDG", "MDV", "MEX", "MHL", "MKD", "MLI", "MLT", "MMR", |
| 58 | + "MNE", "MNG", "MNP", "MOZ", "MRT", "MSR", "MTQ", "MUS", "MWI", "MYS", "MYT", |
| 59 | + "NAM", "NCL", "NER", "NFK", "NGA", "NIC", "NIU", "NLD", "NOR", "NPL", "NRU", "NZL", |
| 60 | + "OMN", |
| 61 | + "PAK", "PAN", "PCN", "PER", "PHL", "PLW", "PNG", "POL", "PRI", "PRK", "PRT", "PRY", "PSE", |
| 62 | + "PYF", |
| 63 | + "QAT", |
| 64 | + "REU", "ROU", "RUS", "RWA", |
| 65 | + "SAU", "SDN", "SEN", "SGP", "SGS", "SHN", "SJM", "SLB", "SLE", "SLV", "SMR", "SOM", "SPM", |
| 66 | + "SRB", "SSD", "STP", "SUR", "SVK", "SVN", "SWE", "SWZ", "SXM", "SYC", "SYR", |
| 67 | + "TCA", "TCD", "TGO", "THA", "TJK", "TKL", "TKM", "TLS", "TON", "TTO", "TUN", "TUR", "TUV", |
| 68 | + "TWN", "TZA", |
| 69 | + "UGA", "UKR", "UMI", "URY", "USA", "UZB", |
| 70 | + "VCT", "VEN", "VGB", "VIR", "VNM", "VUT", |
| 71 | + "WLF", "WSM", |
| 72 | + "YEM", |
| 73 | + "ZAF", "ZMB", "ZWE", |
| 74 | +} |
| 75 | +numeric = { |
| 76 | + "004", "008", "010", "012", "016", "020", "024", "028", "031", "032", |
| 77 | + "036", "040", "044", "048", "050", "051", "052", "056", "060", "064", |
| 78 | + "068", "070", "072", "074", "076", "084", "086", "090", "092", "096", |
| 79 | + "100", "104", "108", "112", "116", "120", "124", "132", "136", "140", |
| 80 | + "144", "148", "152", "156", "158", "162", "166", "170", "174", "175", |
| 81 | + "178", "180", "184", "188", "191", "192", "196", "203", "204", "208", |
| 82 | + "212", "214", "218", "222", "226", "231", "232", "233", "234", "238", |
| 83 | + "239", "242", "246", "248", "250", "254", "258", "260", "262", "266", |
| 84 | + "268", "270", "275", "276", "288", "292", "296", "300", "304", "308", |
| 85 | + "312", "316", "320", "324", "328", "332", "334", "340", "344", "348", |
| 86 | + "352", "356", "360", "364", "368", "372", "376", "380", "384", "388", |
| 87 | + "392", "398", "400", "404", "408", "410", "414", "417", "418", "422", |
| 88 | + "426", "428", "430", "434", "438", "440", "442", "446", "450", "454", |
| 89 | + "458", "462", "466", "470", "474", "478", "480", "484", "492", "496", |
| 90 | + "498", "499", "500", "504", "508", "512", "516", "520", "524", "528", |
| 91 | + "531", "533", "534", "535", "540", "548", "554", "558", "562", "566", |
| 92 | + "570", "574", "578", "580", "581", "583", "584", "585", "586", "591", |
| 93 | + "598", "600", "604", "608", "612", "616", "620", "624", "626", "630", |
| 94 | + "634", "638", "642", "643", "646", "652", "654", "659", "660", "662", |
| 95 | + "663", "666", "670", "674", "678", "682", "686", "688", "690", "694", |
| 96 | + "702", "703", "704", "705", "706", "710", "716", "724", "728", "729", |
| 97 | + "732", "740", "744", "748", "752", "756", "760", "762", "764", "768", |
| 98 | + "772", "776", "780", "784", "788", "792", "795", "796", "798", "800", |
| 99 | + "804", "807", "818", "826", "831", "832", "833", "834", "840", "850", |
| 100 | + "854", "858", "860", "862", "876", "882", "887", "894", |
| 101 | +} |
| 102 | +# fmt: on |
| 103 | + |
| 104 | + |
| 105 | +def get_code_type(format_type: str): |
| 106 | + """Returns the type of country code.""" |
| 107 | + if format_type.isdigit(): |
| 108 | + return "numeric" |
| 109 | + if format_type.isalpha(): |
| 110 | + if len(format_type) == 2: |
| 111 | + return "alpha2" |
| 112 | + if len(format_type) == 3: |
| 113 | + return "alpha3" |
| 114 | + return "invalid" |
| 115 | + |
| 116 | + |
| 117 | +@validator |
| 118 | +def country_code(value: str, /, *, iso_format: str = "auto"): |
| 119 | + """Validates given country code. |
| 120 | +
|
| 121 | + This performs a case-sensitive [ISO 3166][1] country code validation. |
| 122 | +
|
| 123 | + [1]: https://www.iso.org/iso-3166-country-codes.html |
| 124 | +
|
| 125 | + Examples: |
| 126 | + >>> country_code('GB', iso_format='alpha3') |
| 127 | + # Output: False |
| 128 | + >>> country_code('USA') |
| 129 | + # Output: True |
| 130 | + >>> country_code('840', iso_format='numeric') |
| 131 | + # Output: True |
| 132 | + >>> country_code('iN', iso_format='alpha2') |
| 133 | + # Output: False |
| 134 | + >>> country_code('ZWE', iso_format='alpha3') |
| 135 | + # Output: True |
| 136 | +
|
| 137 | + Args: |
| 138 | + value: |
| 139 | + Country code string to validate. |
| 140 | + iso_format: |
| 141 | + ISO format to be used. Available options are: |
| 142 | + `auto`, `alpha2`, `alpha3` and `numeric`. |
| 143 | +
|
| 144 | + Returns: |
| 145 | + (Literal[True]): |
| 146 | + If `value` is a valid country code. |
| 147 | + (ValidationError): |
| 148 | + If `value` is an invalid country code. |
| 149 | + """ |
| 150 | + if not value: |
| 151 | + return False |
| 152 | + |
| 153 | + if not (1 < len(value) < 4): |
| 154 | + return False |
| 155 | + |
| 156 | + if iso_format == "auto" and (iso_format := get_code_type(value)) == "invalid": |
| 157 | + return False |
| 158 | + |
| 159 | + if iso_format == "alpha2": |
| 160 | + return value in alpha_2 |
| 161 | + if iso_format == "alpha3": |
| 162 | + return value in alpha_3 |
| 163 | + return value in numeric if iso_format == "numeric" else False |
0 commit comments