Repository navigation
v0.80.0
Breaking
-
BREAKING: Replaced
FormatCachewithIntegrityCache(DATA-INTEGRITY-002):- Previous:
FormatCacheclass with simple LRU caching and tuple-based API - Now:
IntegrityCacheclass with BLAKE2b-128 checksum verification - API change:
cache.put(...)signature changed from(msg_id, args, attr, locale, isolating, (result, errors))to(msg_id, args, attr, locale, isolating, result, errors)(separate arguments) - API change:
cache.get(...)returnsIntegrityCacheEntry | Noneinstead oftuple[str, tuple[Error, ...]] | None - Migration pattern:
# Before from ftllexengine.runtime.cache import FormatCache cache = FormatCache(maxsize=1000) cache.put("msg", args, None, "en", True, (result, errors)) cached = cache.get("msg", args, None, "en", True) if cached: result, errors = cached # After from ftllexengine.runtime.cache import IntegrityCache cache = IntegrityCache(maxsize=1000, strict=False) cache.put("msg", args, None, "en", True, result, errors) entry = cache.get("msg", args, None, "en", True) if entry: result, errors = entry.to_tuple()
- Impact: All direct cache API usage must be updated; FluentBundle internal usage updated automatically
- Previous:
-
BREAKING: Replaced exception hierarchy with
FrozenFluentErrorsealed class (DATA-INTEGRITY-001):- Previous:
FluentError,FluentReferenceError,FluentResolutionError,FluentCyclicReferenceError,FluentParseError,FormattingErrorexception classes - Now: Single
FrozenFluentErrorclass withErrorCategoryenum for classification - Migration pattern:
# Before from ftllexengine import FluentReferenceError if isinstance(error, FluentReferenceError): ... # After from ftllexengine.diagnostics import FrozenFluentError, ErrorCategory if isinstance(error, FrozenFluentError) and error.category == ErrorCategory.REFERENCE: ...
- Categories:
REFERENCE,RESOLUTION,CYCLIC,PARSE,FORMATTING - Impact: All code checking error types via isinstance() must be updated
- Previous:
Added
-
IntegrityCache: Financial-Grade Format Caching (DATA-INTEGRITY-002):
- Thread-safe LRU cache with BLAKE2b-128 checksum verification on every
get() IntegrityCacheEntry: Immutable cache entry withformatted,errors,checksum,created_at,sequenceWriteLogEntry: Immutable audit log entry for compliance and debugging- Write-once semantics: Optional
write_once=Trueprevents overwrites (data race prevention) - Strict mode:
strict=True(default) raisesCacheCorruptionErroron checksum mismatch;strict=Falsesilently evicts - Audit logging:
enable_audit=Truerecords all cache operations to internal log - New integrity exceptions:
CacheCorruptionError,WriteConflictError - Sequence numbers: Monotonically increasing for audit trail integrity
- Configurable limits:
max_entry_weight,max_errors_per_entry,max_audit_entries - Import:
from ftllexengine.runtime.cache import IntegrityCache, IntegrityCacheEntry
- Thread-safe LRU cache with BLAKE2b-128 checksum verification on every
-
Integrity Context and Exceptions (DATA-INTEGRITY-002):
IntegrityContext: Dataclass for error context (component, operation, key, expected, actual, timestamp)CacheCorruptionError: Raised when checksum verification fails (strict mode)WriteConflictError: Raised when write-once semantics violated (strict mode)- Import:
from ftllexengine.integrity import CacheCorruptionError, WriteConflictError, IntegrityContext
-
FrozenFluentError: Immutable, Content-Addressable Errors (DATA-INTEGRITY-001):
- Immutable: All attributes frozen after construction; mutation raises
ImmutabilityViolationError - Sealed: Cannot be subclassed (enforced at static analysis via
@finaland at runtime) - Content-addressed: BLAKE2b-128 hash computed at construction for integrity verification
- Hashable: Can be used in sets and as dict keys; hash based on content, not identity
- Properties:
message,category,diagnostic,context,content_hash,fallback_value - Method:
verify_integrity()- recomputes hash with constant-time comparison
- Immutable: All attributes frozen after construction; mutation raises
-
ErrorCategory Enum: Replaces exception class hierarchy
REFERENCE: Unknown message, term, or variable referenceRESOLUTION: Runtime resolution failure (depth exceeded, function error)CYCLIC: Cyclic reference detectedPARSE: Bi-directional parsing failure (number, date, currency)FORMATTING: Locale-aware formatting failure
-
FrozenErrorContext Dataclass: Immutable context for parse/formatting errors
- Fields:
input_value,locale_code,parse_type,fallback_value - Used to provide additional context for
PARSEandFORMATTINGcategory errors
- Fields:
-
DataIntegrityError and ImmutabilityViolationError: New integrity exceptions
DataIntegrityError: Base class for data integrity violationsImmutabilityViolationError: Raised when attempting to mutate frozen objects- Import:
from ftllexengine.integrity import DataIntegrityError, ImmutabilityViolationError
-
FormattingIntegrityError: Strict Mode Exception (DATA-INTEGRITY-003):
- Raised when
strict=Truebundle encounters ANY formatting errors - Carries original Fluent errors:
fluent_errorsproperty (tuple of FrozenFluentError) - Carries fallback value:
fallback_valueproperty (what would have been returned in non-strict mode) - Carries message ID:
message_idproperty for identifying failed message - Includes
IntegrityContextfor post-mortem analysis - Import:
from ftllexengine.integrity import FormattingIntegrityError
- Raised when
-
FluentBundle strict Mode Parameter (DATA-INTEGRITY-003):
- New
strict: bool = Falseparameter inFluentBundle.__init__ - When
strict=True: Any formatting error raisesFormattingIntegrityErrorinstead of returning fallback - Property:
bundle.strictreturns current strict mode setting - Use case: Financial applications that cannot accept silent fallbacks for missing translations
- Example:
bundle = FluentBundle("en", strict=True) bundle.add_resource("msg = Hello, { $name }!") # Raises FormattingIntegrityError instead of returning "Hello, {$name}!" bundle.format_pattern("msg", {})
- New