Skip to content

Fix IndexError in choices_distribution when uniform() returns 1.0#2328

Open
bysiber wants to merge 1 commit intojoke2k:masterfrom
bysiber:fix/choices-distribution-index-overflow
Open

Fix IndexError in choices_distribution when uniform() returns 1.0#2328
bysiber wants to merge 1 commit intojoke2k:masterfrom
bysiber:fix/choices-distribution-index-overflow

Conversation

@bysiber
Copy link
Contributor

@bysiber bysiber commented Feb 20, 2026

Summary

choices_distribution_unique (and the fallback path of choices_distribution) can crash with IndexError when random.uniform(0, 1.0) returns exactly 1.0.

The Bug

random.uniform(0, 1.0) can return 1.0 — from the Python docs: "The end-point value b may or may not be included" and the implementation note says a + (b-a) * random() can return b.

When this happens, bisect.bisect_right(cdf2, 1.0) returns len(cdf2) because the last CDF element is always 1.0 and bisect_right places equal values to the right. This index is one past the end:

uniform_sample = random_sample(random=random)  # can be 1.0
idx = bisect.bisect_right(cdf2, uniform_sample)  # returns len(cdf2)
item = items[idx]  # IndexError!
from faker.utils.distribution import choices_distribution_unique
from unittest.mock import MagicMock
from random import Random

mock_random = MagicMock(spec=Random)
mock_random.uniform.return_value = 1.0

choices_distribution_unique(["a", "b"], [0.5, 0.5], random=mock_random, length=1)
# IndexError: list index out of range

This is intermittent in production — uniform() returning exactly 1.0 is rare but will happen given enough calls.

The Fix

Clamp the index to the valid range:

idx = bisect.bisect_right(cdf2, uniform_sample)
idx = min(idx, len(items) - 1)

Applied to both choices_distribution_unique and the fallback path of choices_distribution.

random.uniform(0, 1.0) can return exactly 1.0, causing bisect_right
to return len(cdf2) which is one past the last valid index. Clamp
the index to avoid the overflow.
@fcurella
Copy link
Collaborator

Thank you! Could you add a unit test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants