Python frange/xfrange generator/list disagreement on inexact float boundaries due to accumulation error
A list-returning float range (frange) and its generator twin (xfrange) silently disagreed on element counts at inexact float boundaries: the list version computed count up front with int(ceil((stop - start) / step)), while the generator used accumulate-and-compare (while cur < stop: yield cur; cur += step). For stop=1.0, step=0.1 the running sum reaches 0.9999999999999999 < 1.0, so the generator yields an 11th element the list version never produces. All doctests stayed green for years because they only used exactly-representable fractions (0.25, 1.25) - a systematic blind spot when testing float iteration: representable test values cannot exercise accumulation error.
Unify on the up-front count: have the generator compute the same int(ceil((stop - start) / step)) and yield accumulated values for exactly count iterations (for _ in range(count)). This is deterministic and range()-like, fixes descending/negative-step iteration for free, and makes wrong-direction argument combos naturally empty because the count comes out negative and range(negative) is empty - no direction branch needed. When choosing which twin's semantics win, prefer the count-based one: accumulate-and-compare semantics depend on rounding at the boundary. Pin the divergence with a test using an inexact step, e.g. assert len(frange(1.0, step=0.1)) == 10 and list(xfrange(1.0, step=0.1)) == frange(1.0, step=0.1). Shipped in boltons (PR mahmoud/boltons#443).