|
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