diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2013-05-17 12:46:27 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2013-06-08 14:45:39 +0200 |
commit | 2259cbb09e419e56c355efdbd865f99127d559c5 (patch) | |
tree | 736b02f87d6f1240ae14a5dba118a617cb0b688b /stdnum/es/cif.py | |
parent | 07c66e13b3928fb92fd0e537e23d3c5be2ad8956 (diff) |
Implement validate() for Spanish numbers
Diffstat (limited to 'stdnum/es/cif.py')
-rw-r--r-- | stdnum/es/cif.py | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/stdnum/es/cif.py b/stdnum/es/cif.py index 679e596..eeb0e72 100644 --- a/stdnum/es/cif.py +++ b/stdnum/es/cif.py @@ -1,7 +1,7 @@ # cif.py - functions for handling Spanish fiscal numbers # coding: utf-8 # -# Copyright (C) 2012 Arthur de Jong +# Copyright (C) 2012, 2013 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -24,25 +24,32 @@ The CIF is a tax identification number for legal entities. It has 9 digits where the first digit is a letter (denoting the type of entity) and the last is a check digit (which may also be a letter). ->>> compact('J-99216582') +>>> validate('J99216582') 'J99216582' ->>> is_valid('J99216582') -True ->>> is_valid('J99216583') # invalid check digit -False ->>> is_valid('M-1234567-L') -True ->>> is_valid('O-1234567-L') # invalid first character -False +>>> validate('J99216583') # invalid check digit +Traceback (most recent call last): + ... +InvalidChecksum: ... +>>> validate('J992165831') # too long +Traceback (most recent call last): + ... +InvalidLength: ... +>>> validate('M-1234567-L') +'M1234567L' +>>> validate('O-1234567-L') # invalid first character +Traceback (most recent call last): + ... +InvalidFormat: ... >>> split('A13 585 625') ('A', '13', '58562', '5') """ from stdnum import luhn from stdnum.es import dni +from stdnum.exceptions import * -__all__ = ['compact', 'is_valid', 'split'] +__all__ = ['compact', 'validate', 'is_valid', 'split'] # use the same compact function as DNI @@ -57,28 +64,40 @@ def calc_check_digits(number): return check + 'JABCDEFGHI'[int(check)] -def is_valid(number): +def validate(number): """Checks to see if the number provided is a valid DNI number. This checks the length, formatting and check digit.""" - try: - number = compact(number) - except: - return False - if len(number) != 9 or not number[1:-1].isdigit(): - return False + number = compact(number) + if not number[1:-1].isdigit(): + raise InvalidFormat() + if len(number) != 9: + raise InvalidLength() if number[0] in 'KLM': # K: Spanish younger than 14 year old # L: Spanish living outside Spain without DNI # M: granted the tax to foreigners who have no NIE # these use the old checkdigit algorithm (the DNI one) - return number[-1] == dni.calc_check_digit(number[1:-1]) - # there seems to be conflicting information on which organisation types - # should have which type of check digit (alphabetic or numeric) so - # we support either here - if number[0] in 'ABCDEFGHJNPQRSUVW': - return number[-1] in calc_check_digits(number[:-1]) - # anything else is invalid - return False + if number[-1] != dni.calc_check_digit(number[1:-1]): + raise InvalidChecksum() + elif number[0] in 'ABCDEFGHJNPQRSUVW': + # there seems to be conflicting information on which organisation types + # should have which type of check digit (alphabetic or numeric) so + # we support either here + if number[-1] not in calc_check_digits(number[:-1]): + raise InvalidChecksum() + else: + # anything else is invalid + raise InvalidFormat() + return number + + +def is_valid(number): + """Checks to see if the number provided is a valid DNI number. This + checks the length, formatting and check digit.""" + try: + return bool(validate(number)) + except ValidationError: + return False def split(number): |