Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.41.0
current_version = 0.42.0
commit = True
tag = False
message = chore: Bump version from {current_version} to {new_version}
Expand Down
7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# History

## 0.42.0 (2025-01-28)

- (PR #758, 2025-01-15) Enable `warn_unused_ignores` in Mypy configuration
- (PR #759, 2025-01-28) Annotate method return types with `typing.Self` where appropriate
- (PR #761, 2025-01-28) deps: Increase minimum version of Python package `Django` to 4.2
- (PR #760, 2025-01-28) rut: Add constant with lowest RUT for personas jurídicas

## 0.41.0 (2025-01-08)

- (PR #753, 2025-01-08) Exclude only individual test files in Mypy configuration
Expand Down
1 change: 1 addition & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ strict_optional = True
disallow_untyped_defs = True
check_untyped_defs = True
warn_return_any = True
warn_unused_ignores = True

show_column_numbers = True
show_error_codes = True
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies = [
"pyOpenSSL>=24.0.0",
"pytz>=2019.3",
"signxml>=4.0.0",
"typing-extensions>=4.0.1",
]
requires-python = ">=3.8, <3.11"
authors = [
Expand All @@ -49,7 +50,7 @@ classifiers = [
dynamic = ["version"]

[project.optional-dependencies]
django = ["Django>=2.2.24"]
django = ["Django>=4.2"]
django-filter = ["django-filter>=24.2"]
djangorestframework = ["djangorestframework>=3.10.3,<3.16"]
pydantic = ["pydantic>=2.0"]
Expand Down
3 changes: 2 additions & 1 deletion requirements.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ backports-zoneinfo==0.2.1 ; python_version < "3.9" # Used by `djangorestframewor
cryptography==44.0.0
defusedxml==0.7.1
django-filter>=24.2
Django>=2.2.24
Django>=4.2
djangorestframework>=3.10.3,<3.16
importlib-metadata==8.5.0
jsonschema==4.23.0
Expand All @@ -19,3 +19,4 @@ pydantic==2.10.4
pyOpenSSL==24.3.0
pytz==2024.2
signxml==4.0.3
typing-extensions==4.12.2
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ cryptography==44.0.0
# signxml
defusedxml==0.7.1
# via -r requirements.in
django==4.2.17
django==4.2.18
# via
# -r requirements.in
# django-filter
Expand Down Expand Up @@ -81,6 +81,7 @@ sqlparse==0.5.0
# via django
typing-extensions==4.12.2
# via
# -r requirements.in
# annotated-types
# asgiref
# pydantic
Expand Down
2 changes: 1 addition & 1 deletion src/cl_sii/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

"""

__version__ = '0.41.0'
__version__ = '0.42.0'
7 changes: 4 additions & 3 deletions src/cl_sii/dte/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from typing import Mapping, Optional, Sequence

import pydantic
from typing_extensions import Self

import cl_sii.contribuyente.constants
import cl_sii.rut.constants
Expand Down Expand Up @@ -854,7 +855,7 @@ def validate_referencias_numero_linea_ref_order(cls, v: object) -> object:
@pydantic.model_validator(mode='after')
def validate_referencias_rut_otro_is_consistent_with_tipo_dte(
self, info: pydantic.ValidationInfo
) -> DteXmlData:
) -> Self:
referencias = self.referencias
tipo_dte = self.tipo_dte

Expand All @@ -880,7 +881,7 @@ def validate_referencias_rut_otro_is_consistent_with_tipo_dte(
@pydantic.model_validator(mode='after')
def validate_referencias_rut_otro_is_consistent_with_emisor_rut(
self, info: pydantic.ValidationInfo
) -> DteXmlData:
) -> Self:
referencias = self.referencias
emisor_rut = self.emisor_rut

Expand All @@ -900,7 +901,7 @@ def validate_referencias_rut_otro_is_consistent_with_emisor_rut(
return self

@pydantic.model_validator(mode='after')
def validate_referencias_codigo_ref_is_consistent_with_tipo_dte(self) -> DteXmlData:
def validate_referencias_codigo_ref_is_consistent_with_tipo_dte(self) -> Self:
referencias = self.referencias
tipo_dte = self.tipo_dte

Expand Down
2 changes: 1 addition & 1 deletion src/cl_sii/extras/mm_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,6 @@ def _validated(self, value: Optional[object]) -> Optional[RcvPeriodoTributario]:
except TypeError as exc:
raise self.make_error('type') from exc

validated = RcvPeriodoTributario.from_date(value) # type: ignore
validated = RcvPeriodoTributario.from_date(value)

return validated
6 changes: 1 addition & 5 deletions src/cl_sii/libs/rows_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ def csv_rows_mm_deserialization_iterator(
on CSV error when iterating over ``csv_reader``

"""
# note: mypy complaint is wrong because a 'csv.DictReader' object can be iterated over
# and yields instances of 'Dict[str, object]'.
# > Incompatible types in assignment (expression has type "DictReader", variable has type
# > "Iterable[Dict[str, object]]")
rows_iterator: Iterable[Dict[str, object]] = csv_reader # type: ignore
rows_iterator: Iterable[Dict[str, object]] = csv_reader
iterator = rows_mm_deserialization_iterator(
rows_iterator, row_schema, n_rows_offset, max_n_rows, fields_to_remove_names
)
Expand Down
2 changes: 1 addition & 1 deletion src/cl_sii/libs/tz_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
pytz.tzinfo.BaseTzInfo,
pytz.tzinfo.StaticTzInfo,
pytz.tzinfo.DstTzInfo,
pytz._FixedOffset, # type: ignore
pytz._FixedOffset,
]


Expand Down
3 changes: 2 additions & 1 deletion src/cl_sii/rcv/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from typing import ClassVar, Optional

import pydantic
from typing_extensions import Self

import cl_sii.dte.data_models
from cl_sii.base.constants import SII_OFFICIAL_TZ
Expand Down Expand Up @@ -174,7 +175,7 @@ def validate_datetime_tz(cls, v: object) -> object:
return v

@pydantic.model_validator(mode='after')
def validate_rcv_kind_is_consistent_with_rc_estado_contable(self) -> RcvDetalleEntry:
def validate_rcv_kind_is_consistent_with_rc_estado_contable(self) -> Self:
rcv_kind = self.RCV_KIND
rc_estado_contable = self.RC_ESTADO_CONTABLE

Expand Down
90 changes: 45 additions & 45 deletions src/cl_sii/rcv/parse_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,16 +633,16 @@ def postprocess(self, data: dict, **kwargs: Any) -> dict:

def to_detalle_entry(self, data: dict) -> RvDetalleEntry:
try:
emisor_rut: Rut = data['emisor_rut'] # type: ignore
tipo_docto = data['tipo_docto'] # type: ignore
folio: int = data['folio'] # type: ignore
fecha_emision_date: date = data['fecha_emision_date'] # type: ignore
receptor_rut: Rut = data['receptor_rut'] # type: ignore
monto_total: int = data['monto_total'] # type: ignore
receptor_razon_social: str = data['receptor_razon_social'] # type: ignore
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt'] # type: ignore
fecha_acuse_dt: Optional[datetime] = data['fecha_acuse_dt'] # type: ignore
fecha_reclamo_dt: Optional[datetime] = data['fecha_reclamo_dt'] # type: ignore
emisor_rut: Rut = data['emisor_rut']
tipo_docto = data['tipo_docto']
folio: int = data['folio']
fecha_emision_date: date = data['fecha_emision_date']
receptor_rut: Rut = data['receptor_rut']
monto_total: int = data['monto_total']
receptor_razon_social: str = data['receptor_razon_social']
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt']
fecha_acuse_dt: Optional[datetime] = data['fecha_acuse_dt']
fecha_reclamo_dt: Optional[datetime] = data['fecha_reclamo_dt']
except KeyError as exc:
raise ValueError("Programming error: a referenced field is missing.") from exc

Expand Down Expand Up @@ -765,15 +765,15 @@ def postprocess(self, data: dict, **kwargs: Any) -> dict:

def to_detalle_entry(self, data: dict) -> RcRegistroDetalleEntry:
try:
emisor_rut: Rut = data['emisor_rut'] # type: ignore
tipo_docto = data['tipo_docto'] # type: ignore
folio: int = data['folio'] # type: ignore
fecha_emision_date: date = data['fecha_emision_date'] # type: ignore
receptor_rut: Rut = data['receptor_rut'] # type: ignore
monto_total: int = data['monto_total'] # type: ignore
emisor_razon_social: str = data['emisor_razon_social'] # type: ignore
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt'] # type: ignore
fecha_acuse_dt: Optional[datetime] = data['fecha_acuse_dt'] # type: ignore
emisor_rut: Rut = data['emisor_rut']
tipo_docto = data['tipo_docto']
folio: int = data['folio']
fecha_emision_date: date = data['fecha_emision_date']
receptor_rut: Rut = data['receptor_rut']
monto_total: int = data['monto_total']
emisor_razon_social: str = data['emisor_razon_social']
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt']
fecha_acuse_dt: Optional[datetime] = data['fecha_acuse_dt']
except KeyError as exc:
raise ValueError("Programming error: a referenced field is missing.") from exc

Expand All @@ -798,15 +798,15 @@ def to_detalle_entry(self, data: dict) -> RcRegistroDetalleEntry:
class RcvCompraNoIncluirCsvRowSchema(RcvCompraRegistroCsvRowSchema):
def to_detalle_entry(self, data: dict) -> RcNoIncluirDetalleEntry:
try:
emisor_rut: Rut = data['emisor_rut'] # type: ignore
tipo_docto = data['tipo_docto'] # type: ignore
folio: int = data['folio'] # type: ignore
fecha_emision_date: date = data['fecha_emision_date'] # type: ignore
receptor_rut: Rut = data['receptor_rut'] # type: ignore
monto_total: int = data['monto_total'] # type: ignore
emisor_razon_social: str = data['emisor_razon_social'] # type: ignore
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt'] # type: ignore
fecha_acuse_dt: Optional[datetime] = data['fecha_acuse_dt'] # type: ignore
emisor_rut: Rut = data['emisor_rut']
tipo_docto = data['tipo_docto']
folio: int = data['folio']
fecha_emision_date: date = data['fecha_emision_date']
receptor_rut: Rut = data['receptor_rut']
monto_total: int = data['monto_total']
emisor_razon_social: str = data['emisor_razon_social']
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt']
fecha_acuse_dt: Optional[datetime] = data['fecha_acuse_dt']
except KeyError as exc:
raise ValueError("Programming error: a referenced field is missing.") from exc

Expand Down Expand Up @@ -934,15 +934,15 @@ def postprocess(self, data: dict, **kwargs: Any) -> dict:

def to_detalle_entry(self, data: dict) -> RcReclamadoDetalleEntry:
try:
emisor_rut: Rut = data['emisor_rut'] # type: ignore
tipo_docto = data['tipo_docto'] # type: ignore
folio: int = data['folio'] # type: ignore
fecha_emision_date: date = data['fecha_emision_date'] # type: ignore
receptor_rut: Rut = data['receptor_rut'] # type: ignore
monto_total: int = data['monto_total'] # type: ignore
emisor_razon_social: str = data['emisor_razon_social'] # type: ignore
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt'] # type: ignore
fecha_reclamo_dt: Optional[datetime] = data['fecha_reclamo_dt'] # type: ignore
emisor_rut: Rut = data['emisor_rut']
tipo_docto = data['tipo_docto']
folio: int = data['folio']
fecha_emision_date: date = data['fecha_emision_date']
receptor_rut: Rut = data['receptor_rut']
monto_total: int = data['monto_total']
emisor_razon_social: str = data['emisor_razon_social']
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt']
fecha_reclamo_dt: Optional[datetime] = data['fecha_reclamo_dt']
except KeyError as exc:
raise ValueError("Programming error: a referenced field is missing.") from exc

Expand Down Expand Up @@ -1053,14 +1053,14 @@ def postprocess(self, data: dict, **kwargs: Any) -> dict:

def to_detalle_entry(self, data: dict) -> RcPendienteDetalleEntry:
try:
emisor_rut: Rut = data['emisor_rut'] # type: ignore
tipo_docto = data['tipo_docto'] # type: ignore
folio: int = data['folio'] # type: ignore
fecha_emision_date: date = data['fecha_emision_date'] # type: ignore
receptor_rut: Rut = data['receptor_rut'] # type: ignore
monto_total: int = data['monto_total'] # type: ignore
emisor_razon_social: str = data['emisor_razon_social'] # type: ignore
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt'] # type: ignore
emisor_rut: Rut = data['emisor_rut']
tipo_docto = data['tipo_docto']
folio: int = data['folio']
fecha_emision_date: date = data['fecha_emision_date']
receptor_rut: Rut = data['receptor_rut']
monto_total: int = data['monto_total']
emisor_razon_social: str = data['emisor_razon_social']
fecha_recepcion_dt: datetime = data['fecha_recepcion_dt']
except KeyError as exc:
raise ValueError("Programming error: a referenced field is missing.") from exc

Expand Down
5 changes: 3 additions & 2 deletions src/cl_sii/rtc/data_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from typing import ClassVar, Mapping, Optional

import pydantic
from typing_extensions import Self

from cl_sii.base.constants import SII_OFFICIAL_TZ
from cl_sii.dte import data_models as dte_data_models
Expand Down Expand Up @@ -508,7 +509,7 @@ def validate_monto_cedido(cls, v: object) -> object:
return v

@pydantic.model_validator(mode='after')
def validate_monto_cedido_does_not_exceed_dte_monto_total(self) -> CesionL1:
def validate_monto_cedido_does_not_exceed_dte_monto_total(self) -> Self:
monto_cedido = self.monto_cedido
dte_monto_total = self.dte_monto_total

Expand Down Expand Up @@ -705,7 +706,7 @@ def validate_contribuyente_razon_social(cls, v: object) -> object:
return v

@pydantic.model_validator(mode='after')
def validate_dte_data_l2(self) -> CesionL2:
def validate_dte_data_l2(self) -> Self:
dte_key = self.dte_key
try:
# Note: Delegate some validation to 'dte_data_models.DteDataL2'.
Expand Down
13 changes: 7 additions & 6 deletions src/cl_sii/rtc/data_models_aec.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from typing import ClassVar, Mapping, Optional, Sequence, Tuple

import pydantic
from typing_extensions import Self

from cl_sii.base.constants import SII_OFFICIAL_TZ
from cl_sii.dte import data_models as dte_data_models
Expand Down Expand Up @@ -342,7 +343,7 @@ def validate_datetime_tz(cls, v: object) -> object:
return v

@pydantic.model_validator(mode='after')
def validate_fecha_cesion_dt_is_consistent_with_dte(self) -> CesionAecXml:
def validate_fecha_cesion_dt_is_consistent_with_dte(self) -> Self:
fecha_cesion_dt = self.fecha_cesion_dt
dte = self.dte

Expand All @@ -352,7 +353,7 @@ def validate_fecha_cesion_dt_is_consistent_with_dte(self) -> CesionAecXml:
return self

@pydantic.model_validator(mode='after')
def validate_monto_cesion_does_not_exceed_dte_monto_total(self) -> CesionAecXml:
def validate_monto_cesion_does_not_exceed_dte_monto_total(self) -> Self:
monto_cesion = self.monto_cesion
dte = self.dte

Expand All @@ -365,7 +366,7 @@ def validate_monto_cesion_does_not_exceed_dte_monto_total(self) -> CesionAecXml:
return self

@pydantic.model_validator(mode='after')
def validate_fecha_ultimo_vencimiento_is_consistent_with_dte(self) -> CesionAecXml:
def validate_fecha_ultimo_vencimiento_is_consistent_with_dte(self) -> Self:
fecha_ultimo_vencimiento = self.fecha_ultimo_vencimiento
dte = self.dte

Expand Down Expand Up @@ -732,7 +733,7 @@ def validate_cesiones_seq_order(cls, v: object) -> object:
# return v

@pydantic.model_validator(mode='after')
def validate_dte_matches_cesiones_dtes(self) -> AecXml:
def validate_dte_matches_cesiones_dtes(self) -> Self:
dte = self.dte
cesiones = self.cesiones

Expand All @@ -751,7 +752,7 @@ def validate_dte_matches_cesiones_dtes(self) -> AecXml:
return self

@pydantic.model_validator(mode='after')
def validate_last_cesion_matches_some_fields(self) -> AecXml:
def validate_last_cesion_matches_some_fields(self) -> Self:
field_validations: Sequence[Tuple[str, str]] = [
# (AecXml field, CesionAecXml field):
# Even though it seems reasonable to expect that the date in `fecha_firma_dt`
Expand Down Expand Up @@ -784,7 +785,7 @@ def validate_last_cesion_matches_some_fields(self) -> AecXml:
@pydantic.model_validator(mode='after')
def validate_signature_value_and_signature_x509_cert_der_may_only_be_none_together(
self,
) -> AecXml:
) -> Self:
signature_value = self.signature_value
signature_x509_cert_der = self.signature_x509_cert_der

Expand Down
Loading