8000 Add swedish postcode validator · Dzikpol/python-stdnum@8071444 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8071444

Browse files
michelearthurdejong
authored andcommitted
Add swedish postcode validator
Closes arthurdejong#271
1 parent 424e408 commit 8071444

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

stdnum/se/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@
2222

2323
# provide aliases
2424
from stdnum.se import personnummer as personalid # noqa: F401
25+
from stdnum.se import postnummer as postal_code # noqa: F401

stdnum/se/postnummer.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# postnummer.py - functions for handling Swedish postal codes
2+
#
3+
# Copyright (C) 2021 Michele Ciccozzi
4+
#
5+
# This library is free software; you can redistribute it and/or
6+
# modify it under the terms of the GNU Lesser General Public
7+
# License as published by the Free Software Foundation; either
8+
# version 2.1 of the License, or (at your option) any later version.
9+
#
10+
# This library is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
# Lesser General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Lesser General Public
16+
# License along with this library; if not, write to the Free Software
17+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18+
# 02110-1301 USA
19+
20+
"""Postcode (the Swedish postal code).
21+
22+
The Swedish postal code consists of three numbers followed by two numbers,
23+
separated by a single space.
24+
25+
More information:
26+
27+
* https://en.wikipedia.org/wiki/Postal_codes_in_Sweden
28+
* https://sv.wikipedia.org/wiki/Postnummer_i_Sverige
29+
30+
>>> validate('114 18')
31+
'11418'
32+
>>> validate('SE-11418')
33+
'11418'
34+
>>> validate('1145 18')
35+
Traceback (most recent call last):
36+
...
37+
InvalidLength: ...
38+
>>> format('11418')
39+
'114 18'
40+
"""
41+
42+
from stdnum.exceptions import *
43+
from stdnum.util import clean, isdigits
44+
45+
46+
def compact(number):
47+
"""Convert the number to the minimal representation. This strips the
48+
number of any valid separators and removes surrounding whitespace."""
49+
number = clean(number, ' -').upper().strip()
50+
if number.startswith('SE'):
51+
number = number[2:]
52+
return number
53+
54+
55+
def validate(number):
56+
"""Check if the number is in the correct format. This currently does not
57+
check whether the code corresponds to a real address."""
58+
number = compact(number)
59+
if not isdigits(number) or number.startswith('0'):
60+
raise InvalidFormat()
61+
if len(number) != 5:
62+
raise InvalidLength()
63+
return number
64+
65+
66+
def is_valid(number):
67+
"""Check if the number is a valid postal code."""
68+
try:
69+
return bool(validate(number))
70+
except ValidationError:
71+
return False
72+
73+
74+
def format(number):
75+
"""Reformat the number to the standard presentation format."""
76+
number = compact(number)
77+
return '%s %s' % (number[:3], number[3:])

tests/test_se_postnummer.doctest

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
test_se_postnummer.doctest - more detailed doctests for stdnum.se.postnummer module
2+
3+
Copyright (C) 2021 Michele Ciccozzi
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18+
02110-1301 USA
19+
20+
21+
This file contains more detailed doctests for the stdnum.se.postnummer
22+
module. It tries to cover more corner cases and detailed functionality that
23+
is not really useful as module documentation.
24+
25+
26+
>>> from stdnum.se import postnummer
27+
28+
29+
Test for various formats and corner cases.
30+
31+
>>> postnummer.is_valid('114 18')
32+
True
33+
>>> postnummer.is_valid('SE-114 18')
34+
True
35+
>>> postnummer.is_valid('114018')
36+
False
37+
>>> postnummer.is_valid('01418')
38+
False
39+
40+
>>> postnummer.validate('114 18')
41+
'11418'
42+
>>> postnummer.validate('SE-114 18')
43+
'11418'
44+
>>> postnummer.validate('11418')
45+
'11418'
46+
47+
>>> postnummer.format('114 18')
48+
'114 18'
49+
>>> postnummer.format('SE-114 18')
50+
'114 18'
51+
>>> postnummer.format('11418')
52+
'114 18'
53+
54+
55+
Invalid values are rejected.
56+
57+
58+
>>> postnummer.validate('114180')
59+
Traceback (most recent call last):
60+
...
61+
InvalidLength: ...
62+
>>> postnummer.validate('1 14 18')
63+
'11418'
64+
>>> postnummer.validate('a' * 10)
65+
Traceback (most recent call last):
66+
...
67+
InvalidFormat: ...
68+
>>> postnummer.validate('a' * 11)
69+
Traceback (most recent call last):
70+
...
71+
InvalidFormat: ...
72+
>>> postnummer.validate('01234')
73+
Traceback (most recent call last):
74+
...
75+
InvalidFormat: ...

0 commit comments

Comments
 (0)
0