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

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

30 statements  

1"""Finland.""" 

2 

3# standard 

4from functools import lru_cache 

5import re 

6 

7# local 

8from validators.utils import validator 

9 

10 

11@lru_cache 

12def _business_id_pattern(): 

13 """Business ID Pattern.""" 

14 return re.compile(r"^[0-9]{7}-[0-9]$") 

15 

16 

17@lru_cache 

18def _ssn_pattern(ssn_check_marks: str): 

19 """SSN Pattern.""" 

20 return re.compile( 

21 r"""^ 

22 (?P<date>(0[1-9]|[1-2]\d|3[01]) 

23 (0[1-9]|1[012]) 

24 (\d{{2}})) 

25 [ABCDEFYXWVU+-] 

26 (?P<serial>(\d{{3}})) 

27 (?P<checksum>[{check_marks}])$""".format( 

28 check_marks=ssn_check_marks 

29 ), 

30 re.VERBOSE, 

31 ) 

32 

33 

34@validator 

35def fi_business_id(value: str, /): 

36 """Validate a Finnish Business ID. 

37 

38 Each company in Finland has a distinct business id. For more 

39 information see [Finnish Trade Register][1] 

40 

41 [1]: http://en.wikipedia.org/wiki/Finnish_Trade_Register 

42 

43 Examples: 

44 >>> fi_business_id('0112038-9') # Fast Monkeys Ltd 

45 # Output: True 

46 >>> fi_business_id('1234567-8') # Bogus ID 

47 # Output: ValidationError(func=fi_business_id, ...) 

48 

49 Args: 

50 value: 

51 Business ID string to be validated. 

52 

53 Returns: 

54 (Literal[True]): If `value` is a valid finnish business id. 

55 (ValidationError): If `value` is an invalid finnish business id. 

56 """ 

57 if not value: 

58 return False 

59 if not re.match(_business_id_pattern(), value): 

60 return False 

61 factors = [7, 9, 10, 5, 8, 4, 2] 

62 numbers = map(int, value[:7]) 

63 checksum = int(value[8]) 

64 modulo = sum(f * n for f, n in zip(factors, numbers)) % 11 

65 return (11 - modulo == checksum) or (modulo == checksum == 0) 

66 

67 

68@validator 

69def fi_ssn(value: str, /, *, allow_temporal_ssn: bool = True): 

70 """Validate a Finnish Social Security Number. 

71 

72 This validator is based on [django-localflavor-fi][1]. 

73 

74 [1]: https://github.com/django/django-localflavor-fi/ 

75 

76 Examples: 

77 >>> fi_ssn('010101-0101') 

78 # Output: True 

79 >>> fi_ssn('101010-0102') 

80 # Output: ValidationError(func=fi_ssn, args=...) 

81 

82 Args: 

83 value: 

84 Social Security Number to be validated. 

85 allow_temporal_ssn: 

86 Whether to accept temporal SSN numbers. Temporal SSN numbers are the 

87 ones where the serial is in the range [900-999]. By default temporal 

88 SSN numbers are valid. 

89 

90 Returns: 

91 (Literal[True]): If `value` is a valid finnish SSN. 

92 (ValidationError): If `value` is an invalid finnish SSN. 

93 """ 

94 if not value: 

95 return False 

96 ssn_check_marks = "0123456789ABCDEFHJKLMNPRSTUVWXY" 

97 if not (result := re.match(_ssn_pattern(ssn_check_marks), value)): 

98 return False 

99 gd = result.groupdict() 

100 checksum = int(gd["date"] + gd["serial"]) 

101 return ( 

102 int(gd["serial"]) >= 2 

103 and (allow_temporal_ssn or int(gd["serial"]) <= 899) 

104 and ssn_check_marks[checksum % len(ssn_check_marks)] == gd["checksum"] 

105 )