lists.arthurdejong.org
RSS feed

python-stdnum branch master updated. 1.5-2-gdcde8f4

[Date Prev][Date Next] [Thread Prev][Thread Next]

python-stdnum branch master updated. 1.5-2-gdcde8f4



This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "python-stdnum".

The branch, master has been updated
       via  dcde8f4f0dfbaba274d0ced7383b5a0809c11e48 (commit)
       via  da18e3ba8794b9eaa611c17fed23552dd51aa024 (commit)
      from  62ebbceaf8dd7baeb6ff310da90ff8e2096af580 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://arthurdejong.org/git/python-stdnum/commit/?id=dcde8f4f0dfbaba274d0ced7383b5a0809c11e48

commit dcde8f4f0dfbaba274d0ced7383b5a0809c11e48
Author: Luciano Rossi <lukio@gcoop.coop>
Date:   Mon Nov 14 16:35:24 2016 -0300

    Implement CBU (unique bank code) of Argentina
    
    See https://github.com/arthurdejong/python-stdnum/issues/43

diff --git a/stdnum/ar/cbu.py b/stdnum/ar/cbu.py
new file mode 100644
index 0000000..cd753ac
--- /dev/null
+++ b/stdnum/ar/cbu.py
@@ -0,0 +1,86 @@
+# cbu.py - functions for handling Argentinian CBU numbers
+# coding: utf-8
+#
+# Copyright (C) 2016 Luciano Rossi
+#
+# 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
+
+"""CBU (Clave Bancaria Uniforme, Argentine bank account number).
+
+CBU it s a code of the Banks of Argentina to identify customer
+accounts. The number consists of 22 digits and consists of a 3 digit
+bank identiefyer, followed by a 4 digit branch identifyer, a check
+digit, a 13 digit account identifyer and another check digit.
+
+More information:
+
+* https://es.wikipedia.org/wiki/Clave_Bancaria_Uniforme
+* http://www.clientebancario.gov.ar/mediospago/mp080000.asp
+
+>>> validate('2850590940090418135201')
+'2850590940090418135201'
+>>> format('2850590940090418135201')
+'28505909 40090418135201'
+>>> validate('2810590940090418135201')
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+"""
+
+from stdnum.exceptions import *
+from stdnum.util import clean
+
+
+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 calc_check_digit(number):
+    """Calculate the check digit."""
+    weights = (3, 1, 7, 9)
+    check = sum(int(n) * weights[i % 4]
+                for i, n in enumerate(reversed(number)))
+    return str((10 - check) % 10)
+
+
+def validate(number):
+    """Checks to see if the number provided is a valid CBU."""
+    number = compact(number)
+    if len(number) != 22:
+        raise InvalidLength()
+    if not number.isdigit():
+        raise InvalidFormat()
+    if calc_check_digit(number[:7]) != number[7]:
+        raise InvalidChecksum()
+    if calc_check_digit(number[8:-1]) != number[-1]:
+        raise InvalidChecksum()
+    return number
+
+
+def is_valid(number):
+    """Checks to see if the number provided is a valid CBU."""
+    try:
+        return bool(validate(number))
+    except ValidationError:
+        return False
+
+
+def format(number):
+    """Reformat the passed number to the standard format."""
+    number = compact(number)
+    return ' '.join((number[:8], number[8:]))
diff --git a/tests/test_ar_cbu.doctest b/tests/test_ar_cbu.doctest
new file mode 100644
index 0000000..151600e
--- /dev/null
+++ b/tests/test_ar_cbu.doctest
@@ -0,0 +1,79 @@
+test_ar_cbu.doctest - more detailed doctests for the stdnum.ar.cbu module
+
+Copyright (C) 2016 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
+
+
+This file contains more detailed doctests for the stdnum.ar.cbu module. It
+tries to validate a number of numbers that have been found online.
+
+>>> from stdnum.ar import cbu
+>>> from stdnum.exceptions import *
+
+
+These have been found online and should all be valid numbers.
+
+>>> numbers = '''
+...
+... 0 0 7 0 9 9 9 0 2 0 0 0 0 0 6 5 7 0 6 0 8 0
+... 0 1 1 0 4 3 3 6 3 0 0 4 3 3 1 3 8 5 7 6 8 3
+... 0 1 4 0 3 3 9 6   0 1 6 3 0 2 0 1 3 8 1 2 7 6
+... 0 1400 236 – 01 5068 0262 5874
+... 0 4 4 0 0 6 4 – 6 – 4 0 0 0 0 1 4 2 9 4 1 0 9 – 2
+... 0 7 2 0 1 4 6 8 2 0 0 0 0 0 0 1 0 6 2 3 4 0
+... 0 7 2 0 1 6 8 0 2 0 0 0 0 0 0 1 1 8 3 2 3 6
+... 0 7 2 0 3 8 0 8 8 8 0 0 0 0 3 5 5 3 3 9 6 8
+... 0070090020000004146504
+... 0110097630009704213797
+... 0140339601630201381276
+... 0140351801684605023087
+... 0168888-1-0000827441015-8
+... 01703342 – 200 000 3036 7766
+... 0200915901000000274233
+... 03400562 00560007577005
+... 0720079388000035942322
+... 0940099324001313220028
+... 1 5 0 0 0 0 6 0 0 0 0 0 5 6 6 0 4 4 7 2 0 0
+... 1 5 0 0 0 8 7 9 - 0 0 0 5 1 3 3 2 0 7 5 1 9 - 6
+... 1 9 1 0 1 1 9 6   5 5 0 1 1 9 0 1 0 8 4 6 4 6
+... 2850590940090418135201
+...
+... '''
+>>> [x for x in numbers.splitlines() if x and not cbu.is_valid(x)]
+[]
+
+
+More detailed tests:
+
+>>> cbu.validate('285059094009041')
+Traceback (most recent call last):
+    ...
+InvalidLength: ...
+>>> cbu.validate('A850590940090418135201')
+Traceback (most recent call last):
+    ...
+InvalidFormat: ...
+>>> cbu.validate('0940099324001313220028')
+'0940099324001313220028'
+>>> cbu.validate('1940099324001313220028')  # error in first part
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...
+>>> cbu.validate('0940099324001313220038')  # error in second part
+Traceback (most recent call last):
+    ...
+InvalidChecksum: ...

