"""The Spanish postcode shape, declared once.A postcode is five digits whose first two are a province code from 01 to 52.It is a STRING throughout and must never be int-coerced: leading zeros aresignificant, and ``01001`` is Vitoria-Gasteiz while ``1001`` is nothing.The rule was enforced in exactly one place -- the setup wizard, and only forquestions whose id said "postcode". The profile field the wizard writes intocarried no constraint at all, so any other route to it (a bulk import, a directprofile mutation, a future API) could persist a malformed value with norefusal. A rule that lives at one entrance is not a rule about the data.It was also, at the same time, enforced DIFFERENTLY elsewhere: the registryscalar boundary took any five digits. Both halves of that sentence were true atonce, which is the reason this module states the province alternation as its ownnamed fragment rather than inlining it -- a caller that needs a province code, apostcode or an INE municipality code now reads the same characters.Two framings over one pattern, because the field genuinely has two states: apostcode that has been declared, and a profile where the operator has notsupplied one yet."""from__future__importannotationsimportrefromtypingimportAnnotated,FinalfrompydanticimportStringConstraintsSPANISH_PROVINCE_CODE_PATTERN:Final[str]=r"(0[1-9]|[1-4][0-9]|5[0-2])""""A province code in 01..52, unanchored.Its own name because it is not only the head of a postcode. A province codestands alone on a censo declaration, and it prefixes an INE municipality codeas well, so three shapes read this one alternation. They were each carryingtheir own copy of it, and the copies had already come apart: the postcodevalidator at the registry boundary accepted any five digits, so ``99999``passed as a Spanish postcode with a province that does not exist."""SPANISH_POSTCODE_PATTERN:Final[str]=SPANISH_PROVINCE_CODE_PATTERN+r"[0-9]{3}""""Five digits whose leading pair is a province code in 01..52, unanchored."""OptionalSpanishPostcode=Annotated[str,StringConstraints(pattern=rf"^$|^{SPANISH_POSTCODE_PATTERN}$")]"""A postcode field an operator may legitimately have left undeclared."""_COMPILED:Final[re.Pattern[str]]=re.compile(rf"^{SPANISH_POSTCODE_PATTERN}$")
[docs]defis_spanish_postcode(value:str)->bool:"""Whether ``value`` is a well-formed Spanish postcode. For a caller that needs a boolean rather than a refusal -- an input widget deciding whether to re-prompt, say -- so the shape is asked of the same pattern the models validate against. """return_COMPILED.match(value)isnotNone