python / python/cpython

python versions of bisect_right and bisect_left can fail guarantees

Abierto
#125,889 21 comentarios 0 reacciones 1 asignado Ver en GitHub

@rhettinger ya está trabajando en esto.

Desde el 25/10/2024.

3.13 3.14 extension-modules stdlib type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
36k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Bug report

Bug description:

The documentation for bisect.bisect_right and bisect.bisect_left states in both cases that

The returned insertion point ip partitions the array a into two slices such that
all(elem <= x for elem in a[lo : ip]) is true for the left slice and
all(elem > x for elem in a[ip : hi]) is true for the right slice.

But in the python version of bisect, that guarantee can fail:

import sys
import _bisect as c_bisect
sys.modules['_bisect'] = None
import bisect as py_bisect

def check_guarantees(bisect_func, a, x, lo, hi):
    ip = bisect_func(a, x, lo, hi)
    check_pass = True 
    if not all(elem <= x for elem in a[lo : ip]): 
        print("\tFAIL. Elements of",a[lo:ip]," are not <=",x)
        check_pass = False
    if not all(elem > x for elem in a[ip : hi]):
        print("\tFAIL. Elements of",a[ip:hi]," are not >",x)
        check_pass = False
    if  check_pass: print("\tOk")

#print(c_bisect.bisect_right) # <built-in function bisect_right>
#print(py_bisect.bisect_right) # <function bisect_right at 0x0000023164AE7C40>

a = [0,1,2,3,4]
x = 8
lo = 3
hi = -1

print("bisect_left from C")
check_guarantees(c_bisect.bisect_left, a, x, lo, hi)

print("bisect_left from python")
check_guarantees(py_bisect.bisect_left, a, x, lo, hi)

print("bisect_right from C")
check_guarantees(c_bisect.bisect_right, a, x, lo, hi)

print("bisect_right from python")
check_guarantees(py_bisect.bisect_right, a, x, lo, hi)

Attempt this online
Outputs :

bisect_left from C
	Ok
bisect_left from python
	FAIL. Elements of [3]  are not > 8
bisect_right from C
	Ok
bisect_right from python
	FAIL. Elements of [3]  are not > 8

I think there is an extra check in the C version for hi < 0.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs
  • gh-125915

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.