http://arthurdejong.org/git/python-stdnum/commit/?id=da18e3ba8794b9eaa611c17fed23552dd51aa024

commit da18e3ba8794b9eaa611c17fed23552dd51aa024
Author: Arthur de Jong <arthur@arthurdejong.org>
Date:   Mon Nov 14 23:53:30 2016 +0100

    Add Python 2.6 support
    
    This also brings the list of Python versions in setup.py in line with
    tox.ini.

diff --git a/setup.py b/setup.py
index d91a7a9..941ff4e 100755
--- a/setup.py
+++ b/setup.py
@@ -55,6 +55,7 @@ setup(name='python-stdnum',
           'Programming Language :: Python :: 3',
           'Programming Language :: Python :: 3.4',
           'Programming Language :: Python :: 3.5',
+          'Programming Language :: Python :: 3.6',
           'Topic :: Office/Business :: Financial',
           'Topic :: Software Development :: Libraries :: Python Modules',
           'Topic :: Text Processing :: General',
diff --git a/stdnum/fi/associationid.py b/stdnum/fi/associationid.py
index 7af46c9..4efed2b 100644
--- a/stdnum/fi/associationid.py
+++ b/stdnum/fi/associationid.py
@@ -31,11 +31,11 @@ in groups of 0-3 and 0-3 numbers. E.g. 123.123, 12.123, 
1.123, 123 or 1.
 >>> validate('123123123')
 Traceback (most recent call last):
   ...
-stdnum.exceptions.InvalidLength: The number has an invalid length.
+InvalidLength: The number has an invalid length.
 >>> validate('12df')
 Traceback (most recent call last):
   ...
-stdnum.exceptions.InvalidFormat: The number has an invalid format.
+InvalidFormat: The number has an invalid format.
 >>> format('123')
 '123'
 >>> format('1234')
diff --git a/stdnum/meid.py b/stdnum/meid.py
index 36b4445..be52fbd 100644
--- a/stdnum/meid.py
+++ b/stdnum/meid.py
@@ -1,6 +1,6 @@
 # meid.py - functions for handling Mobile Equipment Identifiers (MEIDs)
 #
-# Copyright (C) 2010, 2011, 2012, 2013 Arthur de Jong
+# Copyright (C) 2010-2016 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
@@ -105,6 +105,14 @@ def compact(number, strip_check_digit=True):
     return number + cd
 
 
+def _bit_length(n):
+    """Number of bits necessary to represent the number in binary."""
+    if hasattr(n, 'bit_length'):
+        return n.bit_length()
+    import math
+    return int(math.log(n, 2)) + 1
+
+
 def validate(number, strip_check_digit=True):
     """Checks to see if the number provided is a valid MEID number. This
     converts the representation format of the number (if it is
@@ -119,7 +127,7 @@ def validate(number, strip_check_digit=True):
         # convert to hex
         manufacturer_code = int(number[0:10])
         serial_num = int(number[10:18])
-        if manufacturer_code.bit_length() > 32 or serial_num.bit_length() > 24:
+        if _bit_length(manufacturer_code) > 32 or _bit_length(serial_num) > 24:
             raise InvalidComponent()
         number = '%08X%06X' % (manufacturer_code, serial_num)
         cd = calc_check_digit(number)
diff --git a/tests/test_mx_rfc.doctest b/tests/test_mx_rfc.doctest
index 2d5e2f3..eba887d 100644
--- a/tests/test_mx_rfc.doctest
+++ b/tests/test_mx_rfc.doctest
@@ -35,7 +35,7 @@ InvalidComponent: ...
 The last three digits are in a special alphabet and should only contain
 1-9A-V, 1-9A-Z and 0-9A for the last digits.
 
->>> rfc.validate('AABN 821103 8Ñ2')
+>>> rfc.validate('AABN 821103 8\xd12')  # \xd1 is the N with tilde
 Traceback (most recent call last):
     ...
 InvalidFormat: ...
diff --git a/tox.ini b/tox.ini
index f8b77dc..ec926c4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = {py27,py34,py35,py36,pypy}
+envlist = {py26,py27,py34,py35,py36,pypy}
 
 [testenv]
 deps = nose

-----------------------------------------------------------------------

Summary of changes:
 setup.py                        |  1 +
 stdnum/{do/rnc.py => ar/cbu.py} | 51 ++++++++++++++------------
 stdnum/fi/associationid.py      |  4 +--
 stdnum/meid.py                  | 12 +++++--
 tests/test_ar_cbu.doctest       | 79 +++++++++++++++++++++++++++++++++++++++++
 tests/test_mx_rfc.doctest       |  2 +-
 tox.ini                         |  2 +-
 7 files changed, 123 insertions(+), 28 deletions(-)
 copy stdnum/{do/rnc.py => ar/cbu.py} (56%)
 create mode 100644 tests/test_ar_cbu.doctest


hooks/post-receive
-- 
python-stdnum
-- 
To unsubscribe send an email to
python-stdnum-commits-unsubscribe@lists.arthurdejong.org or see
https://lists.arthurdejong.org/python-stdnum-commits/