nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: mitsuhiko/insta
Pull request #250 (2022-07-27 12:52:12)

Add support for Settings::bind_to_scope
The current `Settings::bind_to_thread` is very hard to use as it has no resetting drop guard.


Patch:
diff --git a/src/settings.rs b/src/settings.rs
index 7a9a52b..028ccb8 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -1,5 +1,6 @@
 use std::cell::RefCell;
 use std::future::Future;
+use std::mem;
 use std::path::{Path, PathBuf};
 use std::pin::Pin;
 use std::sync::Arc;
@@ -515,14 +516,39 @@ impl Settings {
     }
 
     /// Binds the settings to the current thread permanently.
+    ///
+    /// This should no longer be used in favor of [`Settings::bind_to_scope`].
+    #[deprecated(since = "0.17.0", note = "Use Settings::bind_to_scope instead.")]
     pub fn bind_to_thread(&self) {
         CURRENT_SETTINGS.with(|x| {
             x.borrow_mut().inner = self.inner.clone();
         })
     }
 
+    /// Binds the settings to the current thread and resets when the drop
+    /// guard is released.
+    ///
+    /// This is the recommen
+    pub fn bind_to_scope(&self) -> impl Drop {
+        CURRENT_SETTINGS.with(|x| {
+            let mut x = x.borrow_mut();
+            let old = mem::replace(&mut x.inner, self.inner.clone());
+            BindDropGuard(Some(old))
+        })
+    }
+
     /// Runs a function with the current settings.
     pub(crate) fn with<R, F: FnOnce(&Settings) -> R>(f: F) -> R {
         CURRENT_SETTINGS.with(|x| f(&*x.borrow()))
     }
 }
+
+struct BindDropGuard(Option<Arc<ActualSettings>>);
+
+impl Drop for BindDropGuard {
+    fn drop(&mut self) {
+        CURRENT_SETTINGS.with(|x| {
+            x.borrow_mut().inner = self.0.take().unwrap();
+        })
+    }
+}


Test patch:
diff --git a/tests/test_settings.rs b/tests/test_settings.rs
index 915263c..888f3d6 100644
--- a/tests/test_settings.rs
+++ b/tests/test_settings.rs
@@ -23,6 +23,7 @@ fn test_simple() {
 }
 
 #[test]
+#[allow(deprecated)]
 fn test_bound_to_thread() {
     let mut map = HashMap::new();
     map.insert("a", "first value");
@@ -40,6 +41,34 @@ fn test_bound_to_thread() {
     c: third value
     d: fourth value
     "###);
+
+    // put defaults back
+    let settings = Settings::new();
+    settings.bind_to_thread();
+}
+
+#[test]
+fn test_bound_to_scope() {
+    let mut map = HashMap::new();
+    map.insert("a", "first value");
+    map.insert("b", "second value");
+    map.insert("c", "third value");
+    map.insert("d", "fourth value");
+
+    {
+        let mut settings = Settings::new();
+        settings.set_sort_maps(true);
+        let _guard = settings.bind_to_scope();
+        assert_yaml_snapshot!(&map, @r###"
+        ---
+        a: first value
+        b: second value
+        c: third value
+        d: fourth value
+        "###);
+    }
+
+    assert!(!Settings::clone_current().sort_maps());
 }
 
 #[test]