Skip to content

Commit 3038f78

Browse files
xiehuanyinandgator
authored andcommitted
Require numeric check digits in CUSIP and SEDOL identifiers
1 parent 4db9c17 commit 3038f78

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

‎src/validators/finance.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def cusip(value: str):
8282
(Literal[True]): If `value` is a valid CUSIP string.
8383
(ValidationError): If `value` is an invalid CUSIP string.
8484
"""
85-
return len(value) == 9 and _cusip_checksum(value)
85+
return len(value) == 9 and value[-1] in "0123456789" and _cusip_checksum(value)
8686

8787

8888
@validator
@@ -128,7 +128,7 @@ def sedol(value: str):
128128
(Literal[True]): If `value` is a valid SEDOL string.
129129
(ValidationError): If `value` is an invalid SEDOL string.
130130
"""
131-
if len(value) != 7:
131+
if len(value) != 7 or value[-1] not in "0123456789":
132132
return False
133133

134134
weights = [1, 3, 1, 7, 3, 9, 1]

‎tests/test_finance.py‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
"""Test Finance."""
22

3+
# standard
4+
from typing import Callable
5+
36
# external
47
import pytest
58

@@ -61,3 +64,27 @@ def test_returns_true_on_valid_sedol(value: str):
6164
def test_returns_failed_validation_on_invalid_sedol(value: str):
6265
"""Test returns failed validation on invalid sedol."""
6366
assert isinstance(sedol(value), ValidationError)
67+
68+
69+
@pytest.mark.parametrize(
70+
"validate, value",
71+
[
72+
(cusip, "03783310J"),
73+
(cusip, "03783310j"),
74+
(cusip, "03783310@"),
75+
(sedol, "293692L"),
76+
(sedol, "B12345G"),
77+
(sedol, "B12345Q"),
78+
],
79+
)
80+
def test_rejects_non_numeric_check_digit(validate: Callable[[str], object], value: str):
81+
"""Reject letters and symbols that accidentally satisfy the checksum."""
82+
assert isinstance(validate(value), ValidationError)
83+
84+
85+
@pytest.mark.parametrize(
86+
"validate, value", [(cusip, "037833100"), (sedol, "2936921"), (sedol, "B123456")]
87+
)
88+
def test_accepts_numeric_check_digit(validate: Callable[[str], object], value: str):
89+
"""Keep valid numeric check digits, including alphanumeric identifiers."""
90+
assert validate(value) is True

0 commit comments

Comments
 (0)