mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
40 lines
1.4 KiB
Python
40 lines
1.4 KiB
Python
"""The :class:`Postcode` value object.
|
|
|
|
A frozen value object that owns postcode sanitisation. Constructing a
|
|
``Postcode`` always yields the canonical form -- uppercase with all
|
|
whitespace removed -- so no part of the domain can hold an un-normalised
|
|
postcode. This matches the legacy splitter's
|
|
``df["postcode"].str.upper().str.replace(" ", "")``.
|
|
|
|
``Postcode`` is the single sanitisation point: anywhere a postcode crosses a
|
|
domain boundary it should be wrapped in one, and ``str(postcode)`` gives the
|
|
canonical string back for serialisation.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Postcode:
|
|
"""A postcode held in canonical form.
|
|
|
|
The ``value`` passed to the constructor is sanitised eagerly in
|
|
:meth:`__post_init__` -- uppercased, with all whitespace (spaces, tabs,
|
|
newlines) removed -- so every ``Postcode`` instance is canonical by
|
|
construction. Two postcodes that differ only in surface whitespace or
|
|
case therefore compare equal.
|
|
|
|
Attributes:
|
|
value: The canonical postcode string (e.g. ``"SW1A1AA"``).
|
|
"""
|
|
|
|
value: str
|
|
|
|
def __post_init__(self) -> None:
|
|
# Frozen dataclass: bypass the descriptor with object.__setattr__.
|
|
object.__setattr__(self, "value", "".join(self.value.split()).upper())
|
|
|
|
def __str__(self) -> str:
|
|
return self.value
|