Switch to python3

This commit is contained in:
j 2014-09-30 18:15:32 +02:00
commit 9ba4b6a91a
5286 changed files with 677347 additions and 576888 deletions

View file

@ -0,0 +1,24 @@
# __init__.py - collection of French numbers
# coding: utf-8
#
# Copyright (C) 2012 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
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
"""Collection of French numbers."""
# provide vat as an alias
from stdnum.fr import tva as vat

View file

@ -0,0 +1,85 @@
# siren.py - functions for handling French SIREN numbers
# coding: utf-8
#
# 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
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
"""SIREN (a French company identification number).
The SIREN (Système d'Identification du Répertoire des Entreprises) is a 9
digit number used to identify French companies. The Luhn checksum is used
to validate the numbers.
>>> compact('552 008 443')
'552008443'
>>> validate('404833048')
'404833048'
>>> validate('404833047')
Traceback (most recent call last):
...
InvalidChecksum: ...
>>> to_tva('443 121 975')
'46 443 121 975'
"""
from stdnum import luhn
from stdnum.exceptions import *
from stdnum.util import clean
# An online validation function is available but it does not provide an
# automated entry point, has usage restrictions and seems to require
# attribution to the service for any results used.
# http://avis-situation-sirene.insee.fr/
def compact(number):
"""Convert the number to the minimal representation. This strips the
number of any valid separators and removes surrounding whitespace."""
return clean(number, ' ').strip()
def validate(number):
"""Checks to see if the number provided is a valid number. This checks
the length, formatting and check digit."""
number = compact(number)
if not number.isdigit():
raise InvalidFormat()
if len(number) != 9:
raise InvalidLength()
luhn.validate(number)
return number
def is_valid(number):
"""Checks to see if the number provided is a valid number. This checks
the length, formatting and check digit."""
try:
return bool(validate(number))
except ValidationError:
return False
def to_tva(number):
"""Return a TVA that prepends the two extra check digits to the SIREN."""
# note that this always returns numeric check digits
# it is unclean when the alphabetic ones are used
return '%02d%s%s' % (
int(compact(number) + '12') % 97,
' ' if ' ' in number else '',
number
)

View file

@ -0,0 +1,94 @@
# tva.py - functions for handling French TVA numbers
# coding: utf-8
#
# 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
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 USA
"""n° TVA (taxe sur la valeur ajoutée, French VAT number).
The n° TVA (Numéro d'identification à la taxe sur la valeur ajoutée) is the
SIREN (Système dIdentification du Répertoire des Entreprises) prefixed by
two digits. In old style numbers the two digits are numeric, with new
style numbers at least one is a alphabetic.
>>> compact('Fr 40 303 265 045')
'40303265045'
>>> validate('23334175221')
'23334175221'
>>> validate('84 323 140 391')
Traceback (most recent call last):
...
InvalidChecksum: ...
>>> validate('K7399859412') # new-style number
'K7399859412'
>>> validate('4Z123456782') # new-style number starting with digit
'4Z123456782'
"""
from stdnum.exceptions import *
from stdnum.fr import siren
from stdnum.util import clean
# the valid characters for the first two digits (O and I are missing)
_alphabet = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ'
def compact(number):
"""Convert the number to the minimal representation. This strips the
number of any valid separators and removes surrounding whitespace."""
number = clean(number, ' -.').upper().strip()
if number.startswith('FR'):
number = number[2:]
return number
def validate(number):
"""Checks to see if the number provided is a valid VAT number. This
checks the length, formatting and check digit."""
number = compact(number)
if not all(x in _alphabet for x in number[:2]):
raise InvalidFormat()
if len(number) != 11:
raise InvalidLength()
siren.validate(number[2:])
if number.isdigit():
# all-numeric digits
if int(number[:2]) != (int(number[2:] + '12') % 97):
raise InvalidChecksum()
else:
# one of the first two digits isn't a number
if number[0].isdigit():
check = (
_alphabet.index(number[0]) * 24 +
_alphabet.index(number[1]) - 10)
else:
check = (
_alphabet.index(number[0]) * 34 +
_alphabet.index(number[1]) - 100)
if (int(number[2:]) + 1 + check // 11) % 11 != (check % 11):
raise InvalidChecksum()
return number
def is_valid(number):
"""Checks to see if the number provided is a valid VAT number. This
checks the length, formatting and check digit."""
try:
return bool(validate(number))
except ValidationError:
return False