Repository navigation
v0.128.0
Changed (BREAKING)
-
fiscal.pymoved fromparsing/tocore/(ARCH-FISCAL-MOVE-CORE-001):FiscalCalendar,FiscalDelta,FiscalPeriod,MonthEndPolicy, and the five
convenience functions have zero Babel dependency; keeping them inparsing/forced
parser-only installs to fail withModuleNotFoundError: No module named 'babel'
when importingfrom ftllexengine.parsing import FiscalCalendar, because
parsing/__init__.pyimports.currencyand.datesat module level before
reaching the fiscal re-export; the docstring correctly stated "No external
dependencies" but the import behaviour contradicted this claim- Moved
src/ftllexengine/parsing/fiscal.py→src/ftllexengine/core/fiscal.py;
core/__init__.pynow exports all fiscal types;parsing/__init__.pyre-exports
fromftllexengine.core.fiscalsofrom ftllexengine.parsing import FiscalCalendar
still works for Babel installs; all fiscal types are now directly importable from the
top-levelftllexenginenamespace without Babel;tests/test_parsing_fiscal.py
updated fourfrom ftllexengine.parsing.fiscal import _add_monthscalls to
from ftllexengine.core.fiscal import _add_months - Location:
core/fiscal.py(new),core/__init__.py,parsing/__init__.py,
ftllexengine/__init__.py,tests/test_parsing_fiscal.py
-
FluentNumber.valuetype narrowed fromint | float | Decimaltoint | Decimal
(DEFECT-FLUENTNUMBER-FLOAT-PRECISION-001):- Storing
floatinFluentNumber.valuecontradicted the library's stated guarantee
of "Decimal precision — No float math, no rounding surprises" (README);floathas
approximately 15 significant decimal digits, whileintandDecimalare exact;
FluentNumberis the internal storage type used for plural category matching and cache
key construction, both of which require exact numeric representation FluentNumber.valuetype annotation changed toint | Decimal;number_format()
andcurrency_format()now convertfloatinput viaDecimal(str(value))before
constructingFluentNumber, preserving the caller's intended decimal representation;
FluentValue(the public input type) retainsfloatsince callers legitimately pass
native Python floats toformat_pattern()- Location:
runtime/value_types.py,runtime/functions.py
- Storing
-
FiscalPeriodrejectsfiscal_yearoutside 1–9999 (DEFECT-FISCALPERIOD-YEAR-BOUNDS-001):FiscalPeriod.__post_init__validatedquarter(1–4) andmonth(1–12) but not
fiscal_year; invalid values such as 0, −1, or 99999 were silently accepted at
construction time and produced a crypticValueError: year 0 is out of rangefrom
Python'sdatetime.dateonly whenfiscal_year_start_date()or similar methods
were later called; fail-fast at construction time is the correct behaviour for a
financial-grade library- Added
if not 1 <= self.fiscal_year <= 9999: raise ValueError(...)as the first
check inFiscalPeriod.__post_init__; bounds match Python'sdatetime.dateyear
range; four tests added totests/test_parsing_fiscal.py - Location:
core/fiscal.py,tests/test_parsing_fiscal.py
Changed
-
Fiscal convenience functions use module-level singleton for calendar-year case
(PERF-FISCAL-CALENDAR-ALLOC-001):- Every call to
fiscal_quarter(d),fiscal_year(d),fiscal_month(d),
fiscal_year_start(y), orfiscal_year_end(y)with the defaultstart_month=1
allocated a newFiscalCalendar(start_month=1)instance;FiscalCalendaris an
immutable frozen dataclass so the per-call allocation is unnecessary - Added
_CALENDAR_YEAR: Final[FiscalCalendar] = FiscalCalendar(start_month=1)as a
module-level constant; all five convenience functions now use_CALENDAR_YEARwhen
start_month == 1and allocate a new instance only for non-calendar fiscal years - Location:
core/fiscal.py
- Every call to
-
Fiscal types promoted to top-level
ftllexenginenamespace (API-FISCAL-TOPLEVEL-001):FiscalCalendar,FiscalDelta,FiscalPeriod,MonthEndPolicy,fiscal_quarter,
fiscal_year,fiscal_month,fiscal_year_start, andfiscal_year_endwere only
accessible viaftllexengine.parsing(Babel-gated) or direct submodule import;
financial users expect top-level access and the types have no Babel dependency- All nine symbols now importable as
from ftllexengine import FiscalCalendar, ...
with no Babel requirement; added to__all__inftllexengine/__init__.py - Location:
ftllexengine/__init__.py
-
bridge_fnum_typeandbridge_fnum_precisionstrategy events added to metrics
(GAP-STRATEGY-METRICS-BRIDGE-FNUM-001):- The
fluent_numbers()strategy intests/strategies/ftl.pyemitted
bridge_fnum_type={type}andbridge_fnum_precision={n}events that were absent
fromEXPECTED_EVENTS,STRATEGY_CATEGORIES, andINTENDED_WEIGHTSin
tests/strategy_metrics.py; the coverage gap detection system could not flag missing
coverage for this strategy family; additionally the float branch was removed from the
strategy afterFluentNumber.valueno longer accepts float - Added
bridge_fnum_type=int,bridge_fnum_type=decimal, and four
bridge_fnum_precision=*variants to all three tracking constants; removed float
branch fromfluent_numbers()intests/strategies/ftl.py - Location:
tests/strategy_metrics.py,tests/strategies/ftl.py
- The