From ce56b94e87d9ecd1cd9412095397b325b9109dbf Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Wed, 15 Jan 2025 19:17:32 -0300 Subject: [PATCH 1/8] chore: Enable `warn_unused_ignores` in Mypy configuration --- mypy.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy.ini b/mypy.ini index e3ec935c..e9b6d932 100644 --- a/mypy.ini +++ b/mypy.ini @@ -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 From ddd37aa28d05d50fa64be474c0f9fec5ad9d0b42 Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Wed, 15 Jan 2025 19:19:32 -0300 Subject: [PATCH 2/8] fix: Remove unused type checking ignore directives Some `type: ignore` comments have stopped being necessary, so we remove them. --- src/cl_sii/extras/mm_fields.py | 2 +- src/cl_sii/libs/rows_processing.py | 6 +- src/cl_sii/libs/tz_utils.py | 2 +- src/cl_sii/rcv/parse_csv.py | 90 +++++++++++++++--------------- src/cl_sii/rtc/parse_aec.py | 16 +++--- 5 files changed, 56 insertions(+), 60 deletions(-) diff --git a/src/cl_sii/extras/mm_fields.py b/src/cl_sii/extras/mm_fields.py index dfb2de42..a101e2fc 100644 --- a/src/cl_sii/extras/mm_fields.py +++ b/src/cl_sii/extras/mm_fields.py @@ -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 diff --git a/src/cl_sii/libs/rows_processing.py b/src/cl_sii/libs/rows_processing.py index fc9fda90..86ff99c6 100644 --- a/src/cl_sii/libs/rows_processing.py +++ b/src/cl_sii/libs/rows_processing.py @@ -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 ) diff --git a/src/cl_sii/libs/tz_utils.py b/src/cl_sii/libs/tz_utils.py index a64f5d98..fc7ead55 100644 --- a/src/cl_sii/libs/tz_utils.py +++ b/src/cl_sii/libs/tz_utils.py @@ -23,7 +23,7 @@ pytz.tzinfo.BaseTzInfo, pytz.tzinfo.StaticTzInfo, pytz.tzinfo.DstTzInfo, - pytz._FixedOffset, # type: ignore + pytz._FixedOffset, ] diff --git a/src/cl_sii/rcv/parse_csv.py b/src/cl_sii/rcv/parse_csv.py index e5e2a7b7..8a5d6d08 100644 --- a/src/cl_sii/rcv/parse_csv.py +++ b/src/cl_sii/rcv/parse_csv.py @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/src/cl_sii/rtc/parse_aec.py b/src/cl_sii/rtc/parse_aec.py index ffbdc65e..81e406cc 100644 --- a/src/cl_sii/rtc/parse_aec.py +++ b/src/cl_sii/rtc/parse_aec.py @@ -236,7 +236,7 @@ def parse_xml_to_dict(xml_em: XmlElement) -> Mapping[str, object]: # Validators ########################################################################### - _validate_rut = pydantic.field_validator( # type: ignore[pydantic-field] + _validate_rut = pydantic.field_validator( 'rut', mode='before', )(_validate_rut) @@ -281,12 +281,12 @@ def parse_xml_to_dict(xml_em: XmlElement) -> Mapping[str, object]: # Validators ########################################################################### - _empty_str_to_none = pydantic.field_validator( # type: ignore[pydantic-field] + _empty_str_to_none = pydantic.field_validator( 'nombre', mode='before', )(_empty_str_to_none) - _validate_rut = pydantic.field_validator( # type: ignore[pydantic-field] + _validate_rut = pydantic.field_validator( 'rut', mode='before', )(_validate_rut) @@ -425,12 +425,12 @@ def as_dte_data_l1(self) -> cl_sii.dte.data_models.DteDataL1: # Validators ########################################################################### - _validate_rut_emisor = pydantic.field_validator( # type: ignore[pydantic-field] + _validate_rut_emisor = pydantic.field_validator( 'rut_emisor', mode='before', )(_validate_rut) - _validate_rut_receptor = pydantic.field_validator( # type: ignore[pydantic-field] + _validate_rut_receptor = pydantic.field_validator( 'rut_receptor', mode='before', )(_validate_rut) @@ -776,19 +776,19 @@ def parse_xml_to_dict(xml_em: XmlElement) -> Mapping[str, object]: # Validators ########################################################################### - _empty_str_to_none = pydantic.field_validator( # type: ignore[pydantic-field] + _empty_str_to_none = pydantic.field_validator( 'nmb_contacto', 'fono_contacto', 'mail_contacto', mode='before', )(_empty_str_to_none) - _validate_rut_cedente = pydantic.field_validator( # type: ignore[pydantic-field] + _validate_rut_cedente = pydantic.field_validator( 'rut_cedente', mode='before', )(_validate_rut) - _validate_rut_cesionario = pydantic.field_validator( # type: ignore[pydantic-field] + _validate_rut_cesionario = pydantic.field_validator( 'rut_cesionario', mode='before', )(_validate_rut) From 9700228141ed6393f3945b23f6e0e6d22e00b200 Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Mon, 27 Jan 2025 19:20:13 -0300 Subject: [PATCH 3/8] chore(deps): Install Python package `typing-extensions` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > The `typing_extensions` module serves two related purposes: > > - Enable use of new type system features on older Python versions. […] > - Enable experimentation with new type system PEPs before they are > accepted and added to the `typing` module. - [Web Site](https://github.com/python/typing_extensions) - [VCS Repository](https://github.com/python/typing_extensions.git) - [Documentation](https://typing-extensions.readthedocs.io/) - [Software Repository](https://pypi.org/project/typing-extensions/) --- pyproject.toml | 1 + requirements.in | 1 + requirements.txt | 1 + 3 files changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index b7961f89..2f9ee178 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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 = [ diff --git a/requirements.in b/requirements.in index 809cd12d..3161a3f3 100644 --- a/requirements.in +++ b/requirements.in @@ -19,3 +19,4 @@ pydantic==2.10.4 pyOpenSSL==24.3.0 pytz==2024.2 signxml==4.0.3 +typing-extensions==4.12.2 diff --git a/requirements.txt b/requirements.txt index f1082336..69b4e98c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -81,6 +81,7 @@ sqlparse==0.5.0 # via django typing-extensions==4.12.2 # via + # -r requirements.in # annotated-types # asgiref # pydantic From c89f7e07c7998bd847ef2e642bd190128ad679e5 Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Mon, 27 Jan 2025 19:24:28 -0300 Subject: [PATCH 4/8] chore: Annotate method return types with `typing.Self` where appropriate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > In general, if something returns `self`, […], you should use `Self` as > the return annotation. > You should not use `Self` as the return annotation if the method is > not guaranteed to return an instance of a subclass when the class is > subclassed […] --- src/cl_sii/dte/data_models.py | 7 ++++--- src/cl_sii/rcv/data_models.py | 3 ++- src/cl_sii/rtc/data_models.py | 5 +++-- src/cl_sii/rtc/data_models_aec.py | 13 +++++++------ 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/cl_sii/dte/data_models.py b/src/cl_sii/dte/data_models.py index 673bf92c..aca2aaa8 100644 --- a/src/cl_sii/dte/data_models.py +++ b/src/cl_sii/dte/data_models.py @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/src/cl_sii/rcv/data_models.py b/src/cl_sii/rcv/data_models.py index f9fc3b3b..0278e312 100644 --- a/src/cl_sii/rcv/data_models.py +++ b/src/cl_sii/rcv/data_models.py @@ -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 @@ -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 diff --git a/src/cl_sii/rtc/data_models.py b/src/cl_sii/rtc/data_models.py index 9ef42bd4..3342a299 100644 --- a/src/cl_sii/rtc/data_models.py +++ b/src/cl_sii/rtc/data_models.py @@ -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 @@ -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 @@ -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'. diff --git a/src/cl_sii/rtc/data_models_aec.py b/src/cl_sii/rtc/data_models_aec.py index 94481e57..643d5992 100644 --- a/src/cl_sii/rtc/data_models_aec.py +++ b/src/cl_sii/rtc/data_models_aec.py @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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` @@ -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 From 73ba1683c5d0cdd65d2fa2727590cbf0b928bc56 Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Tue, 28 Jan 2025 13:45:11 -0300 Subject: [PATCH 5/8] chore(deps): Increase minimum version of Python package `Django` to 4.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update constraint for optional dependency `Django` from ≥ 2.2.24 to ≥ 4.2 to prevent compatibility issues. --- pyproject.toml | 2 +- requirements.in | 2 +- requirements.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2f9ee178..6938fcb7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,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"] diff --git a/requirements.in b/requirements.in index 3161a3f3..a3aa5c4c 100644 --- a/requirements.in +++ b/requirements.in @@ -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 diff --git a/requirements.txt b/requirements.txt index 69b4e98c..4d7c201a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 From 50f379097fdf788557b37f4f35c8d0bd32766d5a Mon Sep 17 00:00:00 2001 From: Jose Tomas Robles Hahn Date: Tue, 28 Jan 2025 11:27:44 -0300 Subject: [PATCH 6/8] =?UTF-8?q?feat(rut):=20Add=20constant=20with=20lowest?= =?UTF-8?q?=20RUT=20for=20personas=20jur=C3=ADdicas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cl_sii/rut/constants.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/cl_sii/rut/constants.py b/src/cl_sii/rut/constants.py index b8adb364..7bd4cef8 100644 --- a/src/cl_sii/rut/constants.py +++ b/src/cl_sii/rut/constants.py @@ -40,3 +40,18 @@ # Type-id = 1.3.6.1.4.1.8321.1 # Value ='xx.xxx.xx-v' # > El campo Value es un IA5String con el RUT del individuo titular del certificado. + +PERSONA_JURIDICA_MIN_RUT_DIGITS: int = 50000000 +""" +Lowest RUT digits for “personas jurídicas”. +""" +# Why must “personas jurídicas” have RUT ≥ 50000000-7? +# +# > ¿Qué es una Persona Jurídica? +# > +# > […] persona ficticia, capaz de ejercer derechos y contraer obligaciones civiles, y de ser +# > representada judicial y extrajudicialmente. Además de esto, poseen Rut sobre 50 millones. +# +# Source: +# [BancoEstado Microempresas → Información general sobre personas jurídicas](https://www.bancoestado.cl/content/bancoestado-public/cl/es/home/home-microempresa/servicios/informacion-general-sobre-personas-juridicas---bancoestado-micro.html#/) # noqa: E501 +# (retrieved on 2025-01-28) From 7ed0717ab3f89fb48a6410dbeecc0e283e1d9f27 Mon Sep 17 00:00:00 2001 From: Felipe Pinto Date: Tue, 28 Jan 2025 15:51:52 -0300 Subject: [PATCH 7/8] chore: Update history for new version --- HISTORY.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index e63022db..dc7bab8d 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -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 From 7dd87a9415445cc8756cc58d809257784d9844e0 Mon Sep 17 00:00:00 2001 From: Felipe Pinto Date: Tue, 28 Jan 2025 15:52:15 -0300 Subject: [PATCH 8/8] chore: Bump version from 0.41.0 to 0.42.0 --- .bumpversion.cfg | 2 +- src/cl_sii/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index d0989fd4..84eb193e 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -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} diff --git a/src/cl_sii/__init__.py b/src/cl_sii/__init__.py index 89c02ee8..32c7673e 100644 --- a/src/cl_sii/__init__.py +++ b/src/cl_sii/__init__.py @@ -4,4 +4,4 @@ """ -__version__ = '0.41.0' +__version__ = '0.42.0'