Skip to content

v0.164.0

Choose a tag to compare

@github-actions github-actions released this 23 Apr 01:43
· 22 commits to main since this release
011c058

Changed

  • Release publication now stages PyPI uploads separately from GitHub Release assets. The
    publish workflow now uploads only the wheel and source distribution to PyPI-facing jobs while
    keeping the .sha256 receipt in the GitHub Release asset path, and the maintainer runbook now
    documents rerunning workflow_dispatch against an existing tag to recover a partial release
    without moving or recreating the tag.
  • GitHub Actions now opt into Node 24 and pin the Node 24-capable immutable action releases.
    The Test and Build and Publish workflows now set
    FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true, move astral-sh/setup-uv to its
    official v8.1.0 commit pin, and update actions/setup-python,
    actions/upload-artifact, and actions/download-artifact to their current
    Node 24-native immutable releases.
  • Parser-only facades now expose the zero-dependency helpers that actually work without Babel.
    ftllexengine, ftllexengine.runtime, and ftllexengine.localization now keep
    CacheConfig, FluentNumber, fluent_function, make_fluent_number,
    PathResourceLoader, FallbackInfo, ResourceLoadResult, LoadSummary, and
    CacheAuditLogEntry importable in parser-only installs while gating only the
    Babel-backed bundle/orchestration facades behind the runtime extra.
  • Public locale-aware entry points now reject unknown locales instead of silently formatting as en_US.
    FluentBundle, FluentLocalization, number_format(), datetime_format(), and
    currency_format() now validate locale identifiers against Babel/CLDR up front so
    a misconfigured locale cannot claim one public value while rendering with another.
  • clear_module_caches() now validates selector names and no longer masks internal import failures as missing Babel.
    Unknown cache component names raise ValueError, parser-only skips are driven by
    Babel availability instead of broad ImportError swallowing, and broken runtime
    imports now surface their real exception path.
  • Parser-only optional facades now behave like truly absent names during feature probing.
    Babel-backed names such as ftllexengine.FluentBundle,
    ftllexengine.localization.FluentLocalization, and parser-only-hidden
    ftllexengine.runtime.number_format() now return False from hasattr() and
    honor getattr(..., default) instead of raising during routine capability
    checks, while direct access still carries explicit runtime-install guidance.
  • The Babel availability gate no longer rewrites broken Babel imports into misleading “install Babel” errors.
    core.babel_compat._check_babel_available() now treats only a genuinely missing
    top-level babel package as parser-only mode; internal ImportError failures
    from a broken Babel install now surface unchanged for diagnosis instead of being
    collapsed into BabelImportError.
  • Parser-only ftllexengine.runtime no longer advertises locale-formatting helpers that cannot run without Babel.
    create_default_registry(), get_shared_registry(), number_format(),
    datetime_format(), currency_format(), and select_plural_category() are
    now gated with the same full-runtime boundary as the bundle classes instead of
    remaining importable-but-immediately-failing in parser-only installs.
  • Documentation now uses consistent parser-only vs full-runtime terminology and fixes Babel requirement scope.
    README and guide pages now distinguish the two install modes explicitly,
    document that unknown locales fail fast at public formatting boundaries, and
    stop implying that all ISO helpers require Babel when
    get_currency_decimal_digits() works from embedded tables.
  • Core and runtime reference docs now match the current localization and cache contracts.
    The reference set now describes FluentLocalization as eager-load plus
    demand-driven bundle materialization, documents the exact
    clear_module_caches() selector names, and correctly describes
    CacheAuditLogEntry as the public alias of WriteLogEntry rather than a
    separate dataclass.
  • Quick-reference and example index docs now steer users toward the actual default behavior.
    The quick reference labels full-runtime vs parser-only install commands,
    removes an unnecessary strict=False from the multi-locale example, and the
    examples index now calls out the parser-only helper facades shown by
    examples/parser_only.py.
  • Locale, contributing, release, and fuzzing docs now match the shipped workflows more precisely.
    The locale guide now documents get_system_locale() as a fallback-returning
    helper instead of implying a default-path ValueError, contributing docs no
    longer claim the examples rely on local stubs, the release runbook now keeps
    pre-flight worktrees detached until the gates pass, explicitly distinguishes
    bootstrap-path staged diffs from the full PR diff against origin/main, and
    the Atheris docs now state clearly that --list inspects stored crashes and
    findings instead of enumerating target names.
  • Shipped examples now assert their own contracts, and the example runner enforces those contracts.
    examples/parser_only.py now demonstrates the real top-level validate_resource()
    surface plus warning-only versus invalid validation semantics, examples/ftl_linter.py
    now detects attribute-only no-value messages and undefined term references as advertised,
    and scripts/run_examples.py now rejects examples that exit 0 but miss their registered
    output-contract markers.
  • Diagnostics docs now describe the real structural parser-annotation contract.
    ParserAnnotation is now a documented public diagnostics export, and the
    diagnostics reference plus regression tests now bind ValidationResult.annotations
    to tuple[ParserAnnotation, ...] instead of implying a single concrete Annotation
    implementation.
  • Additional god-files are now split, and architecture budgets reach beyond src/.
    introspection.iso now delegates lookup, validation, and cache clearing into
    focused modules instead of carrying all ISO logic in one file, the
    runtime.bundle property test monolith is now partitioned into focused test
    modules, and tests/test_architecture_contract.py now enforces explicit line
    budgets for the previously ungoverned test, fuzz, and script hotspots as well
    as the remaining large internal utility modules.