ronantakizawa/codereview-bench huggingface dataset:
Repository: astral-sh/uv
File: crates/uv/tests/it/pip_install.rs (Rust)

Code before:

    ----- stderr -----
    Audited 1 package in [TIME]
    "
    );

    Ok(())
}

#[test]
fn install_with_system_interpreter() -> Result<()> {
    let context = TestContext::new("3.12");

    // A simple requirements.txt file with pytest
    let requirements_txt = context.temp_dir.child("requirements.txt");
    requirements_txt.write_str("pytest")?;

    // Add a custom filter to replace the system Python path (works on Unix-like systems, Windows and for CPython, PyPy and GraalPy implementations)
    let filters: Vec<_> = context
        .filters()
        .into_iter()
        .chain(std::iter::once((
            r"([\\/]).+([\\/])python([\\/])(?:cpython|pypy|graalpy)-\d+\.\d+\.\[X\][^\s]+",
            "[PYTHON-PATH]",
        )))
        .collect();

    uv_snapshot!(filters, context.pip_install()
        .arg("--system")
        .arg("-r")
        .arg("requirements.txt"), @r###"
    success: false
    exit_code: 2
    ----- stdout -----
    
    ----- stderr -----
    Using Python 3.12.[X] environment at: [PYTHON-PATH]
    error: The interpreter at [PYTHON-PATH] is externally managed, and indicates the following:
    
      This Python installation is managed by uv and should not be modified.
    
    Consider creating a virtual environment with `uv venv`.
    hint: This happens because you used the `--system` flag, which selects the system Python interpreter.
    "###
    );

    Ok(())
}

Review comment (suggestion):
I am not sure if this is the best way to do this, or if this should be added to  `context.filters` directly.

Code after:

    ----- stderr -----
    Audited 1 package in [TIME]
    "
    );

    Ok(())
}

#[test]
fn install_with_system_interpreter() -> Result<()> {
    let context = TestContext::new("3.12");

    // A simple requirements.txt file with pytest
    let requirements_txt = context.temp_dir.child("requirements.txt");
    requirements_txt.write_str("pytest")?;

    // Add a custom filter to replace the system Python path
    // works on Unix-like systems, Windows and for CPython, PyPy and GraalPy implementations
    let filters: Vec<_> = context
        .filters()
        .into_iter()
        .chain(std::iter::once((
            r"(?:[A-Za-z]:)?([\\/]).+([\\/])python([\\/])(?:cpython|pypy|graalpy)-\d+\.\d+\.\[X\][^\s]+",
            "[PYTHON-PATH]",
        )))
        .collect();

    uv_snapshot!(filters, context.pip_install()
        .arg("--system")
        .arg("-r")
        .arg("requirements.txt"), @r###"
    success: false
    exit_code: 2
    ----- stdout -----
    
    ----- stderr -----
    Using Python 3.12.[X] environment at: [PYTHON-PATH]
    error: The interpreter at [PYTHON-PATH] is externally managed, and indicates the following:
    
      This Python installation is managed by uv and should not be modified.
    
    Consider creating a virtual environment with `uv venv`.
    hint: This happens because the `--system` flag was used, which selected the system Python interpreter.
    "###
    );

    Ok(())
}
Repository: astral-sh/uv
File: crates/uv-build-backend/src/metadata.rs (Rust)

Code before:
                trace!("Further uv build backend direct build of `{name}` mismatch: {other}");
            }
            false
        }
    }
}

/// A `pyproject.toml` as specified in PEP 517.
#[derive(Deserialize, Debug, Clone)]
#[serde(
    rename_all = "kebab-case",
    expecting = "The project table needs to follow \
    https://packaging.python.org/en/latest/guides/writing-pyproject-toml"
)]
pub struct PyProjectToml {
    /// Project metadata
    project: Project,
    /// uv-specific configuration
    tool: Option<Tool>,
    /// Build-related data
    build_system: BuildSystem,
}

impl PyProjectToml {
    pub(crate) fn name(&self) -> &PackageName {
        &self.project.name.1
    }

