Module adcp.reporting.currency
Currency checks shared by trusted obligation writers and source adapters.
These helpers never choose a currency from report rows. A row or a manifest can corroborate the seller's frozen currency, but cannot establish it.
Functions
def require_single_currency(currencies: Iterable[str]) ‑> str-
Expand source code
def require_single_currency(currencies: Iterable[str]) -> str: """Resolve trusted constituent currencies, rejecting an empty or mixed scope. Call this inside a currency resolver with historical account/media-buy values, before an obligation is committed. It does not convert money. """ resolved = {validate_currency(value) for value in currencies} if not resolved: return require_frozen_currency(None) if len(resolved) != 1: raise ReportingCurrencyError( "MIXED_CURRENCY_SCOPE", "one reporting obligation cannot aggregate multiple currencies" ) return next(iter(resolved))Resolve trusted constituent currencies, rejecting an empty or mixed scope.
Call this inside a currency resolver with historical account/media-buy values, before an obligation is committed. It does not convert money.
def validate_currency(value: object) ‑> str-
Expand source code
def validate_currency(value: object) -> str: """Require an ISO 4217-shaped code, without coercion or a registry lookup.""" if not isinstance(value, str) or re.fullmatch(r"[A-Z]{3}", value) is None: raise ReportingCurrencyError( "INVALID_CURRENCY", "reporting currency must be three uppercase ASCII letters" ) return valueRequire an ISO 4217-shaped code, without coercion or a registry lookup.
Classes
class ReportingCurrencyError (code: str, message: str)-
Expand source code
class ReportingCurrencyError(ValueError): """Reporting money cannot be interpreted safely; ``code`` is stable.""" def __init__(self, code: str, message: str) -> None: super().__init__(f"{code}: {message}") self.code = codeReporting money cannot be interpreted safely;
codeis stable.Ancestors
- builtins.ValueError
- builtins.Exception
- builtins.BaseException