ResultSet fetch methods silently return empty after close instead of raising (PEP 249 §Cursor)
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 55/100
- Tipo de issue
- Error
- Claridad
- Bastante claro
- Estado de actividad
- Tranquilo
- Stack tecnológico
- python
- Área
- backend-api-design
Línea de trabajo
Comienza en src/databricks/sql/result_set.py y luego sigue los métodos de fetch de ThriftResultSet, SeaResultSet y KernelResultSet. Reproduce primero el ejemplo del cursor cerrado e inspecciona cómo close() establece el estado existente y los indicadores de agotamiento. La tarea estará completa cuando todos los métodos de fetch enumerados lancen InterfaceError después de close() para los tres backends, se haya verificado el comportamiento de PEP 249 y se haya considerado la nota de compatibilidad.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
PEP 249 §Cursor says fetch operations on a closed cursor should raise an exception. Today, all three result-set implementations (ThriftResultSet, SeaResultSet, KernelResultSet) silently return empty after close() rather than raising InterfaceError.
Repro
import databricks.sql
with databricks.sql.connect(...) as conn:
cur = conn.cursor()
cur.execute("SELECT 1")
cur.close()
cur.fetchall() # PEP 249 says raise; today returns [].
Root cause
# src/databricks/sql/result_set.py — base ResultSet.close():
def close(self) -> None:
...
finally:
self.has_been_closed_server_side = True
self.status = CommandState.CLOSED
The flag is set, but the fetch methods don't read it. They walk self.results (an internal queue) which has been closed; next_n_rows returns empty rather than raising. KernelResultSet has the same shape with self._exhausted = True in close, which short-circuits its fetch loop to empty.
Scope
All three backends. This is a project-wide PEP 249 compliance gap, not specific to the kernel backend.
Concurrent fetch-vs-close (related)
There is no _closed flag readable by concurrent threads — if one thread is mid-fetch while another calls close(), behaviour is undefined (likely AttributeError from a nulled handle). Cursors are documented as not thread-safe, so this is "not a bug" by design, but a single _closed flag would make accidental misuse fail cleanly with InterfaceError instead of AttributeError.
Suggested fix
In base ResultSet (src/databricks/sql/result_set.py):
- Add
self._closed: bool = False. Set toTrueinsideclose()after cleanup. - Add a private
_check_open()that raisesInterfaceError("Result set is closed")if_closed. - Call
_check_open()at the top of every fetch method (fetchone,fetchmany,fetchall,fetchmany_arrow,fetchall_arrow).
Backwards-compat note: any user code that defensively does cur.close(); cur.fetchall() expecting [] will start raising. Likely warrants a release note.
Surfaced by
Review of PR #787 (kernel backend). Documented as P1 #8 + #9 in https://github.com/databricks/databricks-sql-python/pull/787#issuecomment-4475165482 — but the gap is pre-existing on Thrift and SEA too, not specific to the kernel backend.
- Lenguaje dominante
- Python
- Estrellas
- 233
- Forks
- 152
- Merge medio
- 21 h 5 min
- PR fusionados (30 d)
- 10
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de databricks/databricks-sql-python
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
Todos los issues de databricks/databricks-sql-python
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
-
🐛 Bug 🔔 Pending processing
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
jumpserver/jumpserver#17584 ·