aeat.core._irnr module¶
Closed value sets for the IRNR (non-resident income tax) treaty surface.
Two closed axes governing the Modelo 210 IRNR rate-resolution path — and,
by design, every future IRNR consumer (M216 retenciones a no residentes) —
are declared here as enum.StrEnum per the core-authority discipline
(closed axes live in core/, hydrated at boundaries, asserted as members in
tests, surfaced as click Choice at the CLI):
TipoRentaIrnr— the income-type axis an IRNR filer tags each item with. It keys the TRLIRNR baseline rate table, the treaty override rows, and the Art. 25.1.b pension tariff branch. It was previously a free-text casilla value with no enum home, which forced adjacent verification work to route a categorical-equality predicate around the untyped axis.ConvenioOverrideKind— how a bilateral double-taxation treaty (Convenio para evitar la doble imposición, CDI) override acts on the domestic rate. Making the kind typed data turns “más favorable” / limitation-of-benefits from a numeric coincidence (a flat treaty rate that happens to be lower than the domestic baseline) into a computable decision.
Both enums are consumed by the cross-cutting registry/aeat/treaties/ authoring
tree and its ConvenioAuthority
projection. The registry TOML stays free-form (a plain string token); the loader
hydrates the enum at the boundary.
- class TipoRentaIrnr(*values)[source]¶
Bases:
StrEnumThe IRNR income-type axis (TRLIRNR RDLeg 5/2004 arts. 24-25).
Each member’s value is the byte-identical token stored in the registry
tipo_rentacasilla and used as the lookup key for the baseline rate table (m210-tipo-gravamen-2025), the treaty override rows, and the Art. 25.1.b pension tariff branch. The value set is closed by the TRLIRNR rate schedule; a new income category is added here first.- Members:
GENERAL: Art. 25.1.a general non-resident rate (24%).
UE_RESIDENTE: Art. 25.1.a reduced rate for EU/EEA residents (19%).
PENSION: Art. 25.1.b progressive pension tariff (bracket table).
- DIVIDEND: Art. 25.1.f.1º dividends / other income from participation
in an entity’s own funds (19%).
INTEREST: Art. 25.1.f.2º interest / capital-cession income (19%).
GANANCIA_PATRIMONIAL: Art. 25.1.f.3º capital gains (19%).
- INMOBILIARIA: Art. 13.1.h imputed urban real-estate income (the source
article), taxed at the Art. 25.1.a general 24% rate.
- CANONES: Art. 25.1.a cánones (royalties). The consolidated Art. 25.1
carries no cánones-specific letter, so royalties are taxed at the general rendimiento rate (24%, or the Art. 25.1.a reduced 19% for EU/EEA residents). Bilateral treaties routinely cap or exempt the source-state cánones rate via their Art. 12.
- GENERAL¶
- UE_RESIDENTE¶
- PENSION¶
- DIVIDEND¶
- INTEREST¶
- GANANCIA_PATRIMONIAL¶
- INMOBILIARIA¶
- CANONES¶
- class ConvenioOverrideKind(*values)[source]¶
Bases:
StrEnumHow a double-taxation treaty override acts on the domestic IRNR rate.
The override is one branch of the single tipo-de-gravamen resolution path, not a second resolver. On a matched treaty override row the resolver applies the kind:
- Members:
FLAT: The treaty rate REPLACES the domestic baseline outright.
- CEILING: The treaty caps the source-state rate (“may not exceed X%”);
the resolver applies
min(domestic, treaty)so the “más favorable” outcome is computed rather than assumed.- ALLOCATION_DOMESTIC_TARIFF: The treaty allocates taxation to Spain but
fixes no rate; the amount is delegated to the domestic tariff (e.g. the Art. 25.1.b progressive pension tariff). Rows of this kind carry no
rate.- EXEMPT: The source state may not tax the income; the resolver yields a
zero rate. Rows of this kind carry no
rate.
- FLAT¶
- CEILING¶
- ALLOCATION_DOMESTIC_TARIFF¶
- EXEMPT¶
- property carries_rate: bool¶
True when a row of this kind MUST declare a numeric
rate.FLATandCEILINGoperate on a treaty rate;ALLOCATION_DOMESTIC_TARIFFandEXEMPTdo not (the amount is delegated to the domestic tariff or driven to zero). Consumed by the treaty-row validator so a malformed row (a rate on an exempt override, or a missing rate on a ceiling) fails at registry-build time.
- class TipoRentaGroundingTier(*values)[source]¶
Bases:
StrEnumHow firmly the bundled corpus grounds an official code’s rate concept.
The official Modelo 210 tipo-de-renta code axis (Orden EHA/3316/2010, “HOJA INFORMATIVA 210 - TIPOS DE RENTA”) is a numeric code list, but the rate each code bears is only bundled-verifiable for the codes whose rate concept is named by a bundled TRLIRNR Art. 25 letter (the shipped corpus is a Phase-1 extract carrying Art. 25 letters a, b, and f only; the special-rate letters c/d/e/g/h are absent). This tier records, per declared code, how its
TipoRentaIrnrrate concept is grounded:- Members:
- RATE_VERIFIED: The rate concept is explicitly modelled by the bundled
corpus — a bundled Art. 25 special letter that names the income (25.1.b pensions, 25.1.f dividends / interest / capital gains) or a dedicated bundled mechanism (Art. 13.1.h imputed real-estate).
- RESIDUAL: The code is an ordinary rendimiento with no special regime,
mapped to
TipoRentaIrnr.GENERALon the Art. 25.1.a “con carácter general, el 24 por ciento” residual clause. A later fetch of the full consolidated Art. 25 that reveals a special rate for such a code is a CORRECTION of this row, never a contradiction of its grounding.
- RATE_VERIFIED¶
- RESIDUAL¶
- class OfficialTipoRentaCode(code, concept, rate_legal_ref, grounding_tier)[source]¶
Bases:
objectOne official Modelo 210 tipo-de-renta code and its rate projection.
The operator enters the two-digit official code the form asks for; the engine keeps
TipoRentaIrnras its rate key. This record is the single projection from the official code to that conceptual key, carried with the grounding that justifies the mapping. The official codes are many-to-one onto the rate concepts (every ordinary rendimiento folds intogeneral), which is why the code axis is declared alongside — not in place of — the conceptual enum.- Variables:
code – The two-digit official code, byte-identical to the “Tipo” column of the bundled HOJA INFORMATIVA 210 (Orden EHA/3316/2010).
concept – The
TipoRentaIrnrrate concept the code folds into.rate_legal_ref – The legal-catalogue id (a TRLIRNR article) that establishes the concept’s rate for this code. The load-bearing grounding is registry-resident: the
m210-tipo-renta-code-2025parameter carries thelegal_refsthe canonical registry legal-grounding gate validates against the bundled corpus.grounding_tier – Whether the rate concept is directly rate-verified from the bundled corpus or rests on the Art. 25.1.a residual clause.
- Parameters:
code (str)
concept (TipoRentaIrnr)
rate_legal_ref (str)
grounding_tier (TipoRentaGroundingTier)
-
concept:
TipoRentaIrnr¶
-
grounding_tier:
TipoRentaGroundingTier¶
- M210_TIPO_RENTA_CODE_PROJECTION: MappingProxyType¶
Read-only official-code →
TipoRentaIrnrprojection.Derived from
OFFICIAL_M210_TIPO_RENTA_CODES; the single mapping the CLI hydrates to resolve an operator-entered official code to its rate concept. Keys are the byte-identical two-digit official codes; values are the rate concept the engine dispatches on. The registry-build parity gate (validate_m210_tipo_renta_code_projection_parity) cross-checks this projection against the registry-declaredm210-tipo-renta-code-2025code set in both directions, so a declared code without a projection — or a projected code the registry does not declare — fails the build.
- project_m210_tipo_renta_code(code)[source]¶
Project an official Modelo 210 tipo-de-renta
codeto its rate concept.- Parameters:
code (
str) – A two-digit official code from the HOJA INFORMATIVA 210.- Return type:
- Returns:
The
TipoRentaIrnrrate concept the code folds into.- Raises:
KeyError – When
codeis not a declared, rate-grounded official code. A fetch-gated code (whose rate is not yet bundle-verifiable) raises here rather than resolving to a fabricated rate.