Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/validators/country.py: 33%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Country."""
3# local
4from validators.utils import validator
6# fmt: off
7_alpha3_to_alpha2 = {
8 # A
9 "ABW": "AW", "AFG": "AF", "AGO": "AO", "AIA": "AI", "ALB": "AL", "AND": "AD", "ANT": "AN",
10 "ARE": "AE", "ARG": "AR", "ARM": "AM", "ASM": "AS", "ATA": "AQ", "ATF": "TF", "ATG": "AG",
11 "AUS": "AU", "AUT": "AT", "AZE": "AZ",
12 # B
13 "BDI": "BI", "BEL": "BE", "BEN": "BJ", "BFA": "BF", "BGD": "BD", "BGR": "BG", "BHR": "BH",
14 "BHS": "BS", "BIH": "BA", "BLR": "BY", "BLZ": "BZ", "BMU": "BM", "BOL": "BO", "BRA": "BR",
15 "BRB": "BB", "BRN": "BN", "BTN": "BT", "BVT": "BV", "BWA": "BW",
16 # C
17 "CAF": "CF", "CAN": "CA", "CCK": "CC", "CHE": "CH", "CHL": "CL", "CHN": "CN", "CMR": "CM",
18 "COD": "CD", "COG": "CG", "COK": "CK", "COL": "CO", "COM": "KM", "CPV": "CV", "CRI": "CR",
19 "CUB": "CU", "CXR": "CX", "CYM": "KY", "CYP": "CY", "CZE": "CZ",
20 # D
21 "DEU": "DE", "DJI": "DJ", "DMA": "DM", "DNK": "DK", "DOM": "DO", "DZA": "DZ",
22 # E
23 "ECU": "EC", "EGY": "EG", "ERI": "ER", "ESH": "EH", "ESP": "ES", "EST": "EE", "ETH": "ET",
24 # F
25 "FIN": "FI", "FJI": "FJ", "FLK": "FK", "FRA": "FR", "FRO": "FO", "FSM": "FM",
26 # G
27 "GAB": "GA", "GBR": "GB", "GEO": "GE", "GGY": "GG", "GHA": "GH", "GIB": "GI", "GIN": "GN",
28 "GLP": "GP", "GMB": "GM", "GNB": "GW", "GNQ": "GQ", "GRC": "GR", "GRD": "GD", "GRL": "GL",
29 "GTM": "GT", "GUF": "GF", "GUM": "GU", "GUY": "GY",
30 # H
31 "HKG": "HK", "HMD": "HM", "HND": "HN", "HRV": "HR", "HTI": "HT", "HUN": "HU",
32 # I
33 "IDN": "ID", "IMN": "IM", "IND": "IN", "IOT": "IO", "IRL": "IE", "IRN": "IR", "IRQ": "IQ",
34 "ISL": "IS", "ISR": "IL", "ITA": "IT",
35 # J
36 "JAM": "JM", "JEY": "JE", "JOR": "JO", "JPN": "JP",
37 # K
38 "KAZ": "KZ", "KEN": "KE", "KGZ": "KG", "KHM": "KH", "KIR": "KI", "KNA": "KN", "KOR": "KR",
39 "KWT": "KW",
40 # L
41 "LAO": "LA", "LBN": "LB", "LBR": "LR", "LBY": "LY", "LCA": "LC", "LIE": "LI", "LKA": "LK",
42 "LSO": "LS", "LTU": "LT", "LUX": "LU", "LVA": "LV",
43 # M
44 "MAC": "MO", "MAR": "MA", "MCO": "MC", "MDA": "MD", "MDG": "MG", "MDV": "MV", "MEX": "MX",
45 "MHL": "MH", "MKD": "MK", "MLI": "ML", "MLT": "MT", "MMR": "MM", "MNE": "ME", "MNG": "MN",
46 "MNP": "MP", "MOZ": "MZ", "MRT": "MR", "MSR": "MS", "MTQ": "MQ", "MUS": "MU", "MWI": "MW",
47 "MYS": "MY", "MYT": "YT",
48 # N
49 "NAM": "NA", "NCL": "NC", "NER": "NE", "NFK": "NF", "NGA": "NG", "NIC": "NI", "NIU": "NU",
50 "NLD": "NL", "NOR": "NO", "NPL": "NP", "NRU": "NR", "NZL": "NZ",
51 # O
52 "OMN": "OM",
53 # P
54 "PAK": "PK", "PAN": "PA", "PCN": "PN", "PER": "PE", "PHL": "PH", "PLW": "PW", "PNG": "PG",
55 "POL": "PL", "PRI": "PR", "PRK": "KP", "PRT": "PT", "PRY": "PY", "PSE": "PS", "PYF": "PF",
56 # Q
57 "QAT": "QA",
58 # R
59 "REU": "RE", "ROU": "RO", "RUS": "RU", "RWA": "RW",
60 # S
61 "SAU": "SA", "SDN": "SD", "SEN": "SN", "SGP": "SG", "SGS": "GS", "SHN": "SH", "SJM": "SJ",
62 "SLB": "SB", "SLE": "SL", "SLV": "SV", "SMR": "SM", "SOM": "SO", "SPM": "PM", "SRB": "RS",
63 "STP": "ST", "SUR": "SR", "SVK": "SK", "SVN": "SI", "SWE": "SE", "SWZ": "SZ", "SYC": "SC",
64 "SYR": "SY",
65 # T
66 "TCA": "TC", "TCD": "TD", "TGO": "TG", "THA": "TH", "TJK": "TJ", "TKL": "TK", "TKM": "TM",
67 "TLS": "TL", "TON": "TO", "TTO": "TT", "TUN": "TN", "TUR": "TR", "TUV": "TV", "TWN": "TW",
68 "TZA": "TZ",
69 # U
70 "UGA": "UG", "UKR": "UA", "UMI": "UM", "URY": "UY", "USA": "US", "UZB": "UZ",
71 # V
72 "VAT": "VA", "VCT": "VC", "VEN": "VE", "VGB": "VG", "VIR": "VI", "VNM": "VN", "VUT": "VU",
73 # W
74 "WLF": "WF", "WSM": "WS",
75 # Y
76 "YEM": "YE",
77 # Z
78 "ZAF": "ZA", "ZMB": "ZM", "ZWE": "ZW",
79}
80_calling_codes = {
81 # A
82 "ABW": "+297", "AFG": "+93", "AGO": "+244", "AIA": "+1-264", "ALB": "+355", "AND": "+376",
83 "ANT": "+599", "ARE": "+971", "ARG": "+54", "ARM": "+374", "ASM": "+1-684", "ATA": "+672",
84 "ATG": "+1-268", "AUS": "+61", "AUT": "+43", "AZE": "+994",
85 # B
86 "BDI": "+257", "BEL": "+32", "BEN": "+229", "BFA": "+226", "BGD": "+880", "BGR": "+359",
87 "BHR": "+973", "BHS": "+1-242", "BIH": "+387", "BLR": "+375", "BLZ": "+501",
88 "BMU": "+1-441", "BOL": "+591", "BRA": "+55", "BRB": "+1-246", "BRN": "+673", "BTN": "+975",
89 "BWA": "+267",
90 # C
91 "CAF": "+236", "CAN": "+1", "CCK": "+61", "CHE": "+41", "CHL": "+56", "CHN": "+86",
92 "CMR": "+237", "COD": "+243", "COG": "+242", "COK": "+682", "COL": "+57", "COM": "+269",
93 "CPV": "+238", "CRI": "+506", "CUB": "+53", "CXR": "+61", "CYM": "+1-345", "CYP": "+357",
94 "CZE": "+420",
95 # D
96 "DEU": "+49", "DJI": "+253", "DMA": "+1-767", "DNK": "+45", "DOM": "+1-809", "DZA": "+213",
97 # E
98 "ECU": "+593", "EGY": "+20", "ERI": "+291", "ESH": "+212", "ESP": "+34", "EST": "+372",
99 "ETH": "+251",
100 # F
101 "FIN": "+358", "FJI": "+679", "FLK": "+500", "FRA": "+33", "FRO": "+298", "FSM": "+691",
102 # G
103 "GAB": "+241", "GBR": "+44", "GEO": "+995", "GGY": "+44-1481", "GHA": "+233", "GIB": "+350",
104 "GIN": "+224", "GLP": "+590", "GMB": "+220", "GNB": "+245", "GNQ": "+240", "GRC": "+30",
105 "GRD": "+1-473", "GRL": "+299", "GTM": "+502", "GUF": "+594", "GUM": "+1-671",
106 "GUY": "+592",
107 # H
108 "HKG": "+852", "HMD": "+672", "HND": "+504", "HRV": "+385", "HTI": "+509", "HUN": "+36",
109 # I
110 "IDN": "+62", "IMN": "+44-1624", "IND": "+91", "IOT": "+246", "IRL": "+353", "IRN": "+98",
111 "IRQ": "+964", "ISL": "+354", "ISR": "+972", "ITA": "+39",
112 # J
113 "JAM": "+1-876", "JEY": "+44-1534", "JOR": "+962", "JPN": "+81",
114 # K
115 "KAZ": "+7", "KEN": "+254", "KGZ": "+996", "KHM": "+855", "KIR": "+686", "KNA": "+1-869",
116 "KOR": "+82", "KWT": "+965",
117 # L
118 "LAO": "+856", "LBN": "+961", "LBR": "+231", "LBY": "+218", "LCA": "+1-758", "LIE": "+423",
119 "LKA": "+94", "LSO": "+266", "LTU": "+370", "LUX": "+352", "LVA": "+371",
120 # M
121 "MAC": "+853", "MAR": "+212", "MCO": "+377", "MDA": "+373", "MDG": "+261", "MDV": "+960",
122 "MEX": "+52", "MHL": "+692", "MKD": "+389", "MLI": "+223", "MLT": "+356", "MMR": "+95",
123 "MNE": "+382", "MNG": "+976", "MNP": "+1-670", "MOZ": "+258", "MRT": "+222",
124 "MSR": "+1-664", "MTQ": "+596", "MUS": "+230", "MWI": "+265", "MYS": "+60", "MYT": "+262",
125 # N
126 "NAM": "+264", "NCL": "+687", "NER": "+227", "NFK": "+672", "NGA": "+234", "NIC": "+505",
127 "NIU": "+683", "NLD": "+31", "NOR": "+47", "NPL": "+977", "NRU": "+674", "NZL": "+64",
128 # O
129 "OMN": "+968",
130 # P
131 "PAK": "+92", "PAN": "+507", "PCN": "+64", "PER": "+51", "PHL": "+63", "PLW": "+680",
132 "PNG": "+675", "POL": "+48", "PRI": "+1-787", "PRK": "+850", "PRT": "+351", "PRY": "+595",
133 "PSE": "+970", "PYF": "+689",
134 # Q
135 "QAT": "+974",
136 # R
137 "REU": "+262", "ROU": "+40", "RUS": "+7", "RWA": "+250",
138 # S
139 "SAU": "+966", "SDN": "+249", "SEN": "+221", "SGP": "+65", "SHN": "+290", "SJM": "+47",
140 "SLB": "+677", "SLE": "+232", "SLV": "+503", "SMR": "+378", "SOM": "+252", "SPM": "+508",
141 "SRB": "+381", "STP": "+239", "SUR": "+597", "SVK": "+421", "SVN": "+386", "SWE": "+46",
142 "SWZ": "+268", "SYC": "+248", "SYR": "+963",
143 # T
144 "TCA": "+1-649", "TCD": "+235", "TGO": "+228", "THA": "+66", "TJK": "+992", "TKL": "+690",
145 "TKM": "+993", "TLS": "+670", "TON": "+676", "TTO": "+1-868", "TUN": "+216", "TUR": "+90",
146 "TUV": "+688", "TWN": "+886", "TZA": "+255",
147 # U
148 "UGA": "+256", "UKR": "+380", "UMI": "+1", "URY": "+598", "USA": "+1", "UZB": "+998",
149 # V
150 "VAT": "+379", "VCT": "+1-784", "VEN": "+58", "VGB": "+1-284", "VIR": "+1-340",
151 "VNM": "+84", "VUT": "+678",
152 # W
153 "WLF": "+681", "WSM": "+685",
154 # Y
155 "YEM": "+967",
156 # Z
157 "ZAF": "+27", "ZMB": "+260", "ZWE": "+263"
158}
159_numeric = {
160 "004", "008", "010", "012", "016", "020", "024", "028", "031", "032",
161 "036", "040", "044", "048", "050", "051", "052", "056", "060", "064",
162 "068", "070", "072", "074", "076", "084", "086", "090", "092", "096",
163 "100", "104", "108", "112", "116", "120", "124", "132", "136", "140",
164 "144", "148", "152", "156", "158", "162", "166", "170", "174", "175",
165 "178", "180", "184", "188", "191", "192", "196", "203", "204", "208",
166 "212", "214", "218", "222", "226", "231", "232", "233", "234", "238",
167 "239", "242", "246", "248", "250", "254", "258", "260", "262", "266",
168 "268", "270", "275", "276", "288", "292", "296", "300", "304", "308",
169 "312", "316", "320", "324", "328", "332", "334", "340", "344", "348",
170 "352", "356", "360", "364", "368", "372", "376", "380", "384", "388",
171 "392", "398", "400", "404", "408", "410", "414", "417", "418", "422",
172 "426", "428", "430", "434", "438", "440", "442", "446", "450", "454",
173 "458", "462", "466", "470", "474", "478", "480", "484", "492", "496",
174 "498", "499", "500", "504", "508", "512", "516", "520", "524", "528",
175 "531", "533", "534", "535", "540", "548", "554", "558", "562", "566",
176 "570", "574", "578", "580", "581", "583", "584", "585", "586", "591",
177 "598", "600", "604", "608", "612", "616", "620", "624", "626", "630",
178 "634", "638", "642", "643", "646", "652", "654", "659", "660", "662",
179 "663", "666", "670", "674", "678", "682", "686", "688", "690", "694",
180 "702", "703", "704", "705", "706", "710", "716", "724", "728", "729",
181 "732", "740", "744", "748", "752", "756", "760", "762", "764", "768",
182 "772", "776", "780", "784", "788", "792", "795", "796", "798", "800",
183 "804", "807", "818", "826", "831", "832", "833", "834", "840", "850",
184 "854", "858", "860", "862", "876", "882", "887", "894",
185}
186_currency_iso4217 = {
187 # https://en.wikipedia.org/wiki/ISO_4217
188 "AED", "AFN", "ALL", "AMD", "ANG", "AOA", "ARS", "AUD", "AWG", "AZN",
189 "BAM", "BBD", "BDT", "BGN", "BHD", "BIF", "BMD", "BND", "BOB", "BOV", "BRL", "BSD", "BTN",
190 "BWP", "BYN", "BZD",
191 "CAD", "CDF", "CHE", "CHF", "CHW", "CKD", "CLF", "CLP", "CNY", "COP", "CRC", "CUC", "CUP",
192 "CVE", "CZK",
193 "DJF", "DKK", "DOP", "DZD",
194 "EGP", "ERN", "ETB", "EUR",
195 "FJD", "FKP",
196 "GBP", "GEL", "GHS", "GIP", "GMD", "GNF", "GTQ", "GYD",
197 "HKD", "HNL", "HRK", "HTG", "HUF",
198 "IDR", "IEP", "ILS", "INR", "IQD", "IRR", "ISK",
199 "JMD", "JOD", "JPY",
200 "KES", "KGS", "KHR", "KID", "KMF", "KPW", "KRW", "KWD", "KYD", "KZT",
201 "LAK", "LBP", "LKR", "LRD", "LSL", "LYD",
202 "MAD", "MDL", "MGA", "MKD", "MMK", "MNT", "MOP", "MRU", "MUR", "MVR",
203 "MWK", "MXN", "MYR", "MZN",
204 "NAD", "NGN", "NIO", "NOK", "NPR", "NZD",
205 "OMR",
206 "PAB", "PEN", "PGK", "PHP", "PKR", "PLN", "PYG",
207 "QAR",
208 "RON", "RSD", "RUB", "RWF",
209 "SAR", "SBD", "SCR", "SDG", "SEK", "SGD", "SHP", "SLL", "SOS",
210 "SRD", "SSP", "STN", "SVC", "SYP", "SZL",
211 "THB", "TJS", "TMT", "TND", "TOP", "TRY", "TTD", "TWD", "TZS",
212 "UAH", "UGX", "USD", "UYU", "UZS",
213 "VED", "VES", "VND", "VUV",
214 "WST",
215 "XAF", "XCD", "XDR", "XOF", "XPF",
216 "YER",
217 "ZAR", "ZMW", "ZWL"
218}
219_currency_symbols = {
220 # https://en.wikipedia.org/wiki/Currency_sign_(generic)
221 "؋", "฿", "₵", "₡", "¢", "$", "₫", "֏", "€", "ƒ", "₣", "₲", "₴", "₭", "₾", "£", "₺", "₼", "₦",
222 "₱", "元", "圆", "圓", "﷼", "៛", "₽", "₹", "रू", "රු", "૱", "௹", "꠸", "Rs", "₪", "⃀" "৳", "₸",
223 "₮", "₩", "¥", "円", "₿", "¤"
224}
225# fmt: on
228def _get_code_type(format_type: str):
229 """Returns the type of country code."""
230 if format_type.isdecimal():
231 return "numeric"
232 if format_type.isalpha():
233 if len(format_type) == 2:
234 return "alpha2"
235 if len(format_type) == 3:
236 return "alpha3"
237 return "invalid"
240@validator
241def calling_code(value: str, /):
242 """Validates given calling code.
244 This performs country's calling code validation.
246 Examples:
247 >>> calling_code('+91')
248 True
249 >>> calling_code('-31')
250 ValidationError(func=calling_code, args={'value': '-31'})
252 Args:
253 value:
254 Country's calling code string to validate.
256 Returns:
257 (Literal[True]): If `value` is a valid calling code.
258 (ValidationError): If `value` is an invalid calling code.
259 """
260 if not value:
261 return False
263 return value in set(_calling_codes.values())
266@validator
267def country_code(value: str, /, *, iso_format: str = "auto", ignore_case: bool = False):
268 """Validates given country code.
270 This performs a case-sensitive [ISO 3166][1] country code validation.
272 [1]: https://www.iso.org/iso-3166-country-codes.html
274 Examples:
275 >>> country_code('GB', iso_format='alpha3')
276 ValidationError(func=country_code, args={'value': 'GB', 'iso_format': 'alpha3'})
277 >>> country_code('USA')
278 True
279 >>> country_code('840', iso_format='numeric')
280 True
281 >>> country_code('iN', iso_format='alpha2')
282 ValidationError(func=country_code, args={'value': 'iN', 'iso_format': 'alpha2'})
283 >>> country_code('ZWE', iso_format='alpha3')
284 True
286 Args:
287 value:
288 Country code string to validate.
289 iso_format:
290 ISO format to be used. Available options are:
291 `auto`, `alpha2`, `alpha3` and `numeric`.
292 ignore_case:
293 Enable/Disable case-sensitive matching.
295 Returns:
296 (Literal[True]): If `value` is a valid country code.
297 (ValidationError): If `value` is an invalid country code.
298 """
299 if not value:
300 return False
302 if not (1 < len(value) < 4):
303 return False
305 if iso_format == "auto" and (iso_format := _get_code_type(value)) == "invalid":
306 return False
308 if iso_format == "alpha2":
309 return (
310 value.upper() in set(_alpha3_to_alpha2.values())
311 if ignore_case
312 else value in set(_alpha3_to_alpha2.values())
313 )
314 if iso_format == "alpha3":
315 return value.upper() in _alpha3_to_alpha2 if ignore_case else value in _alpha3_to_alpha2
317 return value in _numeric if iso_format == "numeric" else False
320@validator
321def currency(value: str, /, *, skip_symbols: bool = True, ignore_case: bool = False):
322 """Validates given currency code.
324 This performs [ISO 4217][1] currency code/symbol validation.
326 [1]: https://www.iso.org/iso-4217-currency-codes.html
328 Examples:
329 >>> currency('USD')
330 True
331 >>> currency('ZWX')
332 ValidationError(func=currency, args={'value': 'ZWX'})
334 Args:
335 value:
336 Currency code/symbol string to validate.
337 skip_symbols:
338 Skip currency symbol validation.
339 ignore_case:
340 Enable/Disable case-sensitive matching.
342 Returns:
343 (Literal[True]): If `value` is a valid currency code.
344 (ValidationError): If `value` is an invalid currency code.
345 """
346 if not value:
347 return False
349 if not skip_symbols and value in _currency_symbols:
350 return True
352 if len(value) != 3:
353 return False
355 return value.upper() in _currency_iso4217 if ignore_case else value in _currency_iso4217