Skip to content

Commit 8aea318

Browse files
gmorales96gabinopachCodefelipao-mx
authored
Update/pydantic v2 (#171)
* Upgrade Python version requirements and dependencies - Updated Python version from 3.7 to 3.8 in Makefile and README.md. - Upgraded Pydantic dependency from 1.9.0 to 2.10.3 in requirements.txt and setup.py. - Updated mypy version from 0.790 to 1.13.0 in requirements-test.txt. - Refactored CLABE validation logic in types.py, removing custom error classes and integrating Pydantic's validation features. - Removed unused error handling code and updated tests to reflect changes in validation logic. - Updated GitHub Actions workflow to support Python versions 3.8 through 3.13. - Bumped version to 2.0.0.dev0 in version.py. * Update GitHub Actions workflow to use string format for Python versions * Update GitHub Actions workflow to include Python 3.13 in the testing * Add python version actions (#172) * Add python version actions * Update test.yml * update test deps --------- Co-authored-by: Felipe López <flh.1989@gmail.com> * Upgrade Python version requirements and dependencies - Updated Python version from 3.7 to 3.8 in Makefile and README.md. - Upgraded Pydantic dependency from 1.9.0 to 2.10.3 in requirements.txt and setup.py. - Updated mypy version from 0.790 to 1.13.0 in requirements-test.txt. - Refactored CLABE validation logic in types.py, removing custom error classes and integrating Pydantic's validation features. - Removed unused error handling code and updated tests to reflect changes in validation logic. - Updated GitHub Actions workflow to support Python versions 3.8 through 3.13. - Bumped version to 2.0.0.dev0 in version.py. * Changed regex to pattern in BankConfigRequest model * Update README; bump version to 2.0.0 * Update GitHub Actions workflow to remove Python 3.7 from the testing matrix, supporting versions 3.8 through 3.13. * This change enhances compatibility with Pydantic V2 and streamlines error handling. * Update setup.py to require Python 3.8 and bump version to 2.0.0 * Enhance README with Pydantic v2 usage examples and update CLABE validation logic * Fix code block formatting in README.md for Pydantic example * Removing redundant test case --------- Co-authored-by: gabino <gabino@cuenca.com> Co-authored-by: Pach <arturo@cuenca.com> Co-authored-by: Felipe López <flh.1989@gmail.com>
1 parent e8cbcaa commit 8aea318

File tree

11 files changed

+155
-96
lines changed

11 files changed

+155
-96
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
runs-on: ubuntu-latest
2121
strategy:
2222
matrix:
23-
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
23+
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
2424
steps:
2525
- uses: actions/checkout@v2
2626
- name: Set up Python ${{ matrix.python-version }}

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
SHELL := bash
22
PATH := ./venv/bin:${PATH}
3-
PYTHON = python3.7
3+
PYTHON = python3.8
44
PROJECT = clabe
55
isort = isort $(PROJECT) tests setup.py
66
black = black -S -l 79 --target-version py38 $(PROJECT) tests setup.py

README.md

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ https://es.wikipedia.org/wiki/CLABE
1010

1111
## Requerimientos
1212

13-
Python 3.6 o superior.
13+
Python 3.8 o superior.
1414

1515
## Instalación
1616

@@ -30,48 +30,86 @@ $ make test
3030

3131
## Uso básico
3232

33-
Obtener el dígito de control de un número CLABE
33+
### Como tipo personalizado en un modelo de Pydantic
34+
35+
```python
36+
from pydantic import BaseModel, ValidationError
37+
38+
from clabe import Clabe
39+
40+
41+
class Account(BaseModel):
42+
id: str
43+
clabe: Clabe
44+
45+
46+
account = Account(id='123', clabe='723010123456789019')
47+
print(account)
48+
"""
49+
id='123' clabe='723010123456789019'
50+
"""
51+
52+
try:
53+
account = Account(id='321', clabe='000000000000000011')
54+
except ValidationError as exc:
55+
print(exc)
56+
"""
57+
1 validation error for Account
58+
clabe
59+
código de banco no es válido [type=clabe.bank_code, input_value='000000000000000011', input_type=str]
60+
"""
61+
```
62+
63+
### Obtener el dígito de control de un número CLABE
3464

3565
```python
3666
import clabe
3767
clabe.compute_control_digit('00200000000000000')
3868
```
3969

40-
Para validar si un número CLABE es válido
70+
### Para validar si un número CLABE es válido
4171

4272
```python
4373
import clabe
4474
clabe.validate_clabe('002000000000000008')
4575
```
4676

47-
Para obtener el banco a partir de 3 dígitos
77+
### Para obtener el banco a partir de 3 dígitos
4878

4979
```python
5080
import clabe
5181
clabe.get_bank_name('002')
5282
```
5383

54-
Para generar nuevo válido CLABES
84+
### Para generar nuevo válido CLABES
5585

5686
```python
5787
import clabe
5888
clabe.generate_new_clabes(10, '002123456')
5989
```
6090

61-
## Para agregar un nuevo banco
91+
## Agregar un nuevo banco
92+
93+
A partir de la versión **2.0.0**, el paquete ha sido actualizado para utilizar **Pydantic v2**, lo que implica que las versiones anteriores ya no recibirán soporte ni actualizaciones.
6294

63-
A partir de la versión 2.0.0, el paquete se actualizará a **Pydantic v2**, lo que significa que las versiones anteriores ya no recibirán soporte.
95+
No obstante, en versiones anteriores hemos agregado una función que permite añadir bancos adicionales a la lista sin necesidad de crear un PR. Esto es útil para quienes aún utilicen versiones anteriores. Sin embargo, a partir de la versión 2, continuaremos manteniendo y actualizando la lista oficial de bancos mediante PRs en el repositorio.
6496

65-
Sin embargo, hemos añadido una función para agregar bancos adicionales a la lista, en caso de que sea necesario. Esto se puede hacer sin necesidad de crear un PR. Para agregar un banco, simplemente llama a la siguiente función con el código de Banxico y el nombre del banco:
97+
### Cómo agregar un banco
98+
99+
Para agregar un banco, llama a la función `add_bank` pasando el código de Banxico y el nombre del banco como parámetros.
66100

67101
```python
68102
import clabe
69103
clabe.add_bank('12345', 'New Bank')
70104
```
71105

72-
Para eliminar un banco
106+
### Cómo eliminar un banco
107+
108+
De manera similar, puedes eliminar un banco llamando a la función remove_bank con el código del banco que deseas eliminar.
73109

74110
```python
75111
import clabe
76112
clabe.remove_bank('12345')
77113
```
114+
115+
**Nota**: Aunque estas funciones están disponibles para un uso más flexible, recomendamos utilizar siempre la lista oficial de bancos actualizada en la versión 2+.

clabe/errors.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

clabe/types.py

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,67 @@
1-
from typing import TYPE_CHECKING, ClassVar
1+
from typing import Any, Dict, Type
22

3-
from pydantic.v1.errors import NotDigitError
4-
from pydantic.v1.validators import (
5-
constr_length_validator,
6-
constr_strip_whitespace,
7-
str_validator,
8-
)
3+
from pydantic import GetCoreSchemaHandler, GetJsonSchemaHandler
4+
from pydantic_core import PydanticCustomError, core_schema
95

10-
from .errors import BankCodeValidationError, ClabeControlDigitValidationError
116
from .validations import BANK_NAMES, BANKS, compute_control_digit
127

13-
if TYPE_CHECKING:
14-
from pydantic.v1.typing import CallableGenerator
15-
16-
17-
def validate_digits(v: str) -> str:
18-
if not v.isdigit():
19-
raise NotDigitError
20-
return v
8+
CLABE_LENGTH = 18
219

2210

2311
class Clabe(str):
2412
"""
2513
Based on: https://es.wikipedia.org/wiki/CLABE
2614
"""
2715

28-
strip_whitespace: ClassVar[bool] = True
29-
min_length: ClassVar[int] = 18
30-
max_length: ClassVar[int] = 18
31-
32-
def __init__(self, clabe: str):
16+
def __init__(self, clabe: str) -> None:
3317
self.bank_code_abm = clabe[:3]
3418
self.bank_code_banxico = BANKS[clabe[:3]]
3519
self.bank_name = BANK_NAMES[self.bank_code_banxico]
3620

21+
@property
22+
def bank_code(self) -> str:
23+
return self.bank_code_banxico
24+
3725
@classmethod
38-
def __get_validators__(cls) -> 'CallableGenerator':
39-
yield str_validator
40-
yield constr_strip_whitespace
41-
yield constr_length_validator
42-
yield validate_digits
43-
yield cls.validate_bank_code_abm
44-
yield cls.validate_control_digit
45-
yield cls
26+
def __get_pydantic_json_schema__(
27+
cls,
28+
schema: core_schema.CoreSchema,
29+
handler: GetJsonSchemaHandler,
30+
) -> Dict[str, Any]:
31+
json_schema = handler(schema)
32+
json_schema.update(
33+
type="string",
34+
pattern="^[0-9]{18}$",
35+
description="CLABE (Clave Bancaria Estandarizada)",
36+
examples=["723010123456789019"],
37+
)
38+
return json_schema
4639

4740
@classmethod
48-
def validate_bank_code_abm(cls, clabe: str) -> str:
49-
if clabe[:3] not in BANKS.keys():
50-
raise BankCodeValidationError
51-
return clabe
41+
def __get_pydantic_core_schema__(
42+
cls,
43+
_: Type[Any],
44+
__: GetCoreSchemaHandler,
45+
) -> core_schema.CoreSchema:
46+
return core_schema.no_info_after_validator_function(
47+
cls._validate,
48+
core_schema.str_schema(
49+
min_length=CLABE_LENGTH,
50+
max_length=CLABE_LENGTH,
51+
strip_whitespace=True,
52+
),
53+
)
5254

5355
@classmethod
54-
def validate_control_digit(cls, clabe: str) -> str:
56+
def _validate(cls, clabe: str) -> 'Clabe':
57+
if not clabe.isdigit():
58+
raise PydanticCustomError('clabe', 'debe ser numérico')
59+
if clabe[:3] not in BANKS:
60+
raise PydanticCustomError(
61+
'clabe.bank_code', 'código de banco no es válido'
62+
)
5563
if clabe[-1] != compute_control_digit(clabe):
56-
raise ClabeControlDigitValidationError
57-
return clabe
58-
59-
@property
60-
def bank_code(self):
61-
return self.bank_code_banxico
64+
raise PydanticCustomError(
65+
'clabe.control_digit', 'clabe dígito de control no es válido'
66+
)
67+
return cls(clabe)

clabe/validations.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ class BankConfigRequest(BaseModel):
8181
)
8282

8383
bank_code_banxico: str = Field(
84-
regex=r"^\d{5}$", description="Banxico code must be a 5-digit string."
84+
pattern=r"^\d{5}$",
85+
description="Banxico code must be a 5-digit string.",
8586
)
8687

8788
@property

clabe/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.3.0'
1+
__version__ = '2.0.0'

requirements-test.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ pytest-cov==4.1.0
33
black==22.8.0
44
isort==5.11.5
55
flake8==5.0.4
6-
mypy==1.4.1
6+
mypy==1.4.1

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
pydantic==1.10.19
1+
pydantic==2.10.3

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
packages=setuptools.find_packages(),
2222
include_package_data=True,
2323
package_data=dict(clabe=['py.typed']),
24-
install_requires=['pydantic>=1.10.17'],
24+
python_requires='>=3.8',
25+
install_requires=['pydantic>=2.10.3'],
2526
classifiers=[
2627
'Programming Language :: Python :: 3',
2728
'License :: OSI Approved :: MIT License',

0 commit comments

Comments
 (0)