Repository navigation
Release 1.12.0
The first release since 1.11.0. It fixes validity bugs that were found by comparing the library with its Node.js port
and with python-stdnum. Every fix cites its source in the class docstring or in METADATA.links. Several fixes change
which IDs are accepted, so read the first two sections before you upgrade.
Behaviour changes
validate()never raises any more. It returnsFalsefor non-strinput, for empty input and for malformed input,
andparse()returnsNonefor the same inputs. Before, most types raisedAssertionError,ValueError,
IndexErrororTypeError(#371).- An integer is no longer converted to a string. ALB, ARE, BHR, CHN, EST, ITA, KWT, LKA (old), LTU, POL and VNM used to
turn non-strinput into text withrepr(), soLTU.NationalID.validate(37605030299)wasTrue. It is nowFalse,
like every other type. Convert integers withstr()first (#371). - The whole input must match, with ASCII digits only. A trailing newline, and digits such as Arabic-Indic
١٢٣or
full-width123, used to slip through the patterns and are now rejected
(#369). The Irish PPS number allows only a space after the number,
not other whitespace. A tab or newline there used to raise and now givesFalse
(#369). checksum()has a documented contract for malformed input. Checksums that return a digit or letter returnNone, and
checksums that return aboolreturnFalse, instead of raising or returning a meaningless value:- BGR, BRA (CPF and RG), IRN and JPN:
NoneorFalsefor input that does not match the format. For example,
JPN.MyNumber.checksum('00000000178')was'3'and is nowNone
(#371). - ZAF:
Nonefor input that does not match the ID format (#394). - TWN:
Noneinstead ofFalse(#396,
#414). - CHL:
Noneinstead of raising or returning a meaningless character
(#410). - ZWE:
Falseinstead of raisingAttributeError(#415). - Callers that used
checksum()to compute a check digit from a prefix that does not match the ID format are
affected.
- BGR, BRA (CPF and RG), IRN and JPN:
checksum()results that were wrong are corrected: TWN returns0instead of10
(#396), BGR EGN returns0instead of10
(#375), andutil.ean13_digitnow weights the even positions by 3
as EAN-13 does (#377). CHEBusinessIDgains achecksum()method
(#377).parse()returnsNonefor IDs that are valid but have no complete birth date or no check digit to report: BEL
numbers with an unknown month or day (#373), and CZE and SVK
9-digit birth numbers (#384).ParseResultis unchanged. BEL
numbers withyy50 now parse to 1950, not 2050 (#373).- Some types now accept or reject whole groups of IDs. The largest shifts are GEO (11 digits instead of 9,
#400), ZWE (a new check letter,
#398), CHL 7-digit RUTs
(#382), CHE AHV numbers
(#377) and TWN
(#396). See "Validity changes".
Validity changes
Each bullet says what is accepted now and what is rejected now. Vectors are taken from the pull requests, and most of
them are also tests.
- BEL national registration number (#373):
- The post-2000 check digit was computed with an operator-precedence bug. Real numbers born from 2000, such as
01010100126, were rejected, and anyyybelow 50 with check number29was accepted (00010100129, now
rejected). - The century is inferred from the check digit, as the Rijksregister instruction IT000 requires. 1900-1949 numbers
such as47010100190are now valid. A future 20xx birth year is rejected. - For
yy50, validity is unchanged, butparse()now returns 1950 instead of 2050 (50010100156was read as
2050-01-01 and is now 1950-01-01). - A month
00or a day00(an incomplete birth date, for example85003003376) is now valid andparse()returns
None. A day that does not exist in its month, and a month above 12, stay invalid.
- The post-2000 check digit was computed with an operator-precedence bug. Real numbers born from 2000, such as
- BEL entity VAT (#373): a 10-digit number must start with
0or
1. A 9-digit number may start with any digit. - BGR EGN (#375): a weighted-sum remainder of 10 gives check
digit 0. About 1 in 11 real EGNs, such as8507300050and0001011000, were rejected before. - BGR 13-digit EIK/BULSTAT (#375): the check now weights digits 9
to 12, and the first nine digits must be a valid 9-digit EIK.0114806291686is valid and0114806291688is not.
9-digit codes are unchanged. - CHE AHV/AVS number (#377):
- The check digit uses the EAN-13 weights 1 and 3. Genuine numbers such as
756.9217.0769.85are now accepted and
wrong ones such as756.0000.5678.17are rejected. - The dot in the pattern is escaped, so
756.1234.5678-97isFalse.
- The check digit uses the EAN-13 weights 1 and 3. Genuine numbers such as
- CHE UID (
BusinessID) (#377): the modulus 11 check digit is
verified.CHE-116.281.710is valid andCHE-116.281.715is not. - CHL RUT (#382,
#410):- The weights run from the right, so 7-digit RUTs are checked correctly.
1.111.111-4is valid,1.111.111-3is not.
8-digit RUTs are unchanged. - A lowercase check character is accepted:
10.000.013-kis valid.
- The weights run from the right, so 7-digit RUTs are checked correctly.
- CZE and SVK birth number (#384):
- Check digit 0 is accepted when the first nine digits leave remainder 10:
5401031230is valid. - 9-digit numbers are accepted for births up to 1953. They need a valid date with
yy53 or below, for example
530101123. - A 10-digit number with
yy00 to 53 is read as 2000 to 2053 and a birth date in the future is invalid.5001010003
is no longer read as 1950.METADATA.min_lengthis now 9.
- Check digit 0 is accepted when the first nine digits leave remainder 10:
- ITA fiscal code (#386):
- Omocodia codes are now valid.
RSSMRA8LM01H501Wused to makevalidate()raise. parse()maps the letters back to digits (area_codeisH500instead ofH50L) and picks the century: 20yy
unless that date is in the future, otherwise 19yy.RSSMRA40M01H501Bis born in 1940. Validity does not change for
IDs without omocodia letters.
- Omocodia codes are now valid.
- KWT civil number (#388): a number with a correct check digit
but an impossible birth date (200022900006,200013200008,200001000009) used to raise.validate()is now
Falseandparse()isNone. - NOR national ID (#389):
- An impossible date (31 April, 30 February, day or month
00,00000000000) givesFalseinstead of raising. - D-numbers (day plus 40, for example
41019912351) and H-numbers (month plus 40, for example01419912340) are now
valid andparse()returns the real birth date. A number with both offsets, and FH-numbers, stay invalid.
- An impossible date (31 April, 30 February, day or month
- ROU personal numerical code (#391): the first digit 6 (women
born 2000 to 2099) no longer raises, and6050315121230is valid. The first digit 2 now means 1900 to 1999 and 4
means 1800 to 1899, so4000229011237(29 February 1800) is invalid. - SGP NRIC/FIN (#392): M-series FINs add a start constant of 3 to
the weighted sum.M1234567KandM3960741Nare now valid, andM1234567Nis not. The S, T, F and G series are
unchanged. - ZAF national ID (#394,
#275): non-numeric input such asabcraisedValueErrorand now
givesFalse. IDs with month 10 are accepted too, see the CHN and ZAF month pattern entry below. - TWN national ID (#396): a weighted sum that is a multiple of 10
gives check digit 0. About 1 in 10 genuine IDs, such asM162773050andA120229780, were rejected before. - ZWE national ID (#398): the check letter is the whole number
modulo 23, as the cited source says, and not the digit sum.502001148W50and082095850T42are now valid.
751919620S86is now invalid, and751919620J86is the valid one. About 22 in 23 of the IDs that passed the old
digit-sum rule are now rejected. - GEO personal number (#400): the number has 11 digits, and may
start with 0.01001011234is valid. Every 9-digit string, which was valid before, is now invalid. - BRA RG and SWE personal identity number (#402,
#371): a literal|is no longer part of the pattern
(12.345.678-|,811228|9874). These inputs used to makevalidate()raise and now giveFalse. - CHN and ZAF month pattern (#275): the pattern accepted
months 01 to 09, 11 and 12 but not 10. IDs with month 10, for example CHN372925199510103222, are now valid. - NZL driver licence (#369): the two leading characters must be
ASCII.AB123456is valid, andÄB123456andΑΒ123456(Greek capitals) are rejected.
New ID types
- Cyprus tax identification number,
CYP.TaxNumber(alsoCYP.NationalIDandCYP.TIN)
(#261,
#265). - Czech Republic tax number, DIČ,
CZE.TaxNumber(alsoCZE.TIN)
(#266). It follows python-stdnum: 8-digit entity numbers must not
start with 9, 9-digit numbers starting with 6 have a special check digit, and every other 9 or 10-digit number is
validated as a birth number (#384). - Denmark entity VAT,
DNK.EntityVAT, also known as CVR or SE (alsoDNK.TIN.entity)
(#274).
Other fixes
parse()no longer raises on malformed input: BGR returnsNoneon a failed match, UKR checks the pattern before
callingint(), and LKA (old) catchesOverflowErrorin the date arithmetic
(#371).- GRC, ISR and LVA no longer index
id_number[-1]for an empty string, and NZL NHI no longer has an empty alternative
in its pattern (#371). idnumbers.nationalid.util.match_regexp()is new.validate_regexp()and everyparse()that reads the pattern now
use it, so they match the whole input (#369).
Internal, docs and CI
- CI runs the tests on Python 3.9 to 3.14 with current GitHub Actions, and
setup.pylists the 3.13 and 3.14
classifiers (#368). - A tool,
python3 -m tools.collect_regexp, dumps the regular expressions of all ID types, and the aliases of MKD, MNE
and SRBJMBG, PAKCNIC, SMRSSIand VENRIFnow usealias_of
(#269). - The API docs are now built with the reStructuredText docformat, and the
match_regexpdocstring renders correctly
(#380, #408). - The README gains an "Input handling" section (#371,
#403). New tests sweep every ID type to check thatvalidate()
never raises and rejects a trailing newline and non-ASCII digits
(#369, #371). - Test and docs tidy-ups with no behaviour change: #403,
#405, #406,
#407, #411,
#412, #413,
#414, #416 and
#417 (misplaced method docstrings moved to the top of their
functions, with a test that keeps them there).
Full Changelog: v1.11.0...v1.12.0