Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions tests/test_finance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
import pytest

import validators

#good values
@pytest.mark.parametrize('value', [
'912796X38',
'912796X20',
'912796x20'
])
def test_returns_true_on_valid_cusip(value):
assert validators.cusip(value)

#bad values
@pytest.mark.parametrize('value', [
'912796T67',
'912796T68',
'XCVF',
'00^^^1234',
'1234567890'
])
def test_returns_failed_validation_on_invalid_cusip(value):
result = validators.cusip(value)
assert isinstance(result, validators.ValidationFailure)



#good values
@pytest.mark.parametrize('value', [
'0263494',
'0540528',
'B000009'
])
def test_returns_true_on_valid_sedol(value):
assert validators.sedol(value)

#bad values
@pytest.mark.parametrize('value', [
'0540526',
'XCVF',
'00^^^1234',
'A000009'
])
def test_returns_failed_validation_on_invalid_sedol(value):
result = validators.sedol(value)
assert isinstance(result, validators.ValidationFailure)




#good values
@pytest.mark.parametrize('value', [
'US0004026250',
'JP000K0VF054',
'US0378331005'
])
def test_returns_true_on_valid_isin(value):
assert validators.isin(value)

#bad values
@pytest.mark.parametrize('value', [
'010378331005'
'XCVF',
'00^^^1234',
'A000009'
])
def test_returns_failed_validation_on_invalid_isin(value):
result = validators.isin(value)
assert isinstance(result, validators.ValidationFailure)

4 changes: 3 additions & 1 deletion validators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
from .url import url
from .utils import ValidationFailure, validator
from .uuid import uuid
from .finance import ( cusip, sedol, isin )

__all__ = ('between', 'domain', 'email', 'Max', 'Min', 'md5', 'sha1', 'sha224',
'sha256', 'sha512', 'fi_business_id', 'fi_ssn', 'iban', 'ipv4',
'ipv4_cidr', 'ipv6', 'ipv6_cidr', 'length', 'mac_address', 'slug',
'truthy', 'url', 'ValidationFailure', 'validator', 'uuid',
'card_number', 'visa', 'mastercard', 'amex', 'unionpay', 'diners',
'jcb', 'discover', 'btc_address')
'jcb', 'discover', 'btc_address', 'cusip', 'sedol', 'isin')

__version__ = '0.20.0'

145 changes: 145 additions & 0 deletions validators/finance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@


from .utils import validator

def cusipChecksum( cusip ) :

check = 0
val = None # just to be extra safe - should not be needed but ...

for digitIndex in range(9) :
c = cusip[digitIndex]
if c >= '0' and c <= '9' :
val = ord(c) - ord('0')
elif c >= 'A' and c <= 'Z' :
val = 10 + ord(c) - ord('A')
elif c >= 'a' and c <= 'z' :
val = 10 + ord(c) - ord('a')
elif c == '*' :
val = 36
elif c == '@' :
val = 37
elif c == '#' :
val = 38
else :
return False

if digitIndex & 1 :
val = val + val

check = check + (val // 10) + (val % 10)

return (check % 10) == 0


@validator
def cusip(value):
"""
Return whether or not given value is a valid CUSIP.

If the value is a valid CUSIP this function returns ``True``, otherwise
:class:`~validators.utils.ValidationFailure`.

Examples::

>>> cusip('037833DP2')
True

>>> cusip('037833DP3')
ValidationFailure(func=cusip, ...)

.. versionadded:: 0.20

:param value: CUSIP string to validate
"""
return len(value)==9 and cusipChecksum(value)



def isinChecksum( value ) :

check = 0
val = None # just to be extra safe - should not be needed but ...

for digitIndex in range(12) :
c = value[digitIndex]
if c >= '0' and c <= '9' and digitIndex>1 :
val = ord(c) - ord('0')
elif c >= 'A' and c <= 'Z' :
val = 10 + ord(c) - ord('A')
elif c >= 'a' and c <= 'z' :
val = 10 + ord(c) - ord('a')
else :
return False

if digitIndex & 1 :
val = val + val

return (check %10) == 0


@validator
def isin(value):
"""
Return whether or not given value is a valid ISIN.

If the value is a valid ISIN this function returns ``True``, otherwise
:class:`~validators.utils.ValidationFailure`.

Examples::

>>> isin('037833DP2')
True

>>> isin('037833DP3')
ValidationFailure(func=isin, ...)

.. versionadded:: 0.20

:param value: ISIN string to validate
"""
return len(value)==12 and isinChecksum(value)




@validator
def sedol(value):
"""
Return whether or not given value is a valid SEDOL.

If the value is a valid SEDOL this function returns ``True``, otherwise
:class:`~validators.utils.ValidationFailure`.

Examples::

>>> sedol('2936921')
True

>>> sedol('29A6922')
ValidationFailure(func=sedol, ...)

.. versionadded:: 0.20

:param value: SEDOL string to validate
"""
if len(value)!=7 :
return False

weights = [ 1, 3, 1, 7, 3, 9, 1 ]
check = 0
for digitIndex in range(7) :
c = value[digitIndex]
if c in 'AEIOU' :
return False

val = None
if c >= '0' and c <= '9' :
val = ord(c) - ord('0')
elif c >= 'A' and c <= 'Z' :
val = 10 + ord(c) - ord('A')
else :
return False
check += val * weights[digitIndex]

return (check%10)==0