From 2259cbb09e419e56c355efdbd865f99127d559c5 Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Fri, 17 May 2013 12:46:27 +0200 Subject: Implement validate() for Spanish numbers --- stdnum/es/cif.py | 71 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 26 deletions(-) (limited to 'stdnum/es/cif.py') 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): -- cgit v1.2.3