dissolve-python 0.3.0

A tool to dissolve deprecated calls in Python codebases
Documentation
/// Test isolation utilities to ensure clean state between tests
use std::sync::Once;
use tracing::debug;

/// Macro to automatically setup test isolation
/// Use at the beginning of every test function that needs clean state
#[macro_export]
macro_rules! setup_test {
    () => {
        #[cfg(test)]
        $crate::test_isolation::reset_test_state();
    };
}

/// Macro for tests that specifically need magic method isolation
#[macro_export]
macro_rules! setup_magic_method_test {
    () => {
        #[cfg(test)]
        {
            $crate::test_isolation::reset_test_state();
            // Additional delay to ensure LSP client pool cleanup
            std::thread::sleep(std::time::Duration::from_millis(100));
        }
    };
}

static SETUP_TRACING: Once = Once::new();

/// Reset all global state to ensure test isolation
/// Call this at the beginning of every test
pub fn reset_test_state() {
    // Setup tracing only once
    SETUP_TRACING.call_once(|| {
        // Only setup if not already configured
        if std::env::var("RUST_LOG").is_err() {
            std::env::set_var("RUST_LOG", "debug");
        }
        let _ = tracing_subscriber::fmt::try_init();
    });

    debug!("Resetting test state for clean test execution");

    // 1. Clear module cache
    crate::dependency_collector::clear_module_cache();

    // 2. Reset pyright client pool (force new clients)
    reset_pyright_client_pool();

    // 3. Stop any existing dmypy daemons
    reset_dmypy_state();

    // 4. Clear any process-level state
    reset_process_state();

    debug!("Test state reset complete");
}

/// Reset the pyright client pool by clearing all cached clients
fn reset_pyright_client_pool() {
    #[cfg(test)]
    {
        use crate::pyright_lsp::tests::clear_client_pool;
        clear_client_pool();
    }
}

/// Reset dmypy daemon state
fn reset_dmypy_state() {
    // Stop any existing dmypy daemons
    let _ = std::process::Command::new("dmypy").arg("stop").output();

    // Small delay to ensure daemon shutdown
    std::thread::sleep(std::time::Duration::from_millis(50));
}

/// Reset any process-level state
fn reset_process_state() {
    // Reset working directory if changed
    if let Ok(original_dir) = std::env::var("CARGO_MANIFEST_DIR") {
        let _ = std::env::set_current_dir(&original_dir);
    }

    // Clear any test environment variables that might affect behavior
    std::env::remove_var("DISSOLVE_FORCE_TYPE_INTROSPECTION");
}