Repository: astral-sh/ruff
File: crates/ty_site_packages/src/lib.rs (Rust)

Code before:
    site_packages_directories_from_sys_prefix(
        &sys_prefix,
        None,
        PythonImplementation::Unknown,
        system,
    )
    .ok()?;

    Some(binary)
}

/// A parser for `pyvenv.cfg` files: metadata files for virtual environments.
///
/// Note that a `pyvenv.cfg` file *looks* like a `.ini` file, but actually isn't valid `.ini` syntax!
///
/// See also: <https://snarky.ca/how-virtual-environments-work/>
#[derive(Debug)]
struct PyvenvCfgParser<'s> {
    source: &'s str,
    cursor: Cursor<'s>,
    line_number: NonZeroUsize,
    data: RawPyvenvCfg<'s>,
}

impl<'s> PyvenvCfgParser<'s> {
    fn new(source: &'s str) -> Self {
        Self {
            source,
            cursor: Cursor::new(source),
            line_number: NonZeroUsize::new(1).unwrap(),
            data: RawPyvenvCfg::default(),
        }
    }

    /// Parse the `pyvenv.cfg` file and return the parsed data.
    fn parse(mut self) -> Result<RawPyvenvCfg<'s>, PyvenvCfgParseErrorKind> {
        while !self.cursor.is_eof() {
            self.parse_line()?;
            self.line_number = self.line_number.checked_add(1).unwrap();
        }
        Ok(self.data)
    }

    /// Parse a single line of the `pyvenv.cfg` file and advance the cursor
    /// to the beginning of the next line.
    fn parse_line(&mut self) -> Result<(), PyvenvCfgParseErrorKind> {
        let PyvenvCfgParser {
            source,
            cursor,
            line_number,
            data,

Review comment (suggestion):
We will probably want to support at least some kinds of shims, or else this feature is not useful to e.g. pyenv users. We can do that as a separate follow-up, but I would suggest adding a `TODO` comment that pyenv shims should ideally be supported.

Code after:

    Some(path)
}

#[cfg(target_family = "wasm")]
pub(crate) fn environment_from_binary(
    _system: &dyn System,
    _binary: &str,
) -> Option<PythonEnvironment> {
    None
}

#[cfg(not(target_family = "wasm"))]
pub(crate) fn environment_from_binary(
    system: &dyn System,
    binary: &str,
) -> Option<PythonEnvironment> {
    let binary = which::WhichConfig::new_with_sys(system)
        .binary_name(binary.into())
        .first_result()
        .ok()?;
    let binary = SystemPathBuf::from_path_buf(binary).ok()?;
    let env = PythonEnvironment::new(binary, SysPrefixPathOrigin::PythonBinary, system).ok()?;

    // TODO: replace this with better shim support, e.g. pyenv
    // sanity check to filter out shims
    env.site_packages_paths(system).ok()?;

    Some(env)
}

/// A parser for `pyvenv.cfg` files: metadata files for virtual environments.
///
/// Note that a `pyvenv.cfg` file *looks* like a `.ini` file, but actually isn't valid `.ini` syntax!
///
/// See also: <https://snarky.ca/how-virtual-environments-work/>
#[derive(Debug)]
struct PyvenvCfgParser<'s> {
    source: &'s str,
    cursor: Cursor<'s>,
    line_number: NonZeroUsize,
    data: RawPyvenvCfg<'s>,
}

impl<'s> PyvenvCfgParser<'s> {
    fn new(source: &'s str) -> Self {
        Self {
            source,
            cursor: Cursor::new(source),
            line_number: NonZeroUsize::new(1).unwrap(),
            data: RawPyvenvCfg::default(),