Skip to content

Commit 9bc6253

Browse files
committed
Require numeric check digits in CUSIP and SEDOL identifiers
1 parent 70de324 commit 9bc6253

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
@@ -71,7 +71,7 @@ def cusip(value: str):
7171
(Literal[True]): If `value` is a valid CUSIP string.
7272
(ValidationError): If `value` is an invalid CUSIP string.
7373
"""
74-
return len(value) == 9 and _cusip_checksum(value)
74+
return len(value) == 9 and value[-1] in "0123456789" and _cusip_checksum(value)
7575

7676

7777
@validator
@@ -117,7 +117,7 @@ def sedol(value: str):
117117
(Literal[True]): If `value` is a valid SEDOL string.
118118
(ValidationError): If `value` is an invalid SEDOL string.
119119
"""
120-
if len(value) != 7:
120+
if len(value) != 7 or value[-1] not in "0123456789":
121121
return False
122122

123123
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

@@ -49,3 +52,27 @@ def test_returns_true_on_valid_sedol(value: str):
4952
def test_returns_failed_validation_on_invalid_sedol(value: str):
5053
"""Test returns failed validation on invalid sedol."""
5154
assert isinstance(sedol(value), ValidationError)
55+
56+
57+
@pytest.mark.parametrize(
58+
"validate, value",
59+
[
60+
(cusip, "03783310J"),
61+
(cusip, "03783310j"),
62+
(cusip, "03783310@"),
63+
(sedol, "293692L"),
64+
(sedol, "B12345G"),
65+
(sedol, "B12345Q"),
66+
],
67+
)
68+
def test_rejects_non_numeric_check_digit(validate: Callable[[str], object], value: str):
69+
"""Reject letters and symbols that accidentally satisfy the checksum."""
70+
assert isinstance(validate(value), ValidationError)
71+
72+
73+
@pytest.mark.parametrize(
74+
"validate, value", [(cusip, "037833100"), (sedol, "2936921"), (sedol, "B123456")]
75+
)
76+
def test_accepts_numeric_check_digit(validate: Callable[[str], object], value: str):
77+
"""Keep valid numeric check digits, including alphanumeric identifiers."""
78+
assert validate(value) is True

0 commit comments

Comments
 (0)