Source code for phantom.iso3166

Exposes a :py:class:`CountryCode` type that is a union of a :py:class:`Literal`
containing all ISO3166 alpha-2 codes, and a phantom type that parses alpha-2 codes at
runtime. This allows mixing statically known values with runtime-parsed values, like

.. code-block:: python

    countries: tuple[CountryCode] = ("SE", "DK", ParsedAlpha2.parse("FR"))
from __future__ import annotations

from typing import Union
from typing import cast

from typing_extensions import Final
from typing_extensions import Literal
from typing_extensions import get_args

from phantom import Phantom
from phantom import _hypothesis
from phantom.bounds import parse_str
from phantom.predicates.collection import contained
from phantom.schema import Schema

__all__ = (

LiteralAlpha2 = Literal[
"""Literal of all ISO3166 alpha-2 codes. """

ALPHA2: Final = frozenset(get_args(LiteralAlpha2))
is_alpha2_country_code = contained(ALPHA2)

[docs]class InvalidCountryCode(TypeError): ...
[docs]def normalize_alpha2_country_code(country_code: str) -> ParsedAlpha2: """ Normalize mixed case country code. :raises InvalidCountryCode: """ normalized = country_code.upper() if not is_alpha2_country_code(normalized): raise InvalidCountryCode return cast(ParsedAlpha2, normalized)
[docs]class ParsedAlpha2(str, Phantom, predicate=is_alpha2_country_code):
[docs] @classmethod def parse(cls, instance: object) -> ParsedAlpha2: """ Normalize mixed case country code. :raises InvalidCountryCode: """ return normalize_alpha2_country_code(parse_str(instance))
@classmethod def __schema__(cls) -> Schema: return { **super().__schema__(), # type: ignore[misc] "description": "ISO3166-1 alpha-2 country code", "examples": ["NR", "KZ", "ET", "VC", "AE", "NZ", "SX", "XK", "AX"], "format": "iso3166-1 alpha-2", "title": "Alpha2", } @classmethod def __register_strategy__(cls) -> _hypothesis.SearchStrategy | None: from hypothesis.strategies import sampled_from return sampled_from(sorted(ALPHA2))
Alpha2 = Union[LiteralAlpha2, ParsedAlpha2] CountryCode = Alpha2