|
1 |
| -use std::cell::RefCell; |
2 | 1 | use std::fmt;
|
| 2 | +use std::sync::Mutex; |
3 | 3 |
|
4 | 4 | use pyo3::exceptions::{PyTypeError, PyValueError};
|
5 | 5 | use pyo3::intern;
|
@@ -370,18 +370,27 @@ impl From<bool> for WarningsMode {
|
370 | 370 | }
|
371 | 371 | }
|
372 | 372 |
|
373 |
| -#[derive(Clone)] |
374 | 373 | #[cfg_attr(debug_assertions, derive(Debug))]
|
375 | 374 | pub(crate) struct CollectWarnings {
|
376 | 375 | mode: WarningsMode,
|
377 |
| - warnings: RefCell<Option<Vec<String>>>, |
| 376 | + // FIXME: mutex is to satisfy PyO3 0.23, we should be able to refactor this away |
| 377 | + warnings: Mutex<Vec<String>>, |
| 378 | +} |
| 379 | + |
| 380 | +impl Clone for CollectWarnings { |
| 381 | + fn clone(&self) -> Self { |
| 382 | + Self { |
| 383 | + mode: self.mode, |
| 384 | + warnings: Mutex::new(self.warnings.lock().expect("lock poisoned").clone()), |
| 385 | + } |
| 386 | + } |
378 | 387 | }
|
379 | 388 |
|
380 | 389 | impl CollectWarnings {
|
381 | 390 | pub(crate) fn new(mode: WarningsMode) -> Self {
|
382 | 391 | Self {
|
383 | 392 | mode,
|
384 |
| - warnings: RefCell::new(None), |
| 393 | + warnings: Mutex::new(Vec::new()), |
385 | 394 | }
|
386 | 395 | }
|
387 | 396 |
|
@@ -447,41 +456,46 @@ impl CollectWarnings {
|
447 | 456 | }
|
448 | 457 |
|
449 | 458 | fn add_warning(&self, message: String) {
|
450 |
| - let mut op_warnings = self.warnings.borrow_mut(); |
451 |
| - if let Some(ref mut warnings) = *op_warnings { |
452 |
| - warnings.push(message); |
453 |
| - } else { |
454 |
| - *op_warnings = Some(vec![message]); |
455 |
| - } |
| 459 | + self.warnings.lock().expect("lock poisoned").push(message); |
456 | 460 | }
|
457 | 461 |
|
458 | 462 | pub fn final_check(&self, py: Python) -> PyResult<()> {
|
459 | 463 | if self.mode == WarningsMode::None {
|
460 | 464 | return Ok(());
|
461 | 465 | }
|
462 |
| - match *self.warnings.borrow() { |
463 |
| - Some(ref warnings) => { |
464 |
| - let message = format!("Pydantic serializer warnings:\n {}", warnings.join("\n ")); |
465 |
| - if self.mode == WarningsMode::Warn { |
466 |
| - let user_warning_type = py.import_bound("builtins")?.getattr("UserWarning")?; |
467 |
| - PyErr::warn_bound(py, &user_warning_type, &message, 0) |
468 |
| - } else { |
469 |
| - Err(PydanticSerializationError::new_err(message)) |
470 |
| - } |
471 |
| - } |
472 |
| - _ => Ok(()), |
| 466 | + let warnings = self.warnings.lock().expect("lock poisoned"); |
| 467 | + |
| 468 | + if warnings.is_empty() { |
| 469 | + return Ok(()); |
| 470 | + } |
| 471 | + |
| 472 | + let message = format!("Pydantic serializer warnings:\n {}", warnings.join("\n ")); |
| 473 | + if self.mode == WarningsMode::Warn { |
| 474 | + let user_warning_type = py.import_bound("builtins")?.getattr("UserWarning")?; |
| 475 | + PyErr::warn_bound(py, &user_warning_type, &message, 0) |
| 476 | + } else { |
| 477 | + Err(PydanticSerializationError::new_err(message)) |
473 | 478 | }
|
474 | 479 | }
|
475 | 480 | }
|
476 | 481 |
|
477 |
| -#[derive(Default, Clone)] |
| 482 | +#[derive(Default)] |
478 | 483 | #[cfg_attr(debug_assertions, derive(Debug))]
|
479 | 484 | pub struct SerRecursionState {
|
480 |
| - guard: RefCell<RecursionState>, |
| 485 | + // FIXME: mutex is to satisfy PyO3 0.23, we should be able to refactor this away |
| 486 | + guard: Mutex<RecursionState>, |
| 487 | +} |
| 488 | + |
| 489 | +impl Clone for SerRecursionState { |
| 490 | + fn clone(&self) -> Self { |
| 491 | + Self { |
| 492 | + guard: Mutex::new(self.guard.lock().expect("lock poisoned").clone()), |
| 493 | + } |
| 494 | + } |
481 | 495 | }
|
482 | 496 |
|
483 | 497 | impl ContainsRecursionState for &'_ Extra<'_> {
|
484 | 498 | fn access_recursion_state<R>(&mut self, f: impl FnOnce(&mut RecursionState) -> R) -> R {
|
485 |
| - f(&mut self.rec_guard.guard.borrow_mut()) |
| 499 | + f(&mut self.rec_guard.guard.lock().expect("lock poisoned")) |
486 | 500 | }
|
487 | 501 | }
|
0 commit comments