Closed
Description
Bug report
Bug description:
I just encountered the situation where I used random.sample
but both the population
and counts
arguments were empty (my algorithm had nothing left to choose from). So, basically this situation:
>>> random.sample([], 1, counts=[])
Traceback (most recent call last):
File "<python-input-1>", line 1, in <module>
random.sample([], 1, counts=[])
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "/path/to/lib/python3.14/random.py", line 424, in sample
total = cum_counts.pop()
IndexError: pop from empty list
Instead of the IndexError
, I expected a ValueError
, similar to the following situations:
>>> random.sample([], 1)
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
random.sample([], 1)
~~~~~~~~~~~~~^^^^^^^
File "/path/to/lib/python3.14/random.py", line 434, in sample
raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative
>>>
>>> random.sample([1], 2, counts=[1])
Traceback (most recent call last):
File "<python-input-3>", line 1, in <module>
random.sample([1], 2, counts=[1])
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/path/to/lib/python3.14/random.py", line 429, in sample
selections = self.sample(range(total), k=k)
File "/path/to/lib/python3.14/random.py", line 434, in sample
raise ValueError("Sample larger than population or is negative")
ValueError: Sample larger than population or is negative
The docs mention that
If the sample size is larger than the population size, a ValueError is raised.
In addition, I would expect the following to work:
>>> random.sample([], 0, counts=[])
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
random.sample([], 0, counts=[])
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
File "/path/to/lib/python3.14/random.py", line 424, in sample
total = cum_counts.pop()
IndexError: pop from empty list
similar to how it works when counts
is not specified:
>>> random.sample([], 0)
[]
Not sure though what CPython's backwards-compatibility policy has to say here, since changing the exception type – or, in the second case, removing the exception altogether – might actually break someone's code...
Tested with:
Python 3.14.0a5 (main, Feb 12 2025, 14:51:40) [Clang 19.1.6 ] on linux
cpython-3.14.0a5-linux-x86_64-gnu
CPython versions tested on:
3.14
Operating systems tested on:
Linux