Repository: astral-sh/uv
File: crates/uv/tests/it/init.rs (Rust)

Code before:
    ----- stdout -----

    ----- stderr -----
    Initialized script at `script.py`
    ");
    let resulting_script = fs_err::read_to_string(&script_path)?;
    assert_snapshot!(resulting_script, @r#"
    #!/usr/bin/env -S uv run --script
    #
    # /// script
    # requires-python = ">=3.12"
    # dependencies = []
    # ///

    print("Hello, world!")
    "#
    );

    Ok(())
}

// Make sure that `uv init --script` picks the latest non-pre-release version of Python
// for the `requires-python` constraint.
#[test]
fn init_script_picks_latest_stable_version() -> Result<()> {
    let context = TestContext::new_with_versions(&["3.14.0rc2", "3.13.2", "3.11.11"]);

    let script_path = context.temp_dir.join("main.py");

    uv_snapshot!(context.filters(), context.init().arg("--script").arg("main.py"), @r#"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Initialized script at `main.py`
    "#);

    let resulting_script = fs_err::read_to_string(&script_path)?;
    assert_snapshot!(
        resulting_script, @r#"
        # /// script
        # requires-python = ">=3.13"
        # dependencies = []
        # ///


        def main() -> None:
            print("Hello from main.py!")



Review comment (suggestion):
We'll need to mark this test with the `python-patch` feature to indicate it tests behavior for specific patch version. The distros run the test suite against their Python versions and need to exclude the test. 

I probably would not pin 3.13.2 and 3.11.11 and instead just use 3.13 and 3.11, since it's not necessary for the semantics of the test and we'll just need to remember bump them in the future.



Code after:
    ----- stdout -----

    ----- stderr -----
    Initialized script at `script.py`
    ");
    let resulting_script = fs_err::read_to_string(&script_path)?;
    assert_snapshot!(resulting_script, @r#"
    #!/usr/bin/env -S uv run --script
    #
    # /// script
    # requires-python = ">=3.12"
    # dependencies = []
    # ///

    print("Hello, world!")
    "#
    );

    Ok(())
}

// Make sure that `uv init --script` picks the latest non-pre-release version of Python
// for the `requires-python` constraint.
#[cfg(feature = "python-patch")]
#[test]
fn init_script_picks_latest_stable_version() -> Result<()> {
    let managed_versions = &["3.14.0rc2", "3.13", "3.12"];
    // If we do not mark these versions as managed, they would have `PythonSource::SearchPath(First)`, which
    // would mean that pre-releases would be preferred without opt-in (see `PythonSource::allows_prereleases`).
    let context =
        TestContext::new_with_versions(managed_versions).with_versions_as_managed(managed_versions);

    let script_path = context.temp_dir.join("main.py");

    uv_snapshot!(context.filters(), context.init().arg("--script").arg("main.py"), @r#"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Initialized script at `main.py`
    "#);

    let resulting_script = fs_err::read_to_string(&script_path)?;
    assert_snapshot!(
        resulting_script, @r#"
        # /// script
        # requires-python = ">=3.13"
        # dependencies = []
        # ///