Repository: astral-sh/uv
File: crates/uv-workspace/src/pyproject.rs (Rust)

Code before:
    pub tool: Option<Tool>,
    /// Non-project dependency groups, as defined in PEP 735.
    pub dependency_groups: Option<DependencyGroups>,
    /// The raw unserialized document.
    #[serde(skip)]
    pub raw: String,

    /// Used to determine whether a `build-system` section is present.
    #[serde(default, skip_serializing)]
    build_system: Option<serde::de::IgnoredAny>,
}

impl PyProjectToml {
    /// Parse a `PyProjectToml` from a raw TOML string.
    pub fn from_string(raw: String) -> Result<Self, PyprojectTomlError> {
        let pyproject: toml_edit::ImDocument<_> =
            toml_edit::ImDocument::from_str(&raw).map_err(PyprojectTomlError::TomlSyntax)?;
        let pyproject = PyProjectToml::deserialize(pyproject.into_deserializer())
            .map_err(PyprojectTomlError::TomlSchema)?;
        Ok(PyProjectToml { raw, ..pyproject })
    }

    /// Returns `true` if the project should be considered a Python package, as opposed to a
    /// non-package ("virtual") project.
    pub fn is_package(&self) -> bool {
        // If `tool.uv.package` is set, defer to that explicit setting.
        if let Some(is_package) = self.tool_uv_package() {
            return is_package;
        }

        // Otherwise, a project is assumed to be a package if `build-system` is present.
        self.build_system.is_some()
    }

    /// Returns the value of `tool.uv.package` if set.
    pub fn tool_uv_package(&self) -> Option<bool> {
        self.tool
            .as_ref()
            .and_then(|tool| tool.uv.as_ref())
            .and_then(|uv| uv.package)
    }

    /// Returns `true` if the project uses a dynamic version.
    pub fn is_dynamic(&self) -> bool {
        self.project
            .as_ref()
            .is_some_and(|project| project.version.is_none())
    }

    /// Returns whether the project manifest contains any script table.
    pub fn has_scripts(&self) -> bool {

Review comment (suggestion):
I left the existing logic in place in `is_package` (factoring out the `tool.uv.package` check) to constrain this change to path sources only. 

Code after:
    /// Tool-specific metadata.
    pub tool: Option<Tool>,
    /// Non-project dependency groups, as defined in PEP 735.
    pub dependency_groups: Option<DependencyGroups>,
    /// The raw unserialized document.
    #[serde(skip)]
    pub raw: String,

    /// Used to determine whether a `build-system` section is present.
    #[serde(default, skip_serializing)]
    build_system: Option<serde::de::IgnoredAny>,
}

impl PyProjectToml {
    /// Parse a `PyProjectToml` from a raw TOML string.
    pub fn from_string(raw: String) -> Result<Self, PyprojectTomlError> {
        let pyproject: toml_edit::ImDocument<_> =
            toml_edit::ImDocument::from_str(&raw).map_err(PyprojectTomlError::TomlSyntax)?;
        let pyproject = PyProjectToml::deserialize(pyproject.into_deserializer())
            .map_err(PyprojectTomlError::TomlSchema)?;
        Ok(PyProjectToml { raw, ..pyproject })
    }

    /// Returns `true` if the project should be considered a Python package, as opposed to a
    /// non-package ("virtual") project.
    pub fn is_package(&self) -> bool {
        // If `tool.uv.package` is set, defer to that explicit setting.
        if let Some(is_package) = self.tool_uv_package() {
            return is_package;
        }

        // Otherwise, a project is assumed to be a package if `build-system` is present.
        self.build_system.is_some()
    }

    /// Returns the value of `tool.uv.package` if set.
    pub fn tool_uv_package(&self) -> Option<bool> {
        self.tool
            .as_ref()
            .and_then(|tool| tool.uv.as_ref())
            .and_then(|uv| uv.package)
    }

    /// Returns `true` if the project uses a dynamic version.
    pub fn is_dynamic(&self) -> bool {
        self.project
            .as_ref()
            .is_some_and(|project| project.version.is_none())
    }

    /// Returns whether the project manifest contains any script table.