@@ -9,7 +9,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
99use std:: sync:: { Arc , Mutex , OnceLock , PoisonError } ;
1010use std:: thread:: JoinHandle ;
1111
12- use pyo3:: exceptions:: PyRuntimeError ;
12+ use pyo3:: exceptions:: { PyException , PyRuntimeError } ;
1313use 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}
0 commit comments