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

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

31 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(check_marks=ssn_check_marks), 

28 re.VERBOSE, 

29 ) 

30 

31 

32@validator 

33def fi_business_id(value: str, /): 

34 """Validate a Finnish Business ID. 

35 

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

37 information see [Finnish Trade Register][1] 

38 

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

40 

41 Examples: 

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

43 True 

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

45 ValidationError(func=fi_business_id, args={'value': '1234567-8'}) 

46 

47 Args: 

48 value: 

49 Business ID string to be validated. 

50 

51 Returns: 

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

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

54 """ 

55 if not value: 

56 return False 

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

58 return False 

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

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

61 checksum = int(value[8]) 

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

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

64 

65 

66@validator 

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

68 """Validate a Finnish Social Security Number. 

69 

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

71 

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

73 

74 Examples: 

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

76 True 

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

78 ValidationError(func=fi_ssn, args={'value': '101010-0102'}) 

79 

80 Args: 

81 value: 

82 Social Security Number to be validated. 

83 allow_temporal_ssn: 

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

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

86 SSN numbers are valid. 

87 

88 Returns: 

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

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

91 """ 

92 if not value: 

93 return False 

94 ssn_check_marks = "0123456789ABCDEFHJKLMNPRSTUVWXY" 

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

96 return False 

97 gd = result.groupdict() 

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

99 return ( 

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

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

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

103 )