Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/validators/i18n/es.py: 28%

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

40 statements  

1"""Spain.""" 

2 

3# standard 

4from typing import Dict, Set 

5 

6# local 

7from validators.utils import validator 

8 

9 

10def _nif_nie_validation(value: str, number_by_letter: Dict[str, str], special_cases: Set[str]): 

11 """Validate if the doi is a NIF or a NIE.""" 

12 if value in special_cases or len(value) != 9: 

13 return False 

14 value = value.upper() 

15 table = "TRWAGMYFPDXBNJZSQVHLCKE" 

16 # If it is not a DNI, convert the first 

17 # letter to the corresponding digit 

18 numbers = number_by_letter.get(value[0], value[0]) + value[1:8] 

19 # doi[8] is control 

20 return numbers.isdigit() and value[8] == table[int(numbers) % 23] 

21 

22 

23@validator 

24def es_cif(value: str, /): 

25 """Validate a Spanish CIF. 

26 

27 Each company in Spain prior to 2008 had a distinct CIF and has been 

28 discontinued. For more information see [wikipedia.org/cif][1]. 

29 

30 The new replacement is to use NIF for absolutely everything. The issue is 

31 that there are "types" of NIFs now: company, person [citizen or resident] 

32 all distinguished by the first character of the DOI. For this reason we 

33 will continue to call CIFs NIFs, that are used for companies. 

34 

35 This validator is based on [generadordni.es][2]. 

36 

37 [1]: https://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal 

38 [2]: https://generadordni.es/ 

39 

40 Examples: 

41 >>> es_cif('B25162520') 

42 # Output: True 

43 >>> es_cif('B25162529') 

44 # Output: ValidationError(func=es_cif, args=...) 

45 

46 Args: 

47 value: 

48 DOI string which is to be validated. 

49 

50 Returns: 

51 (Literal[True]): If `value` is a valid DOI string. 

52 (ValidationError): If `value` is an invalid DOI string. 

53 """ 

54 if not value or len(value) != 9: 

55 return False 

56 value = value.upper() 

57 table = "JABCDEFGHI" 

58 first_chr = value[0] 

59 doi_body = value[1:8] 

60 control = value[8] 

61 if not doi_body.isdigit(): 

62 return False 

63 res = ( 

64 10 

65 - sum( 

66 # Multiply each positionally even doi 

67 # digit by 2 and sum it all together 

68 sum(map(int, str(int(char) * 2))) if index % 2 == 0 else int(char) 

69 for index, char in enumerate(doi_body) 

70 ) 

71 % 10 

72 ) % 10 

73 if first_chr in "ABEH": # Number type 

74 return str(res) == control 

75 if first_chr in "PSQW": # Letter type 

76 return table[res] == control 

77 return control in {str(res), table[res]} if first_chr in "CDFGJNRUV" else False 

78 

79 

80@validator 

81def es_nif(value: str, /): 

82 """Validate a Spanish NIF. 

83 

84 Each entity, be it person or company in Spain has a distinct NIF. Since 

85 we've designated CIF to be a company NIF, this NIF is only for person. 

86 For more information see [wikipedia.org/nif][1]. This validator 

87 is based on [generadordni.es][2]. 

88 

89 [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identificaci%C3%B3n_fiscal 

90 [2]: https://generadordni.es/ 

91 

92 Examples: 

93 >>> es_nif('26643189N') 

94 # Output: True 

95 >>> es_nif('26643189X') 

96 # Output: ValidationError(func=es_nif, args=...) 

97 

98 Args: 

99 value: 

100 DOI string which is to be validated. 

101 

102 Returns: 

103 (Literal[True]): If `value` is a valid DOI string. 

104 (ValidationError): If `value` is an invalid DOI string. 

105 """ 

106 number_by_letter = {"L": "0", "M": "0", "K": "0"} 

107 special_cases = {"X0000000T", "00000000T", "00000001R"} 

108 return _nif_nie_validation(value, number_by_letter, special_cases) 

109 

110 

111@validator 

112def es_nie(value: str, /): 

113 """Validate a Spanish NIE. 

114 

115 The NIE is a tax identification number in Spain, known in Spanish 

116 as the NIE, or more formally the Número de identidad de extranjero. 

117 For more information see [wikipedia.org/nie][1]. This validator 

118 is based on [generadordni.es][2]. 

119 

120 [1]: https://es.wikipedia.org/wiki/N%C3%BAmero_de_identidad_de_extranjero 

121 [2]: https://generadordni.es/ 

122 

123 Examples: 

124 >>> es_nie('X0095892M') 

125 # Output: True 

126 >>> es_nie('X0095892X') 

127 # Output: ValidationError(func=es_nie, args=...) 

128 

129 Args: 

130 value: 

131 DOI string which is to be validated. 

132 

133 Returns: 

134 (Literal[True]): If `value` is a valid DOI string. 

135 (ValidationError): If `value` is an invalid DOI string. 

136 """ 

137 number_by_letter = {"X": "0", "Y": "1", "Z": "2"} 

138 # NIE must must start with X Y or Z 

139 if value and value[0] in number_by_letter: 

140 return _nif_nie_validation(value, number_by_letter, {"X0000000T"}) 

141 return False 

142 

143 

144@validator 

145def es_doi(value: str, /): 

146 """Validate a Spanish DOI. 

147 

148 A DOI in spain is all NIF / CIF / NIE / DNI -- a digital ID. 

149 For more information see [wikipedia.org/doi][1]. This validator 

150 is based on [generadordni.es][2]. 

151 

152 [1]: https://es.wikipedia.org/wiki/Identificador_de_objeto_digital 

153 [2]: https://generadordni.es/ 

154 

155 Examples: 

156 >>> es_doi('X0095892M') 

157 # Output: True 

158 >>> es_doi('X0095892X') 

159 # Output: ValidationError(func=es_doi, args=...) 

160 

161 Args: 

162 value: 

163 DOI string which is to be validated. 

164 

165 Returns: 

166 (Literal[True]): If `value` is a valid DOI string. 

167 (ValidationError): If `value` is an invalid DOI string. 

168 """ 

169 return es_nie(value) or es_nif(value) or es_cif(value)