astral-sh/ruff · error

Multiple sections with `[project]` dependencies in the same

Error message

Multiple sections with `[project]` dependencies in the same file are not allowed. External dependencies must be specified in a single top-level configuration block.

What it means

ty's markdown test parser allows external (`[project]`) dependencies to be declared only once per mdtest file, in a single top-level configuration block. When a second code-block config in the same file also declares dependencies, parsing fails with this error so tests cannot accidentally use ambiguous per-section dependency sets.

Source

Thrown at crates/ty_test/src/lib.rs:626

    } else {
        expanded.push("lib");
        expanded.push(format!("python{python_version}"));
        expanded.push("site-packages");
    }
    expanded.extend(components.skip(1));

    Some(expanded)
}

fn parse<'s>(
    short_title: &'s str,
    source: &'s str,
) -> anyhow::Result<parser::MarkdownTestSuite<'s, MarkdownTestConfig>> {
    let mut file_has_dependencies = false;
    parser::parse::<MarkdownTestConfig>(short_title, source, |config| {
        if config.dependencies().is_some() {
            if file_has_dependencies {
                bail!(
                    "Multiple sections with `[project]` dependencies in the same file are not allowed. \
                     External dependencies must be specified in a single top-level configuration block."
                );
            }
            file_has_dependencies = true;
        }
        Ok(())
    })
}

#[cfg(test)]
mod tests {
    use ruff_python_ast::PythonVersion;
    use ruff_python_trivia::textwrap::dedent;

    #[test]
    fn normalizes_site_packages_paths_only_in_diagnostic_locations() {
        let rendered = "warning[example]: Invalid value\n\

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Keep exactly one top-level configuration block with `[project] dependencies` in the mdtest file and delete the duplicate.
  2. Move dependency-requiring tests that need different packages into separate `.md` files, each with its own single dependency block.
  3. If a section only needs a comment/config for another purpose, strip the `dependencies` key from that block so it no longer counts.

Example fix

<!-- before: two blocks with [project] dependencies in one file -->
#[config]
[project]
dependencies = ["requests"]
...
#[config]
[project]
dependencies = ["numpy"]

<!-- after: one block per file -->
#[config]
[project]
dependencies = ["requests"]
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
# fail if an mdtest file has more than one dependency block
for f in "$@"; do
  n=$(grep -c '^\[project\]' "$f")
  [ "$n" -le 1 ] || { echo "$f: $n dependency blocks"; exit 1; }
done

Try / catch

match parser::parse::<MarkdownTestConfig>(short_title, source, on_config) {
    Err(e) if e.to_string().contains("Multiple sections with `[project]` dependencies") => {
        eprintln!("Fix mdtest file: keep a single top-level [project] dependencies block: {e}");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Parsing a `.md` test file where two or more `#[config]`/`[project]` configuration blocks each set `dependencies`; raised from `parse` while building the `MarkdownTestSuite`.

Common situations: Adding a new test section with its own `[project] dependencies` block to a file that already declares dependencies at the top, or copy-pasting a config block into multiple sections.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/de2c0d3d7ac23dce. Report an issue: GitHub.