Skip to content

Commit d197166

Browse files
committed
fix: raise Ctrl-C caught while stopping early SQL lint
1 parent 15dd042 commit d197166

3 files changed

Lines changed: 21 additions & 9 deletions

File tree

‎crates/sqlbuild-python/src/bindings/_helpers/compile_driver/analysis.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ fn analyzed<'py>(
182182
let graph_failed: bool = any_error(&project.getattr("diagnostics")?)?;
183183
let mut early_lint_wait_ms: Bound<'py, PyAny> = 0_i64.into_pyobject(py)?.into_any();
184184
if graph_failed {
185-
early_lint_wait_ms = early_lint.borrow().stop(py).into_pyobject(py)?.into_any();
185+
early_lint_wait_ms = early_lint.borrow().stop(py)?.into_pyobject(py)?.into_any();
186186
}
187187
let (lineage, lineage_ms): (Bound<'py, PyAny>, u64) = driver.lineage(&graph, &dialect)?;
188188
let contracts: ContractPhase<'py> = driver.contracts(&project, &dialect)?;
@@ -210,7 +210,7 @@ fn analyzed<'py>(
210210
(&core_diagnostics, &selected_keys),
211211
&lint_dialect,
212212
)?;
213-
early_lint_wait_ms = early_lint.borrow().stop(py).into_pyobject(py)?.into_any();
213+
early_lint_wait_ms = early_lint.borrow().stop(py)?.into_pyobject(py)?.into_any();
214214
result
215215
};
216216
let diagnostics: Bound<'py, PyTuple> =

‎crates/sqlbuild-python/src/bindings/_helpers/rules/early_sql_lint.rs‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
99
use std::sync::{Arc, Mutex, OnceLock, PoisonError};
1010
use std::thread::JoinHandle;
1111

12-
use pyo3::exceptions::PyRuntimeError;
12+
use pyo3::exceptions::{PyException, PyRuntimeError};
1313
use pyo3::prelude::{
1414
Bound, IntoPyObject, Py, PyAny, PyAnyMethods, PyErr, PyModule, PyModuleMethods, PyRefMut,
1515
PyResult, Python,
@@ -172,6 +172,11 @@ impl PreparedSqlLint {
172172
same_codes(&self.codes, codes)
173173
}
174174

175+
/// Whether the lint's result is already known.
176+
fn finished(&self) -> bool {
177+
self.result.get().is_some()
178+
}
179+
175180
/// The lint's result, waiting without the GIL until it finishes or a signal handler raises.
176181
pub(crate) fn result(&self, py: Python<'_>) -> &Result<EarlyLintResult, PyErr> {
177182
self.result.get_or_init(|| {
@@ -307,14 +312,21 @@ impl EarlySqlLint {
307312
self.expansion_reuse.as_ref()
308313
}
309314

310-
/// Abandon unconsumed speculative work and return the milliseconds spent joining it.
311-
pub(crate) fn stop(&self, py: Python<'_>) -> u64 {
315+
/// Abandon speculative work, return the milliseconds spent joining it, and raise Ctrl+C caught while waiting.
316+
pub(crate) fn stop(&self, py: Python<'_>) -> PyResult<u64> {
312317
let started: Instant = Instant::now();
313318
self.stop_requested.store(true, Ordering::Release);
314319
if let Some(preparation) = &self.preparation {
315-
let _ = preparation.get().result(py);
320+
let preparation: &PreparedSqlLint = preparation.get();
321+
let waiting: bool = !preparation.finished();
322+
if let Err(error) = preparation.result(py)
323+
&& waiting
324+
&& !error.is_instance_of::<PyException>(py)
325+
{
326+
return Err(error.clone_ref(py));
327+
}
316328
}
317-
u64::try_from(started.elapsed().as_millis()).unwrap_or(u64::MAX)
329+
Ok(u64::try_from(started.elapsed().as_millis()).unwrap_or(u64::MAX))
318330
}
319331
}
320332

@@ -364,7 +376,7 @@ impl EarlySqlLint {
364376

365377
/// Abandon unconsumed speculative work and return the milliseconds spent joining it.
366378
#[pyo3(name = "stop")]
367-
fn py_stop(&self, py: Python<'_>) -> u64 {
379+
fn py_stop(&self, py: Python<'_>) -> PyResult<u64> {
368380
self.stop(py)
369381
}
370382
}

‎tests/e2e/src/sqlbuild/cli/commands/main/compile/helpers.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4987,7 +4987,7 @@ def compile_with_binding_error(project_dir: Path) -> dict[str, Any]:
49874987

49884988

49894989
def slow_lint_model_files(*, model_count: int) -> dict[str, str]:
4990-
"""A macro used by a model, a function, and macro tests that only the background SQL lint expands."""
4990+
"""A macro used by a model, a function, and macro tests only background SQL lint expands."""
49914991

49924992
return {
49934993
"macros/slow.py": _SLOW_LINT_MACRO,

0 commit comments

Comments
 (0)