Bug report
Bug description:
In Lib/multiprocessing/connection.py, the Windows branch of _exhaustive_wait() that handles more than 60 handles (added in gh-89240 / GH-107873) filters the already signalled handles out of the list with
if res:
L = [h for i, h in enumerate(L) if i > res[0] & i not in res]
& binds tighter than the comparison operators, so this parses as the chained comparison i > (res[0] & i) not in res, i.e. i > (res[0] & i) and ((res[0] & i) not in res), which is not the intended i > res[0] and i not in res. For example with res = [2, 5] and eight handles it keeps indexes 1, 4, 5 instead of 3, 4, 6, 7, so signalled handles can stay in L (and be waited on and reported again) while unsignalled ones are dropped.
>>> res = [2, 5]; L = list("abcdefgh")
>>> [h for i, h in enumerate(L) if i > res[0] & i not in res]
['b', 'e', 'f']
>>> [h for i, h in enumerate(L) if i > res[0] and i not in res]
['d', 'e', 'g', 'h']
pylint reports the line as bad-chained-comparison ("suspicious 2-part chained comparison using semantically incompatible operators ('>' and 'not in')"), which is how I found it. The fix is to use and.
CPython versions tested on:
CPython main branch, 3.14
Operating systems tested on:
Windows (code path), found on macOS by static analysis
Bug report
Bug description:
In
Lib/multiprocessing/connection.py, the Windows branch of_exhaustive_wait()that handles more than 60 handles (added in gh-89240 / GH-107873) filters the already signalled handles out of the list with&binds tighter than the comparison operators, so this parses as the chained comparisoni > (res[0] & i) not in res, i.e.i > (res[0] & i) and ((res[0] & i) not in res), which is not the intendedi > res[0] and i not in res. For example withres = [2, 5]and eight handles it keeps indexes1, 4, 5instead of3, 4, 6, 7, so signalled handles can stay inL(and be waited on and reported again) while unsignalled ones are dropped.pylint reports the line as
bad-chained-comparison("suspicious 2-part chained comparison using semantically incompatible operators ('>' and 'not in')"), which is how I found it. The fix is to useand.CPython versions tested on:
CPython main branch, 3.14
Operating systems tested on:
Windows (code path), found on macOS by static analysis