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

43 statements  

1"""Country.""" 

2 

3# local 

4from validators.utils import validator 

5 

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 

226 

227 

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" 

238 

239 

240@validator 

241def calling_code(value: str, /): 

242 """Validates given calling code. 

243 

244 This performs country's calling code validation. 

245 

246 Examples: 

247 >>> calling_code('+91') 

248 True 

249 >>> calling_code('-31') 

250 ValidationError(func=calling_code, args={'value': '-31'}) 

251 

252 Args: 

253 value: 

254 Country's calling code string to validate. 

255 

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 

262 

263 return value in set(_calling_codes.values()) 

264 

265 

266@validator 

267def country_code(value: str, /, *, iso_format: str = "auto", ignore_case: bool = False): 

268 """Validates given country code. 

269 

270 This performs a case-sensitive [ISO 3166][1] country code validation. 

271 

272 [1]: https://www.iso.org/iso-3166-country-codes.html 

273 

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 

285 

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. 

294 

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 

301 

302 if not (1 < len(value) < 4): 

303 return False 

304 

305 if iso_format == "auto" and (iso_format := _get_code_type(value)) == "invalid": 

306 return False 

307 

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 

316 

317 return value in _numeric if iso_format == "numeric" else False 

318 

319 

320@validator 

321def currency(value: str, /, *, skip_symbols: bool = True, ignore_case: bool = False): 

322 """Validates given currency code. 

323 

324 This performs [ISO 4217][1] currency code/symbol validation. 

325 

326 [1]: https://www.iso.org/iso-4217-currency-codes.html 

327 

328 Examples: 

329 >>> currency('USD') 

330 True 

331 >>> currency('ZWX') 

332 ValidationError(func=currency, args={'value': 'ZWX'}) 

333 

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. 

341 

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 

348 

349 if not skip_symbols and value in _currency_symbols: 

350 return True 

351 

352 if len(value) != 3: 

353 return False 

354 

355 return value.upper() in _currency_iso4217 if ignore_case else value in _currency_iso4217