    pub(crate) fn version(&self) -> &Version {
        &self.project.version
    }

    pub(crate) fn parse(contents: &str) -> Result<Self, Error> {
        Ok(toml::from_str(contents)?)
    }

    pub(crate) fn readme(&self) -> Option<&Readme> {
        self.project.readme.as_ref()
    }

    /// The license files that need to be included in the source distribution.
    pub(crate) fn license_files_source_dist(&self) -> impl Iterator<Item = &str> {
        let license_file = self
            .project
            .license
            .as_ref()
            .and_then(|license| license.file())
            .into_iter();
        let license_files = self
            .project
            .license_files

Review comment (suggestion):
I'd probably suggest adding a `VerbatimPackageName` struct with its own `Deserialize` implementation that stores the two.

Code after:
                trace!("Further uv build backend direct build of `{name}` mismatch: {other}");
            }
            false
        }
    }
}

/// A package name as provided in a `pyproject.toml`.
#[derive(Debug, Clone)]
struct VerbatimPackageName {
    /// The package name as given in the `pyproject.toml`.
    given: String,
    /// The normalized package name.
    normalized: PackageName,
}

impl<'de> Deserialize<'de> for VerbatimPackageName {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let given = String::deserialize(deserializer)?;
        let normalized = PackageName::from_str(&given).map_err(serde::de::Error::custom)?;
        Ok(Self { given, normalized })
    }
}

/// A `pyproject.toml` as specified in PEP 517.
#[derive(Deserialize, Debug, Clone)]
#[serde(
    rename_all = "kebab-case",
    expecting = "The project table needs to follow \
    https://packaging.python.org/en/latest/guides/writing-pyproject-toml"
)]
pub struct PyProjectToml {
    /// Project metadata
    project: Project,
    /// uv-specific configuration
    tool: Option<Tool>,
    /// Build-related data
    build_system: BuildSystem,
}

impl PyProjectToml {
    pub(crate) fn name(&self) -> &PackageName {
        &self.project.name.normalized
    }

    pub(crate) fn version(&self) -> &Version {
        &self.project.version
    }
Repository: astral-sh/uv
File: crates/uv/tests/it/sync.rs (Rust)

Code before:
    )?;

    context.lock().assert().success();

    uv_snapshot!(context.filters(), context.sync().arg("--all-groups"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Prepared 9 packages in [TIME]
    Installed 9 packages in [TIME]
     + anyio==4.3.0
     + certifi==2024.2.2
     + charset-normalizer==3.3.2
     + idna==3.6
     + iniconfig==2.0.0
     + requests==2.31.0
     + sniffio==1.3.1
     + typing-extensions==4.10.0
     + urllib3==2.2.1
    ");

    // Using `UV_NO_DEFAULT_GROUPS` should exclude all groups.
    uv_snapshot!(context.filters(), context.sync().env("UV_NO_DEFAULT_GROUPS", "true"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Uninstalled 8 packages in [TIME]
     - anyio==4.3.0
     - certifi==2024.2.2
     - charset-normalizer==3.3.2
     - idna==3.6
     - iniconfig==2.0.0
     - requests==2.31.0
     - sniffio==1.3.1
     - urllib3==2.2.1
    ");

    uv_snapshot!(context.filters(), context.sync().arg("--all-groups"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Installed 8 packages in [TIME]

Review comment (suggestion):
```suggestion
    uv_snapshot!(context.filters(), context.sync().env(EnvVars::UV_NO_DEFAULT_GROUPS, "true"), @r"
```

Code after:
    )?;

    context.lock().assert().success();

    uv_snapshot!(context.filters(), context.sync().arg("--all-groups"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Prepared 9 packages in [TIME]
    Installed 9 packages in [TIME]
     + anyio==4.3.0
     + certifi==2024.2.2
     + charset-normalizer==3.3.2
     + idna==3.6
     + iniconfig==2.0.0
     + requests==2.31.0
     + sniffio==1.3.1
     + typing-extensions==4.10.0
     + urllib3==2.2.1
    ");

    // Using `UV_NO_DEFAULT_GROUPS` should exclude all groups.
    uv_snapshot!(context.filters(), context.sync().env(EnvVars::UV_NO_DEFAULT_GROUPS, "true"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Uninstalled 8 packages in [TIME]
     - anyio==4.3.0
     - certifi==2024.2.2
     - charset-normalizer==3.3.2
     - idna==3.6
     - iniconfig==2.0.0
     - requests==2.31.0
     - sniffio==1.3.1
     - urllib3==2.2.1
    ");

    uv_snapshot!(context.filters(), context.sync().arg("--all-groups"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Installed 8 packages in [TIME]
Repository: astral-sh/uv
File: crates/uv/tests/it/sync.rs (Rust)

Code before:
    ");

    uv_snapshot!(context.filters(), context.sync().arg("--all-groups"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Installed 8 packages in [TIME]
     + anyio==4.3.0
     + certifi==2024.2.2
     + charset-normalizer==3.3.2
     + idna==3.6
     + iniconfig==2.0.0
     + requests==2.31.0
     + sniffio==1.3.1
     + urllib3==2.2.1
    ");

    // Using `UV_NO_DEFAULT_GROUPS` with `--group foo` and `--group bar` should include those groups,
    // excluding the remaining `dev` group.
    uv_snapshot!(context.filters(), context.sync()
        .arg("--group").arg("foo")
        .arg("--group").arg("bar")
        .env("UV_NO_DEFAULT_GROUPS", "true"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Uninstalled 1 package in [TIME]
     - iniconfig==2.0.0
    ");

    Ok(())
}

#[test]
fn sync_disable_default_groups_all_with_environment_variable() -> Result<()> {
    let context = TestContext::new("3.12");

    let pyproject_toml = context.temp_dir.child("pyproject.toml");
    pyproject_toml.write_str(
        r#"
        [project]
        name = "myproject"
        version = "0.1.0"
        requires-python = ">=3.12"
        dependencies = ["typing-extensions"]

Review comment (suggestion):
```suggestion
        .env(EnvVars::UV_NO_DEFAULT_GROUPS, "true"), @r"
```

Code after:
    ");

    uv_snapshot!(context.filters(), context.sync().arg("--all-groups"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Installed 8 packages in [TIME]
     + anyio==4.3.0
     + certifi==2024.2.2
     + charset-normalizer==3.3.2
     + idna==3.6
     + iniconfig==2.0.0
     + requests==2.31.0
     + sniffio==1.3.1
     + urllib3==2.2.1
    ");

    // Using `UV_NO_DEFAULT_GROUPS` with `--group foo` and `--group bar` should include those groups,
    // excluding the remaining `dev` group.
    uv_snapshot!(context.filters(), context.sync()
        .arg("--group").arg("foo")
        .arg("--group").arg("bar")
        .env(EnvVars::UV_NO_DEFAULT_GROUPS, "true"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Uninstalled 1 package in [TIME]
     - iniconfig==2.0.0
    ");

    Ok(())
}

#[test]
fn sync_disable_default_groups_all_with_environment_variable() -> Result<()> {
    let context = TestContext::new("3.12");

    let pyproject_toml = context.temp_dir.child("pyproject.toml");
    pyproject_toml.write_str(
        r#"
        [project]
        name = "myproject"
        version = "0.1.0"
        requires-python = ">=3.12"
        dependencies = ["typing-extensions"]
Repository: astral-sh/uv
File: crates/uv/tests/it/sync.rs (Rust)

Code before:
    )?;

    context.lock().assert().success();

    uv_snapshot!(context.filters(), context.sync(), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Prepared 9 packages in [TIME]
    Installed 9 packages in [TIME]
     + anyio==4.3.0
     + certifi==2024.2.2
     + charset-normalizer==3.3.2
     + idna==3.6
     + iniconfig==2.0.0
     + requests==2.31.0
     + sniffio==1.3.1
     + typing-extensions==4.10.0
     + urllib3==2.2.1
    ");

    // Using `UV_NO_DEFAULT_GROUPS` should exclude all groups.
    uv_snapshot!(context.filters(), context.sync().env("UV_NO_DEFAULT_GROUPS", "true"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Uninstalled 8 packages in [TIME]
     - anyio==4.3.0
     - certifi==2024.2.2
     - charset-normalizer==3.3.2
     - idna==3.6
     - iniconfig==2.0.0
     - requests==2.31.0
     - sniffio==1.3.1
     - urllib3==2.2.1
    ");

    Ok(())
}

/// Sync with `--only-group`, where the group includes a workspace member.
#[test]
fn sync_group_member() -> Result<()> {
    let context = TestContext::new("3.12");


Review comment (suggestion):
```suggestion
    uv_snapshot!(context.filters(), context.sync().env(EnvVars::UV_NO_DEFAULT_GROUPS, "true"), @r"
```

Code after:
    )?;

    context.lock().assert().success();

    uv_snapshot!(context.filters(), context.sync(), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Prepared 9 packages in [TIME]
    Installed 9 packages in [TIME]
     + anyio==4.3.0
     + certifi==2024.2.2
     + charset-normalizer==3.3.2
     + idna==3.6
     + iniconfig==2.0.0
     + requests==2.31.0
     + sniffio==1.3.1
     + typing-extensions==4.10.0
     + urllib3==2.2.1
    ");

    // Using `UV_NO_DEFAULT_GROUPS` should exclude all groups.
    uv_snapshot!(context.filters(), context.sync().env(EnvVars::UV_NO_DEFAULT_GROUPS, "true"), @r"
    success: true
    exit_code: 0
    ----- stdout -----

    ----- stderr -----
    Resolved 10 packages in [TIME]
    Uninstalled 8 packages in [TIME]
     - anyio==4.3.0
     - certifi==2024.2.2
     - charset-normalizer==3.3.2
     - idna==3.6
     - iniconfig==2.0.0
     - requests==2.31.0
     - sniffio==1.3.1
     - urllib3==2.2.1
    ");

    Ok(())
}

/// Sync with `--only-group`, where the group includes a workspace member.
#[test]
fn sync_group_member() -> Result<()> {
    let context = TestContext::new("3.12");
Repository: astral-sh/uv
File: crates/uv/tests/it/workspace_dir.rs (Rust)

Code before:
use std::env;
use std::path::PathBuf;

use anyhow::Result;
use assert_cmd::assert::OutputAssertExt;
use assert_fs::fixture::PathChild;

use crate::common::{TestContext, copy_dir_ignore, uv_snapshot};

fn workspaces_dir() -> PathBuf {
    env::current_dir()
        .unwrap()
        .parent()
        .unwrap()
        .parent()
        .unwrap()
        .join("scripts")
        .join("workspaces")
}

/// Test basic output for a simple workspace with one member.
#[test]
fn workspace_dir_simple() {
    let context = TestContext::new("3.12");

    // Initialize a workspace with one member
    context.init().arg("foo").assert().success();

    let workspace = context.temp_dir.child("foo");

    uv_snapshot!(context.filters(), context.workspace_dir().current_dir(&workspace), @r###"
    success: true
    exit_code: 0
    ----- stdout -----
    [TEMP_DIR]/foo


Review comment (refactor):
We usually read the manifest directory

https://github.com/astral-sh/uv/blob/8b479efd2fd03d5f92ce68e9cd98cf27a23ebc82/crates/uv/tests/it/common/mod.rs#L621-L628

I'd move that part out into a helper in `it/common/mod.rs`

Code after:
use std::env;

use anyhow::Result;
use assert_cmd::assert::OutputAssertExt;
use assert_fs::fixture::PathChild;

use crate::common::{TestContext, copy_dir_ignore, uv_snapshot};

/// Test basic output for a simple workspace with one member.
#[test]
fn workspace_dir_simple() {
    let context = TestContext::new("3.12");

    // Initialize a workspace with one member
    context.init().arg("foo").assert().success();

    let workspace = context.temp_dir.child("foo");

    uv_snapshot!(context.filters(), context.workspace_dir().current_dir(&workspace), @r###"
    success: true
    exit_code: 0
    ----- stdout -----
    [TEMP_DIR]/foo

    ----- stderr -----
    "###
    );
}

// Workspace dir output when run with `--package`
#[test]
fn workspace_dir_specific_package() {
    let context = TestContext::new("3.12");
    context.init().arg("foo").assert().success();
    context.init().arg("foo/bar").assert().success();
    let workspace = context.temp_dir.child("foo");
Repository: astral-sh/uv
File: crates/uv/src/commands/workspace/dir.rs (Rust)

Code before:
    project_dir: &Path,
    preview: Preview,
) -> Result<ExitStatus> {
    if preview.is_enabled(PreviewFeatures::WORKSPACE_DIR) {
        warn_user!(
            "The `uv workspace dir` command is experimental and may change without warning. Pass `--preview-features {}` to disable this warning.",
            PreviewFeatures::WORKSPACE_DIR
        );
    }

    let workspace_cache = WorkspaceCache::default();
    let workspace =
        Workspace::discover(project_dir, &DiscoveryOptions::default(), &workspace_cache).await?;

    let dir: &Path = match package_name {
        None => workspace.install_path().as_path(),
        Some(package) => {
            if let Some(p) = workspace.packages().get(&package) {
                p.root().as_path()
            } else {
                bail!("Package `{package}` not found in workspace.")
            }
        }
    };

    println!("{}", dir.simplified_display().cyan());

    Ok(ExitStatus::Success)
}


Review comment (suggestion):
This code compiles without the type cast:

```suggestion
    let dir = match package_name {
        None => workspace.install_path(),
        Some(package) => {
            if let Some(p) = workspace.packages().get(&package) {
                p.root()
            } else {
                bail!("Package `{package}` not found in workspace.")
            }
        }
    };
```

Code after:
    package_name: Option<PackageName>,
    project_dir: &Path,
    preview: Preview,
    printer: Printer,
) -> Result<ExitStatus> {
    if preview.is_enabled(PreviewFeatures::WORKSPACE_DIR) {
        warn_user!(
            "The `uv workspace dir` command is experimental and may change without warning. Pass `--preview-features {}` to disable this warning.",
            PreviewFeatures::WORKSPACE_DIR
        );
    }

    let workspace_cache = WorkspaceCache::default();
    let workspace =
        Workspace::discover(project_dir, &DiscoveryOptions::default(), &workspace_cache).await?;

    let dir: &Path = match package_name {
        None => workspace.install_path().as_path(),
        Some(package) => {
            if let Some(p) = workspace.packages().get(&package) {
                p.root().as_path()
            } else {
                bail!("Package `{package}` not found in workspace.")
            }
        }
    };

    writeln!(printer.stdout(), "{}", dir.simplified_display().cyan())?;

    Ok(ExitStatus::Success)
}
Repository: astral-sh/uv
File: crates/uv/src/commands/workspace/list.rs (Rust)

Code before:
use std::fmt::Write;
use std::path::Path;

use anyhow::Result;

use owo_colors::OwoColorize;
use uv_preview::{Preview, PreviewFeatures};
use uv_warnings::warn_user;
use uv_workspace::{DiscoveryOptions, Workspace, WorkspaceCache};

use crate::commands::ExitStatus;
use crate::printer::Printer;

/// List workspace members
pub(crate) async fn list(
    project_dir: &Path,
    preview: Preview,
    printer: Printer,
) -> Result<ExitStatus> {
    if preview.is_enabled(PreviewFeatures::WORKSPACE_LIST) {
        warn_user!(
            "The `uv workspace list` command is experimental and may change without warning. Pass `--preview-features {}` to disable this warning.",
            PreviewFeatures::WORKSPACE_LIST
        );
    }

    let workspace_cache = WorkspaceCache::default();
    let workspace =
        Workspace::discover(project_dir, &DiscoveryOptions::default(), &workspace_cache).await?;

    for name in workspace.packages().keys() {
        writeln!(printer.stdout(), "{}", name.cyan())?;
    }

    Ok(ExitStatus::Success)
}


Review comment (suggestion):
Looks like this is supposed to be:

```suggestion
    if !preview.is_enabled(PreviewFeatures::WORKSPACE_LIST) {
```

Code after:
use std::fmt::Write;
use std::path::Path;

use anyhow::Result;

use owo_colors::OwoColorize;
use uv_preview::{Preview, PreviewFeatures};
use uv_warnings::warn_user;
use uv_workspace::{DiscoveryOptions, Workspace, WorkspaceCache};

use crate::commands::ExitStatus;
use crate::printer::Printer;

/// List workspace members
pub(crate) async fn list(
    project_dir: &Path,
    preview: Preview,
    printer: Printer,
) -> Result<ExitStatus> {
    if !preview.is_enabled(PreviewFeatures::WORKSPACE_LIST) {
        warn_user!(
            "The `uv workspace list` command is experimental and may change without warning. Pass `--preview-features {}` to disable this warning.",
            PreviewFeatures::WORKSPACE_LIST
        );
    }

    let workspace_cache = WorkspaceCache::default();
    let workspace =
        Workspace::discover(project_dir, &DiscoveryOptions::default(), &workspace_cache).await?;

    for name in workspace.packages().keys() {
        writeln!(printer.stdout(), "{}", name.cyan())?;
    }

    Ok(ExitStatus::Success)
}
Repository: astral-sh/uv
File: crates/uv/tests/it/build_backend.rs (Rust)

Code before:
        .assert()
        .success();

    project.child("pyproject.toml").write_str(indoc! {r#"
        [project]
        name = "project"
        version = "1.0.0"
        license-files = ["LICENSE"]

        [build-system]
        requires = ["uv_build>=0.7,<10000"]
        build-backend = "uv_build"
        "#
    })?;

    let license_file = context.temp_dir.child("LICENSE");
    let license_symlink = project.child("LICENSE");

    let license_text = "Project license";
    license_file.write_str(license_text)?;
    fs_err::os::unix::fs::symlink(license_file.path(), license_symlink.path())?;

    uv_snapshot!(context
        .build_backend()
        .arg("build-sdist")
        .arg(context.temp_dir.path())
        .current_dir(project.path()), @r"
    success: true
    exit_code: 0
    ----- stdout -----
    project-1.0.0.tar.gz

    ----- stderr -----
    ");

    uv_snapshot!(context
        .build_backend()
        .arg("build-wheel")
        .arg(context.temp_dir.path())
        .current_dir(project.path()), @r"
    success: true
    exit_code: 0
    ----- stdout -----
    project-1.0.0-py3-none-any.whl

    ----- stderr -----
    ");

    uv_snapshot!(context.filters(), context.pip_install().arg("project-1.0.0-py3-none-any.whl"), @r"
    success: true
    exit_code: 0

Review comment (suggestion):
It's not ideal that we say the problem is `pyproject.toml`, the file itself is valid, I'll follow-up in a separate PR.

Code after:

    project.child("pyproject.toml").write_str(indoc! {r#"
        [project]
        name = "license-utf8"
        version = "1.0.0"
        license-files = ["LICENSE.bin"]

        [build-system]
        requires = ["uv_build>=0.7,<10000"]
        build-backend = "uv_build"
        "#
    })?;

    project.child("LICENSE.bin").write_binary(&[0xff])?;

    uv_snapshot!(context
        .build_backend()
        .arg("build-wheel")
        .arg(context.temp_dir.path())
        .current_dir(project.path()), @r###"
    success: false
    exit_code: 2
    ----- stdout -----

    ----- stderr -----
    error: Invalid pyproject.toml
      Caused by: License file `LICENSE.bin` must be UTF-8 encoded
    "###);

    Ok(())
}

/// Test that a symlinked file (here: license) gets included.
#[test]
#[cfg(unix)]
fn symlinked_file() -> Result<()> {
    let context = TestContext::new("3.12");

    let project = context.temp_dir.child("project");
    context
        .init()
        .arg("--lib")
        .arg(project.path())
        .assert()
        .success();

    project.child("pyproject.toml").write_str(indoc! {r#"
        [project]
        name = "project"
        version = "1.0.0"
        license-files = ["LICENSE